This article mainly introduces three points that need to be paid attention to when using React.setState. It puts forward three points that are easy to ignore for React novices. It has certain reference value. Interested friends can For reference
Preface
The original title of this article is 3 Reasons why I stopped using React.setState, but I am not very interested in the arguments put forward by the original author, but The three points raised by the author are easy to ignore for React novices, so I will only mention part of the content here, and change the title to three points that need to be paid attention to when using React.setState.
Text
For React novices, using setState is a very complicated thing. Even if you are skilled in React development, it is very likely that some bugs will occur due to some mechanisms of React, such as the following example:
The document also explains when using setState When doing this, what should you pay attention to:
Note:
Never change this.state directly, because calling setState() later may replace the changes you made
Change. Treat this.state as immutable.
setState() does not change this.state immediately, but creates a state transition that will be processed soon. Accessing this.state after calling this method may return the existing value.
There are no synchronization guarantees for calls to setState, and calls may be batched for performance gains.
setState() will always trigger a redraw unless conditional rendering logic is implemented in shouldComponentUpdate(). If mutable objects are used and this logic cannot be implemented in shouldComponentUpdate(), calling setState() only when there is a difference between the new state and the previous state can avoid unnecessary re-rendering.
To sum up, when using setState, there are three issues to pay attention to:
1. setState is asynchronous (Translator's Note: Synchronization is not guaranteed)
Many developers did not notice that setState is asynchronous at first. If you modify some state and then view it directly, you will see the previous state. This is the most error-prone place in setState. The word setState doesn't look asynchronous, so it can cause bugs if you use it without thinking. The following example illustrates this problem well:
class Select extends React.Component { constructor(props, context) { super(props, context) this.state = { selection: props.values[0] }; } render() { return ( <ul onKeyDown={this.onKeyDown} tabIndex={0}> {this.props.values.map(value => <li className={value === this.state.selection ? 'selected' : ''} key={value} onClick={() => this.onSelect(value)} > {value} </li> )} </ul> ) } onSelect(value) { this.setState({ selection: value }) this.fireOnSelect() } onKeyDown = (e) => { const {values} = this.props const idx = values.indexOf(this.state.selection) if (e.keyCode === 38 && idx > 0) { /* up */ this.setState({ selection: values[idx - 1] }) } else if (e.keyCode === 40 && idx < values.length -1) { /* down */ this.setState({ selection: values[idx + 1] }) } this.fireOnSelect() } fireOnSelect() { if (typeof this.props.onSelect === "function") this.props.onSelect(this.state.selection) /* not what you expected..*/ } } ReactDOM.render( <Select values={["State.", "Should.", "Be.", "Synchronous."]} onSelect={value => console.log(value)} />, document.getElementById("app") )
At first glance, there seems to be nothing wrong with this code. The onSelect method is called in both event handlers. However, there is a bug in this Select component that nicely illustrates the previous GIF. The onSelect method always passes the previous state.selection value, because when fireOnSelect is called, setState has not completed its work. I think React should at least change setState to scheduleState or make the callback function a required parameter.
This bug is easy to fix. The hardest part is that you need to know that there is this problem.
2. setState will cause unnecessary rendering
The second problem caused by setState is: each call will cause re-rendering. Many times, these re-renders are unnecessary. You can use printWasted in the React performance tools to see when unnecessary rendering occurs. However, roughly speaking, there are several reasons for unnecessary rendering:
The new state is actually the same as the previous one. This problem can usually be solved with shouldComponentUpdate. You can also use pure render or other libraries to solve this problem.
Usually the changed state is related to rendering, but there are exceptions. For example, some data is displayed based on certain states.
Third, some states have nothing to do with rendering. Some state may be related to events and timer IDs.
3.setState cannot effectively manage all component states
Based on the last point above, not all component states are SetState should be used to save and update. Complex components may have a variety of states that need to be managed. Using setState to manage these states will not only cause a lot of unnecessary re-rendering, but also cause related life cycle hooks to be called all the time, causing many strange problems.
Afterword
In the original article, the author recommended a library called MobX to manage some states. I am not very cold, so I will not introduce it. If you are interested, you can read the introduction in the original article through the link at the top.
Based on the three points raised above, I think newbies should pay attention to the following:
setState is not guaranteed to be synchronized
setState is not guaranteed to be synchronized, it is not guaranteed Synchronization is not guaranteed. Say important things three times. The reason why it is not said to be asynchronous is because setState is also updated synchronously in some cases. You can refer to this article
If you need to obtain the modified value directly after setState, there are several options:
Pass in the corresponding parameters and do not obtain them through this.state
针对于之前的例子,完全可以在调用 fireOnSelect 的时候,传入需要的值。而不是在方法中在通过 this.state 来获取
使用回调函数
setState 方法接收一个 function 作为回调函数。这个回掉函数会在 setState 完成以后直接调用,这样就可以获取最新的 state 。对于之前的例子,就可以这样:
this.setState({ selection: value }, this.fireOnSelect)
使用setTimeout
在 setState 使用 setTimeout 来让 setState 先完成以后再执行里面内容。这样子:
this.setState({ selection: value }); setTimeout(this.fireOnSelect, 0);
直接输出,回调函数, setTimeout 对比
componentDidMount(){ this.setState({val: this.state.val + 1}, ()=>{ console.log("In callback " + this.state.val); }); console.log("Direct call " + this.state.val); setTimeout(()=>{ console.log("begin of setTimeout" + this.state.val); this.setState({val: this.state.val + 1}, ()=>{ console.log("setTimeout setState callback " + this.state.val); }); setTimeout(()=>{ console.log("setTimeout of settimeout " + this.state.val); }, 0); console.log("end of setTimeout " + this.state.val); }, 0); }
如果val默认为0, 输入的结果是:
Direct call 0
In callback 1
begin of setTimeout 1
setTimeout setState callback 2
end of setTimeout 2
setTimeout of settimeout 2
和渲染无关的状态尽量不要放在 state 中来管理
通常 state 中只来管理和渲染有关的状态 ,从而保证 setState 改变的状态都是和渲染有关的状态。这样子就可以避免不必要的重复渲染。其他和渲染无关的状态,可以直接以属性的形式保存在组件中,在需要的时候调用和改变,不会造成渲染。
避免不必要的修改,当 state 的值没有发生改变的时候,尽量不要使用 setState 。虽然 shouldComponentUpdate 和 PureComponent 可以避免不必要的重复渲染,但是还是增加了一层 shallowEqual 的调用,造成多余的浪费。
上面是我整理给大家的,希望今后会对大家有帮助。
相关文章:
The above is the detailed content of What should you pay attention to when using React.setState?. For more information, please follow other related articles on the PHP Chinese website!

JavaScript originated in 1995 and was created by Brandon Ike, and realized the language into C. 1.C language provides high performance and system-level programming capabilities for JavaScript. 2. JavaScript's memory management and performance optimization rely on C language. 3. The cross-platform feature of C language helps JavaScript run efficiently on different operating systems.

JavaScript runs in browsers and Node.js environments and relies on the JavaScript engine to parse and execute code. 1) Generate abstract syntax tree (AST) in the parsing stage; 2) convert AST into bytecode or machine code in the compilation stage; 3) execute the compiled code in the execution stage.

