preface
This is a series of articles designed to share personal insights and experiences in the practice of react and related technology stacks. If there is anything bad, you are welcome to criticize and correct.
Since we haven’t got a deep understanding of react itself, let’s talk about some issues related to Redux today.
Who creates it?
Dan Abramovyesredux
At the same time, he is also the authorCreate React App
, React Hot Loader
Author. Of course, a year ago, he was also due toredux
And related open source contributionsfacebook
He dropped out of school as a sophomore and worked as a. Net engineer before.
when I first learned about him, I thought he was very polite. At the same time, for more understandingredux
, I planned to start reading every tweet of him. Originally, I planned to start from July 15. Later, because the progress was slow andreact
The version has also changed greatly, so I began to read it from January 1, 2016, and now it is recorded to July 15. Facts have also proved that in this process, I really learned a lot. includeredux
Documents andredux-links
Author ofMark Erikson, as well as many foreign countriesredux
Friends of the series.
if you are interested, you can look at my excerptSome fragments。 In addition to the knowledge content, there are some excerpts about its own life, experience, learning methods, how to face JS fatigue and so on. It also let me gradually understand some views, interests, stems and so on of foreign programmers.
text
OK, that’s all for now. Switch back to Redux itself. Here are some of my own experiences in learning the source code.
createStore
createStore
The third parameter of isenhancer
, ifenhancer
If there are multiple, you should usecompose
Combine multiple in different waysenhancer
and eachenhancer
The template for isexport default createStore => (reducer, preloadedState, enhancer) => {...}
because increateStore
Implemented in:return enhancer(createStore)(reducer, preloadedState)
in addition, the shape mentioned above is as follows:(reducer, preloadedState, enhancer) => {...}
In fact, anything like this can be calledcreateStore
there are so many in the communityenhancer
The reason why they can form aenhancer
Chain, I call yourcreateStore
, then return to mycreateStore
For next level call
so in your owncreateStore
Functions such asvar store = createStore(reducer, preloadedState, enhancer);
The purpose of this usage is to make yourself before this levelenhancer
Generate astore
Come out, and beforeenhancer
InsidecreateStore
Will call the previous, to the end, isredux
Per secreateStore
applyMiddleware
applyMiddleware
The purpose of is to return aenhancer
, thisenhancer
One or more middleware is stored, and the middleware is at the upper leveldispatch
Method, and then return your own logicdispatch
method
for middleware, the template of middleware is:export default store => next => action => {...}
。 It is also written in some placesexport default _ref => next => action => {...}
perhapsexport default ({getState, dispatch}) => next => action => {...}
, it depends on your preference
the actual calling sequence is as follows (defined inredux
ofapplyMiddleware.js
Middle):
1. middleware(middlewareAPI);
/*
var middlewareAPI = {
getState: store.getState,
dispatch: (action) => dispatch(action)
};
chain = middlewares.map(middleware => middleware(middlewareAPI));
dispatch = compose(...chain)(store.dispatch);
The first step is to execute the middleware for the first time, and initialize the dispatch (that is, the next parameter of the middleware) and getstate in each middleware with Redux's own dispatch.
To ensure that at least the Redux itself can work normally, the middleware store or_ Ref is the middlewareapi here
* */
2. dispatch = compose(...chain)(store.dispatch);
/*
The second step is to execute the middleware for the second time
That is, chain call the middleware set returned in step 1 in the form of compose. If the middleware is the last one defined in applymeddleware
Then the next in the middleware is store Dispatch, otherwise next is the result returned by the previous middleware, which can be understood as the previous middleware
As like as two peas, dispatch is the principle of dispatch, which is exactly the same as enhancer.
The purpose of enhancer is to encapsulate multiple createstores and call them in the form of compose
The purpose of middleware is to encapsulate multiple dispatches and call them in the form of compose
* */
Summary:
/*
So finally, in the createstore.com of redux The result of return enhancer (createstore) (reducer, preloadedstate) in JS is an enhancement
The enhanced store stores the enhanced dispatch
* */
/* ×××××××××××××××× About combinereducers ×××××××××××××××
*In terms of execution, combinereducers actually turns into a process of depth first traversal and execution of reducers
*Structurally, combinereducers determines the final structure or shape of our state tree, which is a tree structure
*Combinereducers (reducera, reducerb). Combinereducers (reducera-child1, reducera-child2) are nested in reducera
*In fact, the corresponding state tree is that there are two nodes a and B in the first layer, and there are two child nodes a-child1 and a-child2 under node a
*
*Therefore, in the initial design, we should imagine our final state tree, and then divide the reducer reasonably, just like designing the table structure of the database.
Of course, this is a general statement. In fact, there are too many things worth studying in the design of reducer or the division of state. We will talk about this later.
* */
bindActionCreator
bindActionCreator
Actually, it’s for youactionCreator
An additional layer of functions is added to the outer layer, and this layer of functions stores pairsdispatch
Reference to
function bindActionCreator(actionCreator, dispatch) {
return (...args) => dispatch(actionCreator(...args))
}
So we can usually call it directly in the componentbindActionCreator
ReturnedactionCreator
, i.ethis.props.loadSomething(...)
。 Instead of writingdispatch(actionCreator(...args))
In fact, they are equivalent
connect
now that I mentioned itredux
, because I’m usingreact
Development, so I have to mention the relevantreact-redux
。 The most important one isconnect
This function.
incomingconnect
The component of is called after it is mounted on the pagestore.subscribe
Subscribe. The purpose of subscription is that we calldispatch
It indicates that our state tree is about to change. At this time, we want our components to change, and the only way to change components issetState
。
subscription is tellingredux
, this component depends on a part of the state tree, so when you change, remember to get the lateststate
Then inform me that how I respond is my own business. Just inform me that the state tree has changed and pass it to me. It is worth mentioning that,connect
A lot of performance optimization has been carried out internally to avoid unnecessary rendering. About this andmapStateToProps
andmapDispathToProps
, we’ll talk about it later.
epilogue
The space is limited. This article will be like this for the time being. I want to share more content in the next article. At the same time, I am constantly learning and hope to understand it better.
It is worth mentioning that we may think that the authors of Redux, mobx, rxjs and other libraries with completely different ideas may be “extreme” and exclude others and ideas. In fact, this is incorrect. As early as May 16, Dan interacted with the author of mobx on twitter. They reached a consensus that they should cooperate with each other to promote their own and react development.
for Redux thunk, the document may first recommend using this simple library to deal with asynchronous related problems. For complex applications, they also recommend using libraries such as Redux saga to refactor their own code. On twitter, Dan also mentioned the application scenarios of the library many times. It is recommended that you first understand why you want to use it and what pain points it solves before using it. I even mentioned itissue, to understand the role of react router redux.
In addition, it is also mentioned that when there is plenty of time, learning react should start with itself. ES6, webpack, JSX, Redux, etc. are not directly related to react itself. After learning react, we know its own shortcomings, which areas need to be strengthened, which areas need to be introduced into a third-party database, and what pain points need to be solved, Only when we understand these tools can we really realize their power.
At this point, it’s a little far away, but I think it’s still necessary to mention it. That is, we are in a fickle society. Whether we treat friends, relatives and strangers in reality, we will more or less bring ourselves a little violent due to the pressure of study, work and life and the influence of the fickle atmosphere around us. On the Internet, due to the relaxation of constraints, we may release our repressed emotions to the vast online world. On microblog, post bar and Zhihu, we write and detect such behavior more or less.
However, as a programming ape, I still look forward to seeing our circle spend more time and energy on improving the existing technology, exploring the unknown world, pursuing the essence of programs, libraries, frameworks and ideas, making like-minded friends, communicating, sharing and thinking about technology. Instead of being involved in endless tearing, using the superiority of so and so, and even raising yourself by belittling others.
We can understand the temporary resentment, because most of us are really just ordinary social people. We can’t be more ordinary. But if we keep this state, we will always leave words, sarcasm and even abuse about people and things in the above scenes. I hope you can think about it for our future generations.