Reselect是什么以及它在ReactJS中是如何工作的
在 ReactJS 中, Reselect 是一个帮助提供有效计算数据的库,使用 selectors 创建记忆化选择器。它主要与 Redux 一起使用,Redux是一个在React应用程序中用于状态管理的库。在本文中,我们将了解Reselect库及其不同的函数。
createSelector函数: createSelector是Reselect库提供的主要函数。它用于在Redux应用程序中创建记忆化选择器。该函数接受一个或多个输入选择器和一个转换函数作为参数,并返回一个记忆化选择器函数。
语法:
import { createSelector } from 'reselect';
const mySelector = createSelector(
[input1, input2, ...],
output1, output2, ...) => {
//compute output
};
);
创建React应用程序:
步骤1: 使用以下命令创建React应用程序:
npx create-react-app reselectdemo
步骤2: 在创建项目文件夹,即 reselectdemo 之后,使用以下命令进入该文件夹:
cd reselectdemo
步骤3: 在您的项目中使用以下命令安装Reselect库:
npm install reselect
项目结构:
导入createSelector函数:
import { createSelector } from 'reselect';
示例 1: 在这个示例中,我们将看到如何使用 reselect。首先,我们需要使用以下命令安装 redux 和 react-redux 库:
npm install redux react-redux
- counterReducer.js
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
import { createStore } from 'redux';
import counterReducer from './counterReducer';
const store = createStore(counterReducer);
export default store;
现在,我们需要使用Reselect来创建选择器。
- selectors.js
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
);
现在,创建一个React组件并将其连接到Redux Store。
- Counters.jsx
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);
现在,在您的 App.js 文件中渲染以下组件:
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;
运行步骤: 从项目的根目录中使用以下命令运行应用程序。
npm start
输出:
在上面的示例中, Counters 组件使用Reselect选择器 getSquare 和 getCube 从Redux store的派生值计算派生数据。当我们增加计数时,Reselect选择器动态计算平方和立方值,根据Redux store中当前计数值提供更新的派生数据。
示例2: 在这个示例中,我们有一个包含用户姓名和年龄的用户列表。初始的过滤器值在App.js
组件中设置为30,使用setFilter
动作。getFilteredUsers
选择器根据用户的年龄对用户进行过滤,只包括年龄大于或等于过滤器值的用户。
- selectors.js
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
export const setFilter = filter => ({
type: 'SET_FILTER',
payload: filter
});
现在,我们将为我们的应用程序创建Reducers。
- reducers.js
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;
}
}
现在,我们将创建一个 Redux Store。
- store.js
import { createStore } from 'redux';
import userReducer from './reducers';
const store = createStore(userReducer);
export default store;
- App.js 文件
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;
在你的 React App 的 index.js 文件中渲染 App 组件:
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')
);
输出: