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
can call inputref.current.focus ().