React 通过使用 useState 的功能变体来防止重新渲染

Posted

技术标签:

【中文标题】React 通过使用 useState 的功能变体来防止重新渲染【英文标题】:React prevent re-render by using functional variant of 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?

【问题讨论】:

【参考方案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) 中,完全避免了陈旧外壳的问题。 当您说“重新封闭在回调范围内”和“陈旧的外壳”时,我并不完全清楚......尝试再次阅读它以查看它是否有意义......但以防万一,您可以稍微简化一下(可能通过示例或其他方式),这将非常有帮助...

以上是关于React 通过使用 useState 的功能变体来防止重新渲染的主要内容,如果未能解决你的问题,请参考以下文章

React useState 和 useEffect 混淆

使用 useState 在 React 组件之间传递值

React Hook useState 的新功能返回未定义

具有 React useState 设置功能的打字稿类型的 Ramda 镜头组合

React-useState实现

react usestate 重新设置数据后,不渲染页面