This is the 24th day of my participation in the August Text Challenge.More challenges in August
Before, we learned the basic knowledge of hooks. Today, let’s learn some common hooks provided by the authorities.
Based on the hooks
useState
const [state,setState]=useState(initialState);
// We can see that useState returns a state and the function to update the state.
// The state returned during initial rendering is the same as the first parameter passed in.
// The setState function is used to update state. It receives a new state value and queues a re-rendering of the component
setState(newState);
// In subsequent rerenders, the first value returned by useState will always be the latest state after the update.
Copy the code
Pay attention to
React ensures that the setState function identifier is stable and does not change when the component is re-rendered. This is why it is safe to omit setState from useEffect or useCallback’s dependency list.
Functional update
If the new state needs to be computed using the previous state, you can pass the function to setState. This function takes the previous state and returns an updated value. The following counter component example shows two uses of setState:
function 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>
</>
);
}
Copy the code
The “+” and “-” buttons are functional because the updated state needs to be based on the previous state. The reset button, however, takes the usual form because it always sets count back to its initial value.
If your update function returns exactly the same value as the current state, subsequent rerenders will be skipped entirely.
Lazy initial state
The initialState parameter is only used in the initial rendering of the component and will be ignored in subsequent renderings. If the initial state needs to be computed through complex calculations, we can pass in a function that computes and returns the initial state, which is only called during the initial render:
const [state, setState] = useState(() = > {
const initialState = someExpensiveComputation(props);
return initialState;
});
Copy the code
Skip state update
When you call the update function of the State Hook and pass in the current State, React skips rendering and effect execution of the child components. Note that React may still need to render the component before it can be skipped. React doesn’t unnecessarily render “deep” nodes in the component tree, so don’t worry. If you are performing expensive calculations during rendering, you can use useMemo for optimization.
useeffect
useEffect(didUpdate);
Copy the code
The Hook receives a function that contains imperative code that may have side effects.
Changing the DOM, adding subscriptions, setting timers, logging, and performing other side effects within the body of a function component (in this case, during the React rendering phase) are not allowed, as this can cause unexplained bugs and break UI consistency.
Use useEffect for side effects. The function assigned to useEffect is executed after the component is rendered to the screen. You can think of Effect as an escape route from the purely functional world of React to the imperative world.
By default, effect will be executed at the end of each render round, but you can choose to have it executed only when certain values change.
Clear effect
Typically, components uninstall with the need to clear resources such as subscriptions or timer ids created by Effect. To do this, the useEffect function returns a cleanup function. Here is an example of creating a subscription:
useEffect(() = > {
const subscription = props.source.subscribe();
return () = > {
// Clear the subscription
subscription.unsubscribe();
};
},[props.source]);
Copy the code
useContext
const value = useContext(MyContext); // Receives a context object (the return value of 'React. CreateContext') and returns the current value of the context. Remember that the argument to 'useContext' must be the *context object itself *Copy the code
Additional hooks
useReducer
const [state, dispatch] = useReducer(reducer, initialArg, init);
Copy the code
useCallback
const memoizedCallback = useCallback(
() = > {
doSomething(a, b);
},
[a, b],
);
Copy the code
useMemo
const memoizedValue = useMemo(() = > computeExpensiveValue(a, b), [a, b]);
Copy the code
useRef
const refContainer = useRef(initialValue);
// 'useRef' returns a mutable ref object whose '.current 'property is initialized as the passed parameter (' initialValue'). The ref object returned remains constant throughout the life of the component.
Copy the code
useImperativeHandle
useImperativeHandle(ref, createHandle, [deps])
Copy the code
UseImperativeHandle allows you to customize the instance value exposed to the parent component when using a ref. In most cases, imperative code like ref should be avoided. UseImperativeHandle should be used with the forwardRef:
function FancyInput(props, ref) {
const inputRef = useRef();
useImperativeHandle(ref, () = > ({
focus: () = >{ inputRef.current.focus(); }}));return <input ref={inputRef} . />;
}
FancyInput = forwardRef(FancyInput);
Copy the code
In this case, the parent component rendering