React useMemo和redux createSelector的区别
·
目录
createSelector 和 useMemo 都是用于性能优化的记忆化(memoization)工具,但它们在用途、使用场景和实现机制上有重要区别:
一、createSelector
(Redux Toolkit/Reselect)
官网文档:https://redux.js.org/usage/deriving-data-selectors#createselector-overview
主要用于 Redux store state 的派生数据计算:
import { createSelector } from '@reduxjs/toolkit'
const selectUsers = state => state.users
const selectFilters = state => state.filters
// 创建记忆化的selector
export const selectFilteredUsers = createSelector(
[selectUsers, selectFilters],
(users, filters) => {
// 只有当 users 或 filters 改变时才重新计算
return users.filter(user =>
user.name.includes(filters.search) &&
user.active === filters.activeOnly
)
}
)
// 在组件中使用
const filteredUsers = useSelector(selectFilteredUsers)
二、useMemo
(React Hook)
主要用于 组件内部 的昂贵计算:
import { useMemo } from 'react'
function UserList({ users, filters }) {
const filteredUsers = useMemo(() => {
// 只有当 users 或 filters 改变时才重新计算
return users.filter(user =>
user.name.includes(filters.search) &&
user.active === filters.activeOnly
)
}, [users, filters])
return <div>{/* 渲染 filteredUsers */}</div>
}
三、主要区别
| 特性 | createSelector | useMemo |
|---|---|---|
| 使用场景 | Redux state 派生数据 | 组件内部计算 |
| 依赖来源 | Redux store state | 组件 props/state |
| 记忆化范围 | 全局(整个应用) | 组件实例级别 |
| 重新计算时机 | 输入selector结果变化时 | 依赖数组变化时 |
| 缓存策略 | 默认浅比较,可自定义 | 引用比较(Object.is) |
| 测试 | 易于单独测试 | 需要组件测试 |
四、使用建议
使用 createSelector 的情况:
-
从 Redux store 派生复杂数据
-
多个组件需要相同的派生数据
-
数据转换逻辑复杂或计算昂贵
// 推荐:复杂的Redux数据转换
export const selectUserStats = createSelector(
[selectUsers],
(users) => ({
total: users.length,
active: users.filter(u => u.active).length,
inactive: users.filter(u => !u.active).length
})
)
使用 useMemo 的情况:
-
组件内部的昂贵计算
-
基于 props 或本地 state 的派生数据
-
优化子组件重渲染
// 推荐:组件内部计算
function Chart({ data, config }) {
const processedData = useMemo(() => {
return data.map(item => ({
...item,
value: item.value * config.multiplier
}))
}, [data, config])
return <LineChart data={processedData} />
}
五、组合使用
两者可以结合使用以获得最佳性能:
// Redux selector - 第一层记忆化
export const selectProcessedData = createSelector(
[selectRawData],
(rawData) => rawData.map(processRawData)
)
// 组件内 - 第二层记忆化
function DataVisualization() {
const processedData = useSelector(selectProcessedData)
const [sortOrder, setSortOrder] = useState('asc')
const sortedData = useMemo(() => {
return [...processedData].sort((a, b) =>
sortOrder === 'asc' ? a.value - b.value : b.value - a.value
)
}, [processedData, sortOrder])
return <DataTable data={sortedData} />
}
六、总结
createSelector 用于 Redux 状态管理的记忆化,而 useMemo 用于 React 组件内部的记忆化。根据数据来源和使用场景选择合适的工具。
七、createSelector使用案例
import { createSelector } from 'reselect'
`输入选择器:从状态中提取原始数据`
const selectUser = (state) => state.user 【state.user 是 Redux Store 中的一个 slice】
const selectPosts = (state) => state.posts 【state.posts 是 Redux Store 中的一个 slice】
`Reselect 的 createSelector 会按顺序将 输入选择器的返回值,作为参数传递给转换函数。
因此,转换函数中的
user 对应 selectUser的返回值(即state.user)
posts 对应 selectPosts的返回值(即state.posts)`
const selectUserData = createSelector(
[selectUser, selectPosts], `【输入选择器数组】`
(user, posts) => ({ `【转换函数】`
username: user.name,
postCount: posts.length,
})
)
组件中使用:
import { useSelector } from 'react-redux'
import { selectUserData } from './selectors'
const Component = () => {
const { username, postCount } = useSelector(selectUserData)
return (
<div>
<h3>{username}</h3>
<p>Posts: {postCount}</p>
</div>
)
}
到此!
更多推荐



所有评论(0)