停止重新渲染反应功能组件(使用钩子)

Posted

技术标签:

【中文标题】停止重新渲染反应功能组件(使用钩子)【英文标题】:Stop a react functional component (that uses hooks) from re-rendering 【发布时间】:2019-07-27 14:09:43 【问题描述】:

我有一个纯函数组件,我在其中使用 useEffect 获取一些数据。我将一个空字符串传递给 useEffect,所以它就像一个 组件确实挂载了

const getData = () => 
    setTimeout(() => 
        setLocalState( a: 2 );
        setIsLoading(false);
    , 0);
;

useEffect(() => getData(), []);

我的整个组件现在重新渲染两次。我想控制这种行为,并且只在某些条件下重新渲染。

这里,我希望组件在 setLocalState 已设置 localState 时重新渲染,但在 setIsLoading 已设置 isLoading em> 为假。

以下是针对此问题的代码沙箱: https://codesandbox.io/s/0oyp6j506p

【问题讨论】:

你能用isLoading = false而不是setIsLoading(false)将isLoading设置为false吗? useState() 钩子就像 class 组件中的 this.setState( ... ) 一样工作,根据定义,以这种方式更改 state 会导致重新渲染。 @sal 我确实想过,但这对我的情况没有帮助,因为如果我放置 @sallf 我试图编辑 ^ 上面的评论,但我超时了。我同意以正常方式声明isLoading 变量而不是将其与useState 绑定并从useState 获取setter 方法是一种解决方案。但我想找到一种方法来停止在 shouldComponentUpdate 的行上重新渲染,其中我 setState 使用 useState 的变量但阻止它重新渲染,因为它没有必要。 更新 - 将 isLoading 声明为 variable 或使用关键字 let 没有帮助,因为我在 @987654338 之后将其设置为 false @。但这不会导致重新渲染,因此 isLoading 仍然正确。 所以if (condition) setIsLoading(bool) else isLoading = bool 。这应该适用于您的要求,但不能说这是最佳实践。如果这不起作用,您能否更具体地说明您要完成的工作? 【参考方案1】:

如果我们在基于反应的事件之外调用多个状态设置器,将触发多个渲染,但在类组件中,状态更改将一起批处理。但在长期计划中,这将得到解决,这是提到的here

这似乎是正常的 React 行为。它的工作方式完全相同 如果您要在一个类组件中多次调用 setState()。

如果触发状态更新,React 当前将批量更新 在基于 React 的事件中,例如按钮单击或输入更改。它 如果它们是在 React 事件之外触发的,则不会批量更新 处理程序,例如 setTimeout()。

我认为有长期计划总是批量事件,但不确定 关于细节。

【讨论】:

感谢您告诉我这些。从现在开始,我将遵循这种做法。

以上是关于停止重新渲染反应功能组件(使用钩子)的主要内容,如果未能解决你的问题,请参考以下文章

组件不会重新渲染,但 redux 状态已通过反应钩子更改

如何防止我的功能组件使用 React 备忘录或 React 钩子重新渲染?

如何重新渲染 React 组件?

如何从无限重新渲染中停止反应组件

React 功能组件在重新挂载后停止渲染状态更改

React Hook 功能组件防止重新渲染