SoFunction
Updated on 2025-04-07

A brief discussion on the connection between React and Redux react-redux

I have been exploring React-related things before and have a SPA project on my hand, so I am preparing to try it on Redux. Redux itself and React have no connection. It is a general Javascript App module used for the management of App State. To use Redux in React projects, the better way is to use the react-redux library to make connections. The meaning here is that it is not that there is no react-redux, and these two libraries will not be used together. Instead, react-redux provides some encapsulation, a more scientific way of organizing code, allowing us to use Redux more comfortably in React code.

I used to understand react-redux only through the Redux documentation. After a period of practice, I was going to flip through the source code and make some relevant summary. The npm version of the code I'm looking at is v4.0.0, which means the React version used is 0.

react-redux provides two key modules: Provider and connect.

Provider

The Provider module is used as a container for the entire app. It also includes a layer based on your original App Container. Its work is very simple, which is to accept the Redux store as props and declare it as one of the properties of the context. The child components can easily access the store after declaring contextTypes. However, our components usually do not need to do this. Putting the store in the context is for the purpose of using the following connect.

This is a sample of the Provider:

// config app root
const history = createHistory()
const root = (
 <Provider store={store} key="provider">
  <Router history={history} routes={routes} />
 </Provider>
)

// render
(
 root,
 ('root')
)

connect

This module is truly connected to Redux and React, and its name is also called connect.

Let’s first consider how Redux works: First, a state is maintained in the store, we dispatch an action, and then reducer updates the state according to this action.

Map into our React application, the state maintained in the store is our app state. A React component serves as the View layer, which does two things: render and respond to user operations. So connect passes the necessary data in the store as props to the React component to render, and wraps the action creator to dispatch an action in response to user operations.

OK, let's take a look at what the connect module does in detail. First of all, its API is as follows:

connect([mapStateToProps], [mapDispatchToProps], [mergeProps], [options])

mapStateToProps is a function, and the return value indicates the state that needs to be merged into props. The default value is () => ({}), which means nothing is passed.

(state, props) =&gt; ({ }) // The second parameter is usually omitted

mapDispatchToProps can be a function, and the return value indicates that actionCreators that require merge only props. The actionCreator here should have been dispatched. It is recommended to use redux's bindActionCreators function.

(dispatch, props) =&gt; ({ // The second parameter is usually omitted ...bindActionCreators({
  ...ResourceActions
 }, dispatch)
})

What is more convenient is that you can directly accept an object. At this time, the connect function will be converted into a function. This function is exactly the same as the example above.

mergeProps is used to customize merge process. The following is the default process. The parentProps value is the component's own props. You can find that if the same name appears on the component's props, it will be overwritten.

(stateProps, dispatchProps, parentProps) => ({
 ...parentProps,
 ...stateProps,
 ...dispatchProps
})

There are two switches in options: pure represents whether to turn on optimization. The details will be mentioned below. The default is true. WithRef is used to give a ref to the component wrapped inside. This ref can be obtained through the getWrappedInstance method, and the default is false.

connect returns a function that accepts a React component's constructor as a connection object and finally returns the connected component constructor.

Then several questions:

  1. How does React components respond to changes in the store?
  2. Why connect selectively merge some props instead of passing the entire state in directly?
  3. What is pure optimized?

We call the function returned by connect Connect, which returns an internal component called Connect. On the basis of wrapping the original component, it also listens to changes in the Redux store internally, in order to enable the components wrapped by it to respond to changes in the store:

trySubscribe() {
 if (shouldSubscribe && !) {
   = (::)
  ()
 }
}

handleChange () {
 ({
  storeState: ()
 })
}

But usually, what we connect is a Container component, which does not host all App states. However, our handler responds to all state changes. So what we need to optimize is: when the storeState changes, we will only re-resource the corresponding React component when we really rely on that part of the state changes. So what is the part we really rely on? It is obtained through mapStateToProps and mapDispatchToProps.

The specific optimization method is to check in shouldComponentUpdate. If the shouldComponentUpdate will return true only when the component's own props change, or the result of mapStateToProps changes, or the result of mapDispatchToProps changes, the checking method is to compare shallowEqual.

So for a reducer:

export default (state = {}, action) =&gt; {
 return { ...state } // What is returned is a new object that may cause the component to reRender // return state // may not make the component reRender}

In addition, when connecting, be careful to the state or actionCreators that map really needs to go to the props to avoid unnecessary performance losses.

Finally, according to the connect API, we found that ES7 decorator function can be used to match the writing method of React ES6:

@connect(
 state => ({
  user: ,
  resource: 
 }),
 dispatch => ({
  ...bindActionCreators({
   loadResource: 
  }, dispatch)
 })
)
export default class Main extends Component {

}

OK, the above is all about this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.