即使数据未更改也对redux useSelector进行反应

时间:2020-06-05 11:47:46

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

我正在使用redux和redux thunk反应。 我在执行网络请求时有一个动作。 使用useSelector我从redux存储中获取数据。 我遇到的问题是,每次我分派动作时,组件都会重新渲染。 我希望该组件仅在数据更改时才重新渲染。 我试过已经使用shallowEqual作为useSelector的第二个参数。但这是行不通的。 我已将其压缩为此沙箱中的最小示例。在控制台中,您可以看到该组件随每个网络请求都重新提供。 这是codeandbox: 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>
  );

}

2 个答案:

答案 0 :(得分:2)

每次更新都会重新呈现组件的原因是因为您要再次获取数据并在redux存储中对其进行更新,

由于数据引用发生了变化,useSelector函数将为您返回一个新值并重新呈现该组件。

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

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

但是,您必须谨慎地使用它,并测量数据的更新频率,否则您将在代码中添加添加的计算,甚至无法阻止多次重新渲染

Working demo

答案 1 :(得分:1)

当一个动作被分派时,useSelector() 会对前一个选择器结果值和当前结果值进行引用比较。如果它们不同,组件将被迫重新渲染。如果它们相同,则组件不会重新渲染