new*_*ent 3 typescript reactjs redux react-redux reselect
有没有办法从 Redux 存储中的数组中选择派生数组而不进行虚假渲染?
我的 Redux 存储包含一个对象数组。
state = {items: [{id: 1, keys...}, {id: 2, keys...}, {id: 3, keys...}, ...]}
Run Code Online (Sandbox Code Playgroud)
我编写了一个选择器来返回 id 数组。
const selectIds = (state: MyStateType) => {
const {items} = state;
let result = [];
for (let i = 0; i < items.length; i++) {
result.push(items[I].id);
}
return result;
};
Run Code Online (Sandbox Code Playgroud)
然后,我在组件内部使用 React-Redux 的useSelector钩子调用这个选择器来渲染组件列表。
const MyComponent = () => {
const ids = useSelector(selectIds);
return (
<>
{ids.map((id) => (
<IdComponent id={id} key={id} />
))}
</>
);
};
Run Code Online (Sandbox Code Playgroud)
我发现MyComponent每次调用调度都会渲染它,这会破坏大量数组元素的性能。
我已经向 useSelector 传递了一个相等函数,如下所示:
import {shallowEqual, useSelector } from "react-redux";
const ids = useSelector(selectIds, (a, b) => {
if (shallowEqual(a, b)) {
return true;
}
if (a.length !== b.length) {
return false;
}
for (let i = 0; i < a.length; i++) {
if (a[i].id !== b[i].id) {
return false;
}
}
return true;
});
Run Code Online (Sandbox Code Playgroud)
但调度被调用的次数足够多,因此对于大量数组元素,检查相等性变得昂贵。
reselect我也尝试过使用该库。
const selectItems = (state: MyStateType) => {
return state.items;
};
const selectIds = createSelector(
selectItems,
(items) => {
let result = [];
for (let i = 0; i < items.length; i++) {
result.push(items[i].id);
}
return result;
}
);
Run Code Online (Sandbox Code Playgroud)
然而,每次我通过调度修改一个数组元素的属性时,都会改变导致重新计算state.items的依赖关系。selectItemsselectIds
我想要的是仅在修改selectIdsid 时重新计算。state.items这可能吗?
小智 5
我认为你在这里能做的最好的事情就是结合reselect使用shallowEqual:
import { shallowEqual } from "react-redux";
const selectItems = (state: MyStateType) => state.items;
const selectIds = createSelector(
selectItems,
(items) => items.map(item => item.id)
);
const MyComponent = () => {
const ids = useSelector(selectIds, shallowEqual);
return (
<>
{ids.map((id) => (
<IdComponent id={id} key={id} />
))}
</>
);
};
Run Code Online (Sandbox Code Playgroud)
笔记
shallowEqual可以直接传递给useSelector通过上面的代码:
state.items。ids仅当 ids 更改时,该变量才会有新的引用。如果这个解决方案还不够(买不起shallowEqual)你可以看看https://github.com/dai-shi/react-tracked它使用更精确的系统来跟踪状态的哪一部分被使用(使用代理:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy)。
| 归档时间: |
|
| 查看次数: |
1417 次 |
| 最近记录: |