In ReactJS, the Reselect is a library that helps in providing efficient computation of data with selectors. It is a library that is used for building memoized selectors. It is mainly used in combination with Redux, which is a library used for state management in React applications. In this article, we will learn about Reselect and the different functions present in the library.
createSelector function: The createSelector is the main function provided by the Reselect library. It is used to create memoized selectors in Redux applications. This function takes one or more input selectors and a transformation function as arguments. It then returns a memoized selector function.
Syntax:
import { createSelector } from 'reselect';
const mySelector = createSelector(
[input1, input2, ...],
output1, output2, ...) => {
//compute output
};
);
Creating React Application:
Step 1: Create a React Application using the following command:
npx create-react-app reselectdemo
Step 2: After creating your project folder i.e. reselectdemo, move to it using the following command:
cd reselectdemo
Step 3: Install the Reselect library in your project using the following command:
npm install reselect
Project Structure:
Importing the createSelector function:
import { createSelector } from 'reselect';
Example 1: In this example, we will see the use of reselect. Firstly, we have to install the redux and react-redux libraries with the following command:
npm install redux react-redux
- counterReducer.js
Javascript
const initialState = { count: 0 }; const counterReducer = (state = initialState, action) => { switch (action.type) { case 'INCREMENT' : return { ...state, count: state.count + 1 }; default : return state; } }; export default counterReducer; |
- store.js
Javascript
import { createStore } from 'redux' ; import counterReducer from './counterReducer' ; const store = createStore(counterReducer); export default store; |
Now, we have to create selectors using Reselect.
- selectors.js
Javascript
import { createSelector } from 'reselect' ; const getCount = state => state.count; export const getSquare = createSelector( [getCount], count => count * count ); export const getCube = createSelector( [getCount], count => count * count * count ); |
Now, create a React Component and connect it to the Redux Store.
- Counters.jsx
Javascript
import React from 'react' ; import { connect } from 'react-redux' ; import { getSquare, getCube } from './selectors' ; const Counter = ({ count, square, cube, increment }) => { return ( <div> <p>Count: {count}</p> <p>Square: {square}</p> <p>Cube: {cube}</p> <button onClick={increment}> Increment </button> </div> ); }; const mapStateToProps = state => { return { count: state.count, square: getSquare(state), cube: getCube(state) }; }; const mapDispatchToProps = dispatch => { return { increment: () => dispatch({ type: 'INCREMENT' }) }; }; export default connect(mapStateToProps, mapDispatchToProps)(Counter); |
Now, Render the following component in your App.js file:
Javascript
import React from "react" ; import { Provider } from "react-redux" ; import Counters from "./Counters" ; import store from "./store" ; function App() { return ( <> <Provider store={store}> <Counters /> </Provider> </> ); } export default App; |
Step to Run: Run the Application using the following command from the root directory of the project.
npm start
Output:
In the above example, the Counters component uses the Reselect selectors getSquare and getCube to calculate the derived data from the Redux store’s derived value. As we increment the count, the square and cube values are dynamically calculated by the Reselect selectors, providing the updated derived data based on the current count value from the Redux store.
Example 2: In this example, we have a list of users with their names and ages. The initial filter value is set to 30 in the App.js
component using the setFilter
action. The getFilteredUsers
selector filters the users based on their age, only including users with an age greater than or equal to the filter value.
- selectors.js
Javascript
import { createSelector } from 'reselect' ; const getUsers = state => state.users; const getFilter = state => state.filter; export const getFilteredUsers = createSelector( [getUsers, getFilter], (users, filter) => { // Apply filtering logic here // For simplicity, let's assume // we filter by the user's age return users.filter(user => user.age >= filter); } ); |
- actions.js
Javascript
export const setFilter = filter => ({ type: 'SET_FILTER' , payload: filter }); |
Now, we will create the Reducers for our application.
- reducers.js
Javascript
const initialState = { users: [ { id: 1, name: 'John' , age: 25 }, { id: 2, name: 'Jane' , age: 30 }, { id: 3, name: 'Alice' , age: 28 }, { id: 4, name: 'Bob' , age: 32 } ], filter: 30 }; export default function userReducer( state = initialState, action) { switch (action.type) { case 'SET_FILTER' : return { ...state, filter: action.payload }; default : return state; } } |
Now, we will create a Redux Store.
- store.js
Javascript
import { createStore } from 'redux' ; import userReducer from './reducers' ; const store = createStore(userReducer); export default store; |
- App.js file
Javascript
import React, { useEffect } from 'react' ; import { useSelector, useDispatch } from 'react-redux' ; import { setFilter } from './actions' ; import { getFilteredUsers } from './selectors' ; const App = () => { const dispatch = useDispatch(); useEffect(() => { dispatch(setFilter(30)); }, [dispatch]); const filteredUsers = useSelector(getFilteredUsers); return ( <div> <h1>Filtered Users:</h1> <ul> {filteredUsers.map(user => ( <li key={user.id}>{user.name}</li> ))} </ul> </div> ); }; export default App; |
Render the App component in the index.js file of your React App:
Javascript
import React from 'react' ; import React from 'react' ; import ReactDOM from 'react-dom' ; import { Provider } from 'react-redux' ; import store from './store' ; import App from './App' ; ReactDOM.render( <Provider store={store}> <App /> </Provider>, document.getElementById( 'root' ) ); |
Output: