Hooks are functions that allow you to “hook” into React features in function components (hooks are a new feature in react16.8 that allows function components to use state and other react features)
No.1 useState
useState is used to create state variables
const [state,setState] = React.useState(0)
const [state,setState] = React.useState({name:'frank', age: '18})
// 0 or {name:'frank'} is the initial value of the state, setState function can change the value of the state
setState(2)
setState({...state, name: 'newName'})
// Since react update is to regenerate a new object, react will only generate the incoming object, so if you don't want another property to be lost you must use the original object to expand and put it on
No.2 useReducer
useReducer is a comprehensive version of useState
useReducer accepts two parameters, an operator and an initial value
const [state, dispatch] = React.useReducer(fn, obj)
// Call
dispatch({type:'name'}) // Parameters passed to fn's action
Function
const fn = (state, action) => {
// state is the original state; action is the parameter passed
return new state(obj) value
}
Initial Value
const obj={
name:'frank',
age:'18'
}
No.3 useContext
useContext context, the context is a local (context.provider wrapped) global variable
// Create Context
const Context = React.createContext(null)
// Scoping with context.provider
<Context.Provider value={{ n, setN }}>
app
<Father />
</Context.Provider>
// Use the value passed by the context
const Father = () => {
const { n, setN } = useContext(Context) // Use the value of the context
const onButton = () => {
setN(n + 1)
}
return (
<div>
father:{n}
<button onClick={onButton}>+1</button>
</div>
)
}
Note: The interface changes with the value of n in this place, not because of react’s responsiveness, but because each call to setN re-renders the app and finds that the interface only changes when the value of n changes
No.4 useEffect
useEffect use side effects, the name is not very well understood, the name of a flat alternative can be afterRender (rendering after the implementation)
// The following three will all be executed once on the first render
useEffect(() => {}) // Any element change is executed
useEffect(() => {},[n]) // n Change execution
useEffect(() => {},[]) // Mounted Execution
useEffect(() => {
return ()=>{} // Extinction Execution
},[])
Normally the useEffect is executed from top to bottom, but the useLayoutEffect is executed before it
useLayoutEffect
useLayoutEffect is executed after the Dom is created and before it is rendered. The principle is as follows.
No.5 memo, useMemo and useCallback
These three api’s are all here to prevent multiple rendering
As an example, the following code has no change in the value of m, but Child is still executed. How can we prevent this?
const App = () => {
const [n, setN] = useState(0)
const [m, setM] = useState('a')
return (
<div>
<div>grandfather</div>
<button onClick={() => { setN(i => i + 1) }}>+1</button>
<Father n={n} />
<Child m={m} />
</div>
)
}
const Father = (props) => {
console.log('father Performed')
return (
<div>father:{props.n}</div>
)
}
const Child = (props) => {
console.log('child Performed')
return (
<div>child:{props.m}</div>
)
}
Passing components to React.memo
const Child2 = React.memo(Child) // Use Child2 instead of Child
// or
const Child = memo(
() => {
return (
<div>child:{props.m}</div>
)
}
)
But there is a bug that this method does not work when the props are passed as functions. This is where useMemo comes into play
// If the following functions are passed
const fn=React.useMemo(() => {return ()=>{}},[m]) // The passed component will only be executed when n changes
It just doesn’t look weird to write that way. So react provides a syntactic sugar that allows you to pass a function React.useCallback(fn,value) directly
const fn1 = React.useCallback(() => {},[m])
No.6 useRef
useRef declares an unchanging value (by unchanging I mean that the memory address remains unchanged)
// Statement
const count = useRef(0)
// Use
count.current += 1
Because changing the value of useRef will not cause the app to render, it will cause the result to change without updating the UI. Solution.
const [n, setn] = useState(0)
// Call it up
setn()
Use the useState feature to re-render the app (manually)