React learning notes - useState analysis

Keywords: React

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.

Posted by crislewis on Tue, 23 Nov 2021 20:42:55 -0800