1, State Hook
1,useState
State Hook is a function used in function components (useState), which is used to use state in function components
useState
- The function has a parameter whose value represents the default value of the state
- The return value of the function is an array, which must contain two items
- Item 1: value of current status
- Item 2: function of changing state
There can be multiple states in a function component, which is very conducive to the horizontal segmentation of concerns.
Write an adder and subtractor in the class component:
class App extends React.Component { constructor(props) { super(props); this.state = { n: 0 } } render() { return <div> <button onClick={() => { this.setState({ n: this.state.n - 1 }) }}>-</button> <span>{this.state.n}</span> <button onClick={() => { this.setState({ n: this.state.n + 1 }) }}>+</button> </div> } }
Write an adder and subtractor in the function component:
import React, { useState } from 'react' export default function App() { // const arr = useState(0); // Use a state whose default value is 0 // const n = arr[0]; // Get the value of the status // const setN = arr[1]; // Get a function that changes the state const [n, setN] = useState(0); //Use a state whose default value is 0 return <div> <button onClick={() => { setN(n - 1) }}>-</button> <span>{n}</span> <button onClick={() => { setN(n + 1) }}>+</button> </div> }
After using state in function components, it is obviously more concise and clear than class components, and multiple uses will not affect each other.
2. useState principle
- The nth call to useState
- Check the status array of the node and whether there is a corresponding subscript N
- non-existent:
- Create a state using default values
- Add the status to the status array with the subscript N
- Presence:
- Ignore defaults
- Get the status value directly and use
So although we use a component many times, each function component will use its own state array.
3. Pay attention to details
- useState is best written to the starting position of the function for easy reading
- useState is strictly prohibited from appearing in code blocks (judgment and loop) (it is easy to cause subscript confusion, and the obtained state does not correspond)
- The function returned by useState (the second item of the array), and the reference remains unchanged (saving memory space)
- If the data is completely equal to the previous data (compared with Object.is), it will not lead to re rendering, so as to achieve the purpose of optimizing efficiency.
- If you change the data with a function, the incoming value will not be merged with the original data, but will be replaced directly.
- If you want to implement forced refresh component
- Class component: use forceUpdate function
- Function component: useState using an empty object
import React, { useState } from 'react' // import React, { Component } from 'react' // export default class App extends Component { // render() { // return ( // <div> // <button onClick={()=>{ // //shouldComponentUpdate will not be run // this.forceUpdate();// Force re rendering // }}>Force refresh < / button > // </div> // ) // } // } export default function App() { console.log("App Render"); const [, forceUpdate] = useState({}); return <div> <p > <button onClick={() => { forceUpdate({}); }}>force refresh </button> </p> </div> }
- If there is no necessary connection between some states, they should be divided into different states instead of merging into one object
- Like the state of class components, the change of state in function components may be asynchronous (in DOM events). Multiple state changes will be combined to improve efficiency. At this time, the previous state cannot be trusted, but the state should be changed by callback function. If the state changes to use the previous state, try to transfer the function.
import React, { useState } from 'react' export default function App() { console.log("App render") const [n, setN] = useState(0); //Use a state whose default value is 0 return <div> <button onClick={() => { // setN(n - 1); // setN(n - 1); setN(prevN => prevN - 1); //The passed in functions run uniformly after the event is completed setN(prevN => prevN - 1); }}>-</button> <span>{n}</span> <button onClick={() => { // setN(n + 1) / / it will not be changed immediately. It will be changed together after the event is run // setN(n + 1) / / at this time, the value of n is still 0 setN(prevN => prevN + 1); //The passed in functions run uniformly after the event is completed setN(prevN => prevN + 1); }}>+</button> </div> }