【问题标题】:React prevent re-render by using functional variant of useStateReact 通过使用 useState 的功能变体来防止重新渲染
【发布时间】:2021-12-10 02:53:17
【问题描述】:

我试图了解在一种情况下使用普通 setState V/s 导致功能组件重新渲染的确切差异,另一种情况使用功能状态更新

相关代码sn-p如下

案例 1:导致组件重新渲染

const onRemove = useCallback(
  tickerToRemove => {
    setWatchlist(watchlist.filter(ticker => ticker !== tickerToRemove));
  },
  [watchlist]
);

案例2:不会导致重新渲染

const onRemove = useCallback(tickerToRemove => {
  setWatchlist(watchlist =>
    watchlist.filter(ticker => ticker !== tickerToRemove)
  );
}, []);

这两个用例的完整示例可以在上面看到;

https://codesandbox.io/s/06c-usecallback-final-no-rerenders-bsm64?file=/src/watchlistComponent.js

https://codesandbox.io/s/06b-usecallback-usememo-ngwev?file=/src/watchlistComponent.js:961-970

更新

全文链接 https://medium.com/@guptagaruda/react-hooks-understanding-component-re-renders-9708ddee9928#204b

对于如何防止子组件的重新渲染,我有点困惑。

文章里说

"谢天谢地,useState 钩子中的 setter 函数支持函数 变体来拯救我们。而不是调用 setWatchlist 使用更新的监视列表数组,我们可以改为发送一个函数 获取当前状态作为参数"

但是,我有点困惑是否因为我们使用空数组(因为 [] 在渲染之间没有变化)而阻止了子组件的重新渲染,因为使用了 useState 钩子的 setter 变体而阻止了 V/s?

【问题讨论】:

    标签: javascript reactjs react-hooks use-state usecallback


    【解决方案1】:

    是否使用功能状态更新与您所问的问题无关。您似乎在问为什么 (1) 具有依赖关系的回调会触发重新渲染,而 (2) 具有空依赖关系的回调会触发。

    答案非常简单。在版本 (2) 中,您提供了从组件挂载时开始的稳定回调引用永不改变,而在 (1) 中,回调引用在依赖项发生时改变。请记住,当状态或 props 更新时 React 组件会重新渲染(新的回调引用是新的 prop 引用 当父组件重新渲染时。由于 onRemove 属性在 (1) 中更新,它会触发重新渲染。

    【讨论】:

    • Oh k...其实我指的是这篇文章,里面有这个例子(在 useCallback & useMemo 部分)medium.com/@guptagaruda/…
    • 在文章中它说.....谢天谢地,useState 钩子中的 setter 函数支持一个功能变体,它可以帮助我们。我们可以发送一个获取当前状态作为参数的函数,而不是使用更新的监视列表数组调用 setWatchlist。
    • 所以我现在有点困惑......是否阻止了所有其他子组件的重新渲染,因为我们使用了空数组([] 在渲染之间没有变化)而不是因为使用useState 钩子的 setter 变体?
    • @copenndthagen 功能状态更新更多地与从先前状态正确更新(无论之前更新过的地方或无论如何)与使用任何内容的“标准”更新有关状态值在回调范围内关闭。在版本 (1) 中,有必要将状态添加到 useCallback 依赖数组,以便可以在回调范围内重新封闭当前值,即避免陈旧的状态封闭。在使用功能状态更新的版本 (2) 中,完全避免了陈旧外壳的问题。
    • 当您说“重新封闭在回调范围内”和“陈旧的外壳”时,我并不完全清楚......尝试再次阅读它以查看它是否有意义......但以防万一,您可以稍微简化一下(可能通过示例或其他方式),这将非常有帮助...
    猜你喜欢
    • 2020-03-17
    • 2021-02-14
    • 2021-01-07
    • 1970-01-01
    • 2021-09-29
    • 2021-11-26
    • 1970-01-01
    • 2019-07-28
    • 1970-01-01
    相关资源
    最近更新 更多