javascript 与基于类的方法相比,在使用 Hooks 设置状态后重新渲染有什么区别?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/55373878/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What are the differences when re-rendering after state was set with Hooks compared to the class-based approach?
提问by Magnus
Class Components
类组件
In React class components, we are told that setStatealwayscauses a re-render, regardless of whether or not the state actually changed to a new value. In effect, a component willre-render, when state updates to the samevalue it was before.
在 React 类组件中,我们被告知setState总是会导致重新渲染,无论状态是否实际更改为新值。实际上,当状态更新为与之前相同的值时,组件将重新渲染。
Docs (setState API Reference):
setState() will always lead to a re-render unless shouldComponentUpdate() returns false.
setState() 将始终导致重新渲染,除非 shouldComponentUpdate() 返回 false。
Hooks (Function Components)
钩子(函数组件)
With hooks however, the docs specify that updating state to a value identical to the previous state, will notcause a re-render (of child components):
但是,使用钩子,文档指定将状态更新为与先前状态相同的值,不会导致(子组件)重新渲染:
Docs (useState API Reference):
Bailing out of a state update
If you update a State Hook to the same value as the current state, React will bail out without rendering the children or firing effects. (React uses the Object.is comparison algorithm.)
退出状态更新
如果您将 State Hook 更新为与当前状态相同的值,React 将退出而不渲染子项或触发效果。(React 使用 Object.is 比较算法。)
Closely Related Questions
密切相关的问题
- Is it correct that
this.setStatein class components always cause a re-render, even when the newstatevalue is identical to the previous? - Is it correct that in function componentswith hooks,
setStatefromuseStateonly causes a re-render if thestatevalue is different from the previous value? - Is setting
statewiththis.setStateinside therendermethod of a class component, the same as settingstateinside the function body of a function component with hooks? - Is the following correct?
- In a class component, if we set
statein therendermethod an infinite loop will occur. This is because the class componentdoes not care that the newstateis the same as the previousstate. It just keeps re-rendering on everythis.setState. - In a function component with hookshowever, setting
stateinside the function body (which runs at re-render similarly to therendermethod in class components) would notbe an issue, because the function componentjust bails out of re-renders when it sees that thestateis identical to the previousstate.
- In a class component, if we set
this.setState即使新state值与以前的值相同,类中的组件总是会导致重新渲染,这是否正确?- 它是正确的,在功能部件与钩,
setState从useState只能导致重新绘制,如果state值与前值不同? - 在类组件的方法内部设置
statewith 和this.setState在函数组件的函数体内部设置带钩子一样吗?renderstate - 以下是否正确?
- 在类组件中,如果我们
state在render方法中设置,就会发生无限循环。这是因为class 组件并不关心 newstate是否与之前的相同state。它只是在每个this.setState. - 然而,在带有钩子的函数组件中,
state函数体内的设置(render与类组件中的方法类似,在重新渲染时运行)不会成为问题,因为函数组件只是在看到state与前一个相同state。
- 在类组件中,如果我们
采纳答案by Shubham Khatri
Is it correct that this.setState in class components always cause a re-render, even when the new state value is identical to the previous?
类组件中的 this.setState 总是导致重新渲染是否正确,即使新状态值与之前的值相同?
If you set a valid value apart from returning null within setState, a re-render will always be triggered by react in a class component unless your component is a PureComponent or you implement shouldComponentUpdate
如果在 setState 中设置除返回 null 之外的有效值,除非您的组件是 PureComponent 或您实现了 shouldComponentUpdate,否则重新渲染将始终由类组件中的 react 触发
Is it correct that in function components with hooks, setState from useState only causes a re-render if the state value is different from the previous value?
在带有钩子的函数组件中,如果状态值与之前的值不同,useState 中的 setState 只会导致重新渲染,这是否正确?
For a functional component using useStatehook, the setter if called with the same state will not trigger a re-render. However for an occasional case if the setter is called immediately it does result in two renders instead of one
对于使用useState钩子的功能组件,如果以相同的状态调用 setter,则不会触发重新渲染。但是对于偶尔的情况,如果立即调用 setter,它确实会导致两个渲染而不是一个渲染
Is setting state with this.setState inside the render method of a class component, the same as setting state inside the function body of a function component with hooks?
在类组件的render 方法中使用this.setState 设置状态,是否与使用钩子在函数组件的函数体中设置状态相同?
Techincally yes, setting a state directly in render method will cause the function to trigger re-render in case of class component causing an infinite loop which is the case for functional components provided the state values are different. Regardless of that, it will still cause an issue because any other state update will be reverted back due to functional component calling state update directly
技术上是的,直接在渲染方法中设置状态将导致函数在类组件导致无限循环的情况下触发重新渲染,如果状态值不同,则功能组件就是这种情况。无论如何,它仍然会导致问题,因为由于功能组件直接调用状态更新,任何其他状态更新都将被恢复
In a class component, if we set state in the render method an infinite loop will occur. This is because the class component does not care that the new state is the same as the previous state. It just keeps re-rendering on every this.setState.
在类组件中,如果我们在 render 方法中设置状态,将会发生无限循环。这是因为类组件并不关心新状态是否与之前的状态相同。它只是在每个 this.setState 上不断重新渲染。
Yes, hence its recommended not to call setState directly in render
是的,因此建议不要在渲染中直接调用 setState
In a function component with hooks however, setting state inside the function body (which runs at re-render similarly to the render method in class components) would not be an issue, because the function component just bails out of re-renders when it sees that the state is identical to the previous state.
然而,在带有钩子的函数组件中,在函数体内设置状态(它在重新渲染时运行,类似于类组件中的渲染方法)不会成为问题,因为函数组件只是在看到时退出重新渲染状态与之前的状态相同。
Not 100% true, since you can trigger state update using previous value such that the previous and current value are not same.For example
不是 100% 正确,因为您可以使用先前值触发状态更新,从而使先前值和当前值不同。例如
setCount(count => count + 1);
In such a case, you component will still fall in an infinite loop
在这种情况下,您的组件仍将陷入无限循环
回答by Flip
This is not a direct answer to the OP, but related and maybe helpful for some people new to React and/or Hooks and struggling with their side-effect and render timing.
这不是对 OP 的直接回答,而是与某些 React 和/或 Hooks 新手并在其副作用和渲染时间方面苦苦挣扎的人相关,并且可能会有所帮助。
Since it hasn't been mentioned here yet: In functional components rather than using the beforementioned (see comments of the accepted answer) ShouldComponentUpdate()function, which is for class-based Components only, you would use the useEffect()hook. With it you can tell your component when to run the side effects AND under which condition, e.g. when certain dependencies have changed.
由于此处尚未提及:在功能组件中,而不是使用之前提到的(参见已接受答案的评论)ShouldComponentUpdate()函数,该函数仅适用于基于类的组件,您将使用useEffect()钩子。有了它,您可以告诉您的组件何时运行副作用以及在何种条件下运行,例如当某些依赖项发生变化时。
In this example from the React docs, only when props.sourcechanged, the function will be executed.
在 React 文档中的这个示例中,只有在props.source更改时,才会执行该函数。
useEffect(
() => {
const subscription = props.source.subscribe();
return () => {
subscription.unsubscribe();
};
},
[props.source],
);