The future trends of Python and JavaScript include: 1. Python will consolidate its position in the fields of scientific computing and AI, 2. JavaScript will promote the development of web technology, 3. Cross-platform development will become a hot topic, and 4. Performance optimization will be the focus. Both will continue to expand application scenarios in their respective fields and make more breakthroughs in performance.

Both Python and JavaScript's choices in development environments are important. 1) Python's development environment includes PyCharm, JupyterNotebook and Anaconda, which are suitable for data science and rapid prototyping. 2) The development environment of JavaScript includes Node.js, VSCode and Webpack, which are suitable for front-end and back-end development. Choosing the right tools according to project needs can improve development efficiency and project success rate.

Yes, the engine core of JavaScript is written in C. 1) The C language provides efficient performance and underlying control, which is suitable for the development of JavaScript engine. 2) Taking the V8 engine as an example, its core is written in C, combining the efficiency and object-oriented characteristics of C. 3) The working principle of the JavaScript engine includes parsing, compiling and execution, and the C language plays a key role in these processes.

JavaScript is at the heart of modern websites because it enhances the interactivity and dynamicity of web pages. 1) It allows to change content without refreshing the page, 2) manipulate web pages through DOMAPI, 3) support complex interactive effects such as animation and drag-and-drop, 4) optimize performance and best practices to improve user experience.

C and JavaScript achieve interoperability through WebAssembly. 1) C code is compiled into WebAssembly module and introduced into JavaScript environment to enhance computing power. 2) In game development, C handles physics engines and graphics rendering, and JavaScript is responsible for game logic and user interface.

JavaScript is widely used in websites, mobile applications, desktop applications and server-side programming. 1) In website development, JavaScript operates DOM together with HTML and CSS to achieve dynamic effects and supports frameworks such as jQuery and React. 2) Through ReactNative and Ionic, JavaScript is used to develop cross-platform mobile applications. 3) The Electron framework enables JavaScript to build desktop applications. 4) Node.js allows JavaScript to run on the server side and supports high concurrent requests.


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

SAP NetWeaver Server Adapter for Eclipse
Integrate Eclipse with SAP NetWeaver application server.

mPDF
mPDF is a PHP library that can generate PDF files from UTF-8 encoded HTML. The original author, Ian Back, wrote mPDF to output PDF files "on the fly" from his website and handle different languages. It is slower than original scripts like HTML2FPDF and produces larger files when using Unicode fonts, but supports CSS styles etc. and has a lot of enhancements. Supports almost all languages, including RTL (Arabic and Hebrew) and CJK (Chinese, Japanese and Korean). Supports nested block-level elements (such as P, DIV),

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Dreamweaver Mac version
Visual web development tools

EditPlus Chinese cracked version
Small size, syntax highlighting, does not support code prompt function
