Why reselect is so good Reselect is a popular library that provides a convenient way of getting values from a store in a React-Redux application. What makes it so good is its memoization ability. You can read all this in the documentation. In two words, when you use the function, it memiozes an output of every input selector and recalculates the resulting value only if any of the input selectors changes its output. The important thing to note here is that reselect uses reference equality (===) to determine a value change. createSelector() As a motivation to use memoization the documentation suggests an increase of performance, because recalculation on every call may be quite expensive. But we will see in this article that using a memoized selector is sometimes the only way to go in a React-Redux application, even if calculations are very cheap and don’t affect performance. How a React-Redux connected component works First of all, let’s take a look at how a React-Redux application works. What Redux does in essence, is provide us with a store for our app’s state and with ways to communicate with the store. One of these ways is the function. After calling on a custom component you get a wrapper that passes state from a store as props to your component. This happens by means of function which is called on every state change. connect() connect() mapStateToProps() After yields recalculated props, the new props are shallow compared to the old ones and if they differ, component gets rerendered. Again, reference equality (===) is used to compare the props. mapStateToProps() An unmemoized selector can ruin your day Here we can make a use of an example. Let’s make up an application called List of Goods. The app will be based on with an immutable state (see ). react-boilerplate Immutable.js We define a state for our app: import {SET_GOODS, SET_SORTED, COUNT} from 'constants/index';import {fromJS} from 'immutable'; const initialState = fromJS({goods: [{name: 'tomatoes',price: 3,},{name: 'potatoes',price: 2,},{name: 'cucumbers',price: 5,},{name: 'salad',price: 1,}],sorted: false,}); export default ( = initialState, ) => {switch ( .type) {case SET_SORTED: {return .set('sorted', .sorted);}default: {return initialState;}}} state action action state action And a couple of components: class GoodsList extends React.Component {render () {return (< >< >{this.props.goods.map(( , ) =>< key={ }>{`${ .get('name')} - ${ .get('price')}$`}</ >)}</ ></ >)}} div ul g i li i g g li ul div const mapStateToProps = ( ) => {return {goods: getGoods( ),};} state state const mapDispatchToProps = ( ) => bindActionCreators({count,}, ; dispatch dispatch export default connect(mapStateToProps, mapDispatchToProps)(GoodsList); class Buttons extends React.Component {render () {return (< style={{display: 'flex'}}>< style={buttonStyle}onClick={() => this.props.setSorted(true)}> </ >< style={buttonStyle}onClick={() => this.props.setSorted(false)}> </ ></ >)}} div button Show Sorted button button Show Unsorted button div const mapStateToProps = ( ) => {return {}} state const mapDispatchToProps = ( ) => bindActionCreators({setSorted,}, ); dispatch dispatch export default connect(mapStateToProps, mapDispatchToProps)(Buttons); Also we have a page containing our components: export default class HomePage extends React.PureComponent {render() {return (< >< />< /></ >);}} div GoodsList Buttons div The app only renders the list of goods, either sorted by price (when a user clicks the ‘Show sorted’ button) or unsorted (by default and when a user clicks the ‘Show unsorted’ button). In the state we have which is the very list of goods we want to show and which tells us, if the list should be rendered sorted or unsorted. goods sorted The only thing we need to do to get it work now is to define a selector. Let’s try an unmemoized selector first. Basically, this is just a function, like this: export const getGoods = ( ) => {const list = .getIn(['main', 'goods']);const sorted = .getIn(['main', 'sorted']); state state state return sorted ? list.sort(( , ) => {const aPrice = .get('price');const bPrice = .get('price');if (aPrice < bPrice) { return -1; }if (aPrice > bPrice) { return 1; }if (aPrice === bPrice) { return 0; }}) : list;} a b a b Depending on the value of , this selector either just returns the list of goods from the state or sorts it by price before returning. Let’s take a closer look at what happens here. The Immutable.js documentation says: “sort() always returns a new instance, even if the original was already sorted”. This means, our sorted list of goods will never be equal to the previously sorted list of goods. Reference equality for prop of GoodsList component will never hold, meaning the component will be rerendered on every state change, even if this change doesn’t affect the list of goods in any way. sorted goods While this is obviously a wrong way to create a selector, it doesn’t look like a big deal so far. The calculations in the selector are very cheap for our list of only four items, there will not be any significant drop of performance. But what if we need to change state in component’s lifecycle? As suggests, we will do it in componentWillReceiveProps method. Say, we need to count for some reason how many times GoodsList received props. So, we add componentWillReceiveProps to GoodsList component: React documentation componentWillReceiveProps = ( ) => {this. .count();} nextProps props Here is an action dispatched to store. count And the reducer will look like this: import {SET_GOODS, SET_SORTED, COUNT} from 'constants/index';import {fromJS} from 'immutable'; const initialState = fromJS({goods: [...],sorted: false,count: 0,}); export default ( = initialState, ) => {switch ( .type) {case SET_SORTED: {return .set('sorted', .sorted);}case COUNT: {return .set('count', .get('count') + 1);}default: {return initialState;}}} state action action state action state state The following sequence of actions is fired when a user clicks ‘Show sorted’: action with value is dispatch to store. SET_SORTED true The value of is changed in the state. sorted connected component calls . GoodsList mapStateToProps Selector is called from . getGoods mapStateToProps Selector returns the sorted list which is not equal to the list already passed to . GoodsList As returned props that are not shallow equal to the component’s previous props, React starts rerendering. mapStateToProps GoodsList lifecycle method is called. GoodsList componentWillReceiveProps Action is dispatch to store. COUNT The value of is changed in the state. count Points 3–9 are repeated once again. And then one more time. And then… well, it will never stop. We’ve got an endless cycle. This case with counting received props might look a bit artificial, but this may happen in real life. For example, when you set initial values for a , an action is dispatched to store. Or if you need to store route params in the state, you will set them as an object which will cause the state to change and you are likely to do that in componentWillReceiveProps(), because a route may change without unmounting a component. Both these cases effectively behave as if you count received props in componentWillReceiveProps(). redux-form Reselect may or may not help you We can easily fix this with Reselect. This selector will work fine in our case: import {createSelector} from 'reselect'; const getList = ( ) => .getIn(['main', 'goods']);const getSorted = ( ) => .getIn(['main', 'sorted']); state state state state export const getGoods = createSelector(getList,getSorted,( , ) => {return ? .sort(( , ) => {const aPrice = .get('price');const bPrice = .get('price');if (aPrice < bPrice) { return -1; }if (aPrice > bPrice) { return 1; }if (aPrice === bPrice) { return 0; }}) : ;}) list sorted sorted list a b a b list Here the transform function will not be called until or change their values which they don’t on action. Instead, selector just returns the previously calculated value which is obviously equal to the list already passed to component. React doesn’t try to rerender the component for the second time, the cycle breaks. getList getSorted COUNT getGoods GoodsList There is one peril, however: it is quite easy to accidentally make a Reselect selector unmemoized. For example, you might want to use a JavaScript array in your component instead of the immutable list for some reason. But this selector will again cause an endless cycle to start on ‘Show sorted’ click: import {createSelector} from 'reselect'; const getList = ( ) => .getIn(['main', 'goods']).toJS();const getSorted = ( ) => .getIn(['main', 'sorted']); state state state state export const getGoods = createSelector(getList,getSorted,( , ) => {return ? .sort(( , ) => .price - .price) : ;}) list sorted sorted list a b a b list Although is a memoized selector here, it gets a different input from getList every time. In general, selectors that get values from the state shouldn’t do anything else, because they are not memoized. getGoods Another possibility for a mistake is curried selectors. Sometimes you want to create selectors like this just in case if you need to pass arguments to a selector in future: export const getGoods = () => createSelector(...) And it is tempting to write this way then: mapStateToProps const mapStateToProps = ( ) => {return {goods: getGoods()( ),};} state state But here we create a new instance of the selector every time is called. Basically we just throw away the memoization ability of our selector, because every new instance calculates its value again and this value is not equal to the value calculated by another instance. mapStateToProps These kinds of a bug are quite annoying because often you don’t notice when you create a bug and stumble across it many commits later. Thankfully, can help you find where it went wrong. git bisect Top tips to make your life better To sum up, I will designate some tips I derived for myself while using Reselect library. Always use from Reselect to create a selector, if it transforms value from the state in any way. createSelector() Avoid curried selectors. As a rule, you don’t need them. You can pass all the arguments you need using the second argument of a selector. In fact, the only case I can think of when you need a curried selector is described in the documentation . Be careful with dispatching actions to the store from lifecycle functions. In general, avoid doing this. But if you have to, maybe it is a good idea to compare props manually before dispatching an action. Don’t use selectors like or as input selectors. If you access big parts of the state, these parts are very likely to change on every action. If you really need to, you will probably have to memoize the transform function yourself. This may be done by using from or or something else. state => state state => state.get(‘main’) memoize() Lodash Ramda Also, you can find the example I used here on if you want to play around with the selectors and simulate some other cases. GitHub _Redux saga is a middleware between an application and redux store, that is handled by redux actions. This means, it can…_hackernoon.com Missing part of Redux Saga Experience _After applying few simple manipulations to the result of Normalizr’s work we get data that we can keep in store_hackernoon.com Using Normalizr to organize data in stores — practical guide _The second part of the article about how to use Normalizr to organize data in stores._hackernoon.com Using Normalizr to organize data in store. Part 2 _Javascript has two major ways of dealing with asynchronous tasks — callbacks and Promises. In general Promises are…_hackernoon.com How to Stop Using Callbacks and Start Living Written by Ilya Bohaslauchyk