Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62
Subscribe to my email list now at http://jauyeung.net/subscribe/
With Redux, we can use it to store data in a central location in our JavaScript app. It can work alone and it’s also a popular state management solution for React apps when combined with React-Redux.
In this article, we’ll look at how to use mapStateToProps
to subscribe to the store’s state and them to a React component’s props.
mapStateToProps Definition
The React Redux’s mapStateToProps
has 2 parameters. The first is the state
and the second is an optional ownProps
parameter.
It returns a plain object containing the data that the connected component needs.
It doesn’t matter if it’s a traditional function or an arrow function. Both kinds will give the same result.
The first argument, which is state
, has the entire Redux store state. It’s the same value returned by store.getState()
.
It’s usually called state
. However, we can call it whatever we want.
The second parameter, ownProps
, is an optional parameter that has the props of a component.
In the following example:
import React from "react";
import ReactDOM from "react-dom";
import { connect, Provider } from "react-redux";
import { createStore } from "redux";
function message(state = "hello", action) {
switch (action.type) {
default:
return state;
}
}
const store = createStore(message);
function Message({ color, message }) {
return <div style={{ color }}>{message}</div>;
}
const mapStateToProps = (state, ownProps) => {
const { color } = ownProps;
return { color, message: state };
};
Message = connect(mapStateToProps)(Message);
function App() {
return (
<div className="App">
<Message color="blue" />
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
rootElement
);
ownProps
would have the value of the color
prop because that’s what we passed in.
In this case, that should beblue
.
From the mapStateToProps
function, we should also get the state from the store. In this case, we get the 'hello'
string returned from the message
reducer function. So we should see ‘hello’ in the browser screen.
mapStateToProps
function should be pure and synchronous. It only take the state
and ownProps
and return something that’s derived from it by running synchronous code.
This means no asynchronous HTTP calls, setTimeout
, async functions, etc.
Return Values Determine If Your Component Re-Renders
React-Redux internally implements the shouldComponentUpdate
method. Therefore, the Provider
will re-render when the data of our component has changed.
Data also includes entities retrieved from mapStateToProps
.
The comparison is done by using the ===
comparison on each field of the returned object.
mapStateToProps
runs when the store state
changes. Or when state
changes or ownProps
is different if both state
and ownProps
are referenced.
The component re-renders when any field that’s returned by mapStateToProps
is different.
If both state
and ownProps
are referenced in mapStateToProps
, the component re-renders when any field of stateProps
or ownProps
are different.
Only Return New Object References If Needed
Because mapStateToProps
and re-rendering is done when we return new object or array references, we should only return new objects when we need them.
Therefore, we should avoid any code that returns new objects, like array.map()
, array.filter()
, etc.
If we need to run code that returns new object references, then they should be memoized so that they don’t trigger re-render even if their content is the same.
Photo by Pineapple Supply Co. on Unsplash
mapStateToProps
Will Not Run if the Store State is the Same
Every time an action is dispatched, store.getState()
is called to check if the previous state and the current state are the same.
If both states are identical by reference, then mapStateToProps
won’t be run again since it assumes that the rest of the store haven’t changed.
combineReducers
returns the old state object instead of the new one if there’re no changes in the store’s state.
The Number of Declared Arguments Affects Behavior
If ownProps
is omitted from the parameters, then ownProps
won’t be retrieved. Therefore, we should only add ownProps
to the parameter is we need it.
For example, if we have the following mapStateToProps
function:
function mapStateToProps(state) {
console.log(state)
console.log(arguments[1])
}
The arguments[1]
is undefined
since we didn’t include the ownProps
parameter.
Conclusion
We can define mapStateToProps
and use it to get the latest state from our Redux Store to our React app via the connect
function.
It has 2 parameters, which are state
for the store’s state and ownProps
for the props that we pass into the component ourselves.
The connect
function lets us pass in mapStateToProps
as the first argument and returns a function where we can pass in our component into the it and returns a new component that subscribes to the store’s state and gets it as props.