即使数据没有改变,redux useSelector 也会重新渲染
react redux useSelector rerender even when data does not change
我正在使用 react with redux 和 redux thunk。
我有一个动作,我正在发出网络请求。
使用 useSelector 我从 redux 商店获取数据。
我有一个问题,即每次发送操作时组件都会重新呈现。
我希望组件仅在数据更改时重新呈现。
我已经尝试使用 shallowEqual 作为 useSelector 的第二个参数。但它不起作用。
我已经将它压缩到这个沙箱中的最小示例。在控制台中,您可以看到该组件随每个网络请求重新呈现。
这是代码框:
https://codesandbox.io/s/useselector-js6j0?file=/src/App.js:885-1294
代码如下:
function LevelThree() {
console.log(`Level three calls: ${++levelThreeCalls}`);
const contextData = useSelector(state => state.data);
console.log(contextData);
const dispatch = useDispatch();
useInterval(() => {
dispatch(updateData());
}, 1000);
return (
<div>
<button onClick={() => dispatch(updateData())}>Change context</button>
{contextData[0].userId}
</div>
);
}
你的组件在每次更新时都重新渲染的原因是你再次获取数据并在 redux 存储中更新它,
由于数据引用发生变化,useSelector
函数 returns 提供新值并重新呈现组件。
您可以将 deepEqual
比较函数作为第二个参数传递给 useSelector
以避免重新呈现数据未更改
import _ from 'underscore';
...
const contextData = useSelector(state => state.data, _.isEqual);
但是,您必须谨慎使用它并衡量数据更新的频率,否则您将在代码中添加额外的计算,这甚至不会阻止多次重新呈现
调度动作时,useSelector() 将对先前的选择器结果值和当前结果值进行引用比较。如果它们不同,组件将被强制重新渲染。如果相同,则组件不会重新渲染
我正在使用 react with redux 和 redux thunk。 我有一个动作,我正在发出网络请求。 使用 useSelector 我从 redux 商店获取数据。 我有一个问题,即每次发送操作时组件都会重新呈现。 我希望组件仅在数据更改时重新呈现。 我已经尝试使用 shallowEqual 作为 useSelector 的第二个参数。但它不起作用。 我已经将它压缩到这个沙箱中的最小示例。在控制台中,您可以看到该组件随每个网络请求重新呈现。 这是代码框: https://codesandbox.io/s/useselector-js6j0?file=/src/App.js:885-1294
代码如下:
function LevelThree() {
console.log(`Level three calls: ${++levelThreeCalls}`);
const contextData = useSelector(state => state.data);
console.log(contextData);
const dispatch = useDispatch();
useInterval(() => {
dispatch(updateData());
}, 1000);
return (
<div>
<button onClick={() => dispatch(updateData())}>Change context</button>
{contextData[0].userId}
</div>
);
}
你的组件在每次更新时都重新渲染的原因是你再次获取数据并在 redux 存储中更新它,
由于数据引用发生变化,useSelector
函数 returns 提供新值并重新呈现组件。
您可以将 deepEqual
比较函数作为第二个参数传递给 useSelector
以避免重新呈现数据未更改
import _ from 'underscore';
...
const contextData = useSelector(state => state.data, _.isEqual);
但是,您必须谨慎使用它并衡量数据更新的频率,否则您将在代码中添加额外的计算,这甚至不会阻止多次重新呈现
调度动作时,useSelector() 将对先前的选择器结果值和当前结果值进行引用比较。如果它们不同,组件将被强制重新渲染。如果相同,则组件不会重新渲染