Our Global Presence
Canada
57 Sherway St,
Stoney Creek, ON
L8J 0J3
India
606, Suvas Scala,
S P Ring Road, Nikol,
Ahmedabad 380049
USA
1131 Baycrest Drive,
Wesley Chapel,
FL 33544
In a good Redux architecture, you are encouraged to keep your store state minimal, and derive data from the state as needed. As part of that process, we recommend that you use “selector functions” in your application, and use the Reselect library to help create those selectors. Here’s a depth detail of correct use of Reselect.
A “selector function” is simply any function that accepts the Redux store state (or part of the state) as an argument, and returns data that is based on that state. Selectors don’t have to be written using a special library, and it doesn’t matter whether you write them as arrow functions or the function
keyword. For example, these are all selectors:
const selectEntities = state => state.entities; function selectItemIds(state) { return state.items.map(item => item.id); } const selectSomeSpecificField = state => state.some.deeply.nested.field; function selectItemsWhoseNamesStartWith(items, namePrefix) { const filteredItems = items.filter(item => item.name.startsWith(namePrefix)); return filteredItems; }
You can call your selector functions whatever you want, but it’s common to prefix them with select
or get
, or end the name with Selector, like selectFoo
, getFoo
, or fooSelector
.
The first reason to use selector functions is for encapsulation and reusability.
The next reason to use selectors is to improve performance. Performance optimization generally involves doing work faster, or finding ways to do less work. For a React-Redux app, selectors can help us do less work in a couple different ways.
Let’s imagine that we have a component that requires a very expensive filtering/sorting/transformation step for the data it needs. To start with, its mapState
function looks like this:
const mapState = (state) => { const {someData} = state; const filteredData = expensiveFiltering(someData); const sortedData = expensiveSorting(filteredData); const transformedData = expensiveTransformation(sortedData); return {data : transformedData}; }
Right now, that expensive logic will re-run for every dispatched action that results in a state update, even if the store state that was changed was in a part of the state tree that this component doesn’t care about.
What we really want is to only re-run these expensive steps if state.someData
has actually changed. This is where the idea of “memoization” comes in.
Memoization is a form of caching. It involves tracking inputs to a function, and storing the inputs and the results for later reference. If a function is called with the same inputs as before, the function can skip doing the actual work, and return the same result it generated the last time it received those input values.
The Reselect library provides a way to create memoized selector functions. Reselect’s createSelector
function accepts one or more “input selector” functions, and an “output selector” function, and returns a new selector function for you to use.
const selectA = state => state.a; const selectB = state => state.b; const selectC = state => state.c; const selectABC = createSelector( [selectA, selectB, selectC], (a, b, c) => { // do something with a, b, and c, and return a result return a + b + c; } ); // Call the selector function and get a result const abc = selectABC(state); // could also be written as separate arguments, and works exactly the same const selectABC2 = createSelector( selectA, selectB, selectC, (a, b, c) => { // do something with a, b, and c, and return a result return a + b + c; } );
There’s a specific performance issue that can occur when you use memoized selectors with a component that can be rendered multiple times.
The React-Redux connect
function supports a special “factory function” syntax for mapState
and mapDispatch
functions, which can be used to create unique instances of selector functions for each component instance.
If the first call to a mapState
or mapDispatch
function returns a function instead of an object, connect
will use that returned function as the real mapState
or mapDispatch
function. This gives you the ability to create component-instance-specific selectors inside the closure:
const makeUniqueSelectorInstance = () => createSelector( [selectItems, selectItemId], (items, itemId) => items[itemId] ); const makeMapState = (state) => { const selectItemForThisComponent = makeUniqueSelectorInstance(); return function realMapState(state, ownProps) { const item = selectItemForThisComponent(state, ownProps.itemId); return {item}; } }; export default connect(makeMapState)(SomeComponent);
Both component 1 and component 2 will get their own unique copies of selectItemForThisComponent
, and each copy will get called with consistently repeatable inputs, allowing proper memoization.
Hire React.js Developer from us, as we give you high quality product by utilizing all the latest tools and advanced technology. E-mail us any clock at – hello@hkinfosoft.com or Skype us: “hkinfosoft“.
To develop custom web app using React.js, please visit our technology page.
Content Source:
57 Sherway St,
Stoney Creek, ON
L8J 0J3
606, Suvas Scala,
S P Ring Road, Nikol,
Ahmedabad 380049
1131 Baycrest Drive,
Wesley Chapel,
FL 33544
57 Sherway St,
Stoney Creek, ON
L8J 0J3
606, Suvas Scala,
S P Ring Road, Nikol,
Ahmedabad 380049
1131 Baycrest Drive,
Wesley Chapel,
FL 33544
© 2024 — HK Infosoft. All Rights Reserved.
© 2024 — HK Infosoft. All Rights Reserved.
T&C | Privacy Policy | Sitemap