Basic usage
1
const [count, setCount] = useState(initialState)
count
is to read state,setCount
is to update state, andinitialState
is initial value.
State is an array
Because React rendering only checks a shallow copy of state, React will not re-render if you only change the value in the array, rather than changing the address of the array. The solution is to copy the original array and reassign it to the state after changing it.
State is an object
Because React rendering only checks a shallow copy of state, React will not re-render if you only change the value in the object, rather than changing the object address. The solution is to copy the original object and reassign it to the state after the change.
Arrow function update
Official website. If the new state was computed using the previous state, a function can be passed to
setState
. The function will receive the previous value, and return an updated value. Here is an examplesetState
that uses two forms of the counter component:The “+” and “-“ buttons use the functional form because the updated value is based on the previous value. But the “reset” button uses the normal form because it always sets the count back to the initial value.
If your update function returns the exact same value as the current state, subsequent re-renders will be skipped entirely.
1
2
3
4
5
6
7
8
9
10
11function Counter({initialCount}) {
const [count, setCount] = useState(initialCount);
return (
<>
Count: {count}
<button onClick={() => setCount(initialCount)}>Reset</button>
<button onClick={() => setCount(prevCount => prevCount - 1)}>-</button>
<button onClick={() => setCount(prevCount => prevCount + 1)}>+</button>
</>
);
}Arrow functions update state in a way that makes React execute this line before going to the next line. In the normal
setState(value)
method, sometimes React will execute out of order due to performance optimization.
State self-change in useState()
Sometimes the state in
useState()
is used for self-increment and self-decrement, etc. At this time, it is impossible to write code likesetCount(count++);
, becauseconst [count, setCount] = useState(0);
when initially defined, count is a constant. Any direct modification of the state will report an error. But you can usesetCount(count+1);
instead.Another way is to write an arrow function in
setCount()
, and then evaluate the formal parameters. The value of the formal parameter is count, which is the first parameter ofuseState()
.1
2
3const increment = () => {
setCount((prev) => prev + 1);
}
The value of useState in the callback function will not change
In the code below, the number on the page is always 1 greater than the console’s number. This is because the count value passed into the callback function will not change in the callback function. When
setCount()
is passed for the second time, its parameter count is still obtained from the outside, not the previous line in the callback function, so only 1 is added each time.1
2
3
4
5
6
7
8
9
10
11
12
13
14const Footer = () => {
const [count, setCount] = useState(0);
const handleCount = () => {
setCount(count+1);
setCount(count+1); //Second time.
console.log(count);
}
return(
<footer>
<p>count: {count}</p>
<button onClick={handleCount}>click me</button>
</footer>
)
}
useState()
noteReact will run all the code on the component when it re-renders. Therefore, if
setState()
is not triggered by an event, it will cause re-rendering all the time, causing errors. This is because the state drives the data. Every time the state is set, it will re-render, and then call setState() to set the state again during rendering, infinite loop. If you only want to render once, useuseEffect()
.
When using TS, such as
useState<String>("")
, when must the type be defined? If the initial value of the parameter isnull
, the type needs to be declared. Such asuseState<String | null>("");
double type. The types that can be inferred in ts do not need to be written.