introduce
For function components
const App = props => { const [n, setN] = useState(0) //... }
After setN execution:
- n will not be changed by setN (important!)
- UI update will be triggered. App() executes again. When useState(0) is executed again, the value of n is different
analysis:
- setN stores the new value of n into an intermediate variable state
- useState reads the latest value of n from state
Simulate the implementation of React.useState
v 1.0
Use a global variable_ state saves the value of n
let _state const useState2 = (initialValue)=>{ _state = _state === undefined? initialValue: _state //Judge_ Does state exist const setState = (newValue)=>{ _state = newValue render() } return [_state, setState] } const render = ()=>{ //Simulation to achieve re rendering, the source code is not so ReactDOM.render(<App />, rootElement) }
In this way, n can get the latest value every time useState2(0) is called.
Question: only one data can be set. What if there are multiple data?
v 2.0
Improvement idea: put_ state is made into an array to save data in order
let _state = [] let index = 0 const useState2 = (initialValue)=>{ const currentIndex = index const setState = (newValue)=>{ _state[currentIndex] = newValue render() } index++ return [_state[currentIndex], setState] } const render = ()=>{ index=0 //Reset index before each rendering ReactDOM.render(<App />, rootElement) }
[defects of array scheme]
Each time App() is run, the order of setting data must be exactly the same, so React stipulates that useState cannot be used in if statements
[current issues]
App component used_ state and index, what about other components?
[solution]
Will_ state and index are placed on the virtual DOM corresponding to the component (omitted)
summary
-
Each function component corresponds to a React node with state and index on it
-
useState reads state[index] in the order it is called
-
setState modifies the state and triggers an update
Question: each re rendering will generate a new n. how can we make each rendering the same N
How to use the same n every time
(important!) in React, this is not recommended. You can use Vue 3 instead
But React can also do this through some methods, such as useRef or useContext (in doubt)
useRef
useRef is often used to reference elements, but it can also be used in this scenario to declare a data nRef:
const nRef = useRef(0) //It is an object: {current: 0}
useRef makes the nRef the same object and points to a fixed address every time it is re rendered.
However, the problem is that modifying nRef will not trigger re rendering. You can introduce another setState function to force the update
const update = useState(null)[1] //Call update, pass in a new value, and the update will be triggered
[complete example]
const App = props => { const nRef = React.useRef(0) const update = React.useState(null)[1] return ( <div> {nRef.current} <button onClick={()=>{ nRef.current++ update(nRef.current) }}>+1</button> </div> ) }
useContext
The feature of context is that it can transfer data to descendant components across levels.
First create a context
const myContext = React.createContext(null)
Then, this context can be used in any subcomponent surrounded by < mycontext. Provider > < / mycontext. Provider >
const App = props => { return ( <myContext.Provider value={/* incoming data */}> <Child /> </myContext.Provider> ) } const Child = props => { const a = React.useContext(myContext) //a is the above data passed in by value return ( <div>hi</div> ) }
Author: light tea
Link: https://juejin.cn/post/6890086834610077704
Source: rare earth Nuggets
The copyright belongs to the author. For commercial reprint, please contact the author for authorization, and for non-commercial reprint, please indicate the source.