How to make pure, generic React components with immutable data that needs to be transformed
There's another solution that's commonly used with Redux: memoized selectors.
Libraries like Reselect provide a way to wrap a function (like your map call) in another function that checks the arguments for reference equality between calls, and returns a cached value if the arguments are unchanged.
Your scenario is a perfect example for a memoized selector—since you're enforcing immutability, you can make the assumption that as long as your usersList
reference is the same, the output from your call to map
will be the same. The selector can cache the return value of the map
function until your usersList
reference changes.
Using Reselect to create a memoized selector, you first need one (or more) input selectors, and a result function. The input selectors are generally used for selecting child items from a parent state object; in your case, you're selecting directly from the object you have, so you can pass the identity function as the first argument. The second argument, the result function, is the function that generates the value to be cached by the selector.
var createSelector = require('reselect').createSelector; // ES5import { createSelector } from 'reselect'; // ES6var usersListItemSelector = createSelector( ul => ul, // input selector ul => ul.map(user => { // result selector title: user.name, icon: user.avatar, description: `Age: ${user.age}`, }));// ...<ListView items={usersListItemSelector(usersList)} />
Now, each time React renders your ListView
component, your memoized selector will be called, and your map
result function will only be called if a different usersList
is passed in.