【问题标题】:react redux useSelector rerender even when data does not change即使数据没有改变,react redux useSelector 也会重新渲染
【发布时间】:2020-09-24 14:51:42
【问题描述】:

我正在使用 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>
  );

}

【问题讨论】:

    标签: javascript reactjs redux react-hooks redux-thunk


    【解决方案1】:

    当一个动作被派发时,useSelector() 会对之前的选择器结果值和当前的结果值做一个参考比较。如果它们不同,组件将被强制重新渲染。如果它们相同,则组件不会重新渲染

    【讨论】:

      【解决方案2】:

      您的组件在每次更新时都重新渲染的原因是因为您再次获取数据并在 redux 存储中更新它,

      由于数据的引用发生了变化,useSelector 函数会返回一个新值并重新渲染组件。

      您可以将deepEqual 比较函数作为第二个参数传递给useSelector,以避免重新呈现数据未更改的情况

      import _ from 'underscore';
      ...
      const contextData = useSelector(state => state.data, _.isEqual);
      

      但是,您必须谨慎使用它并衡量数据的更新频率,否则您将在代码中添加一个额外的计算,这甚至不会阻止多次重新渲染

      Working demo

      【讨论】:

      • 谢谢 :) 链接失效。可以更新吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-05
      • 1970-01-01
      • 2017-12-29
      • 2020-01-20
      • 2022-01-22
      相关资源
      最近更新 更多