UseEffect, useMemo, useCallback

background

The parent component passes a value to the child component. If other values of the parent component change, the child component will also render multiple times, resulting in a performance waste.

Introduction to the

UseMemo caches the value passed from the parent component to the child component. The child component is rerendered only when the state of the second parameter in the useMemo changes, and runs only once if the array is empty.

UseCallback caches the method passed from the parent component to the child component. The child component is rerendered only when the state of the second parameter in useCallback changes, and only once if the array is empty.

useMemo

const plusResult = useMemo(() => c + 1 , [c])

ShouldComponentUpdate is a means of performance optimization, similar to shouldComponentUpdate in class components, to determine whether or not to re-render a component. It only runs the callback function when a dependency changes. This optimization helps avoid costly calculations every time you render.

useCallback

const memorizedCallback = useCallback( () => { doSomething(a, b); }, [a, b], );

Passing the inline callback function and an array of dependencies as arguments to useCallback returns a Memorized version of the callback function, which is updated only when a dependency changes.

UseMemo is different from useCallback

Unlike the function instance provided by the useCallback cache, useMemo calls the provided function and caches its results.

UseCallback (fn, deps) is equivalent to useMemo(() => FN, deps).

useEffect

useEffect(() => { // dosomething }, [...] / * optional * /);

The function assigned to useEffect is executed after the component is rendered to the screen. Similar to Vue’s $nextTick(), you can do things like fetch data, set up subscriptions, and manually change the DOM in the React component.

Unlike useMemo/useCallback, the value in the second argument to useEffect must be the value that appears in the callback of the first argument, not the value outside.

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. This cleanup function is called when the component is unloaded
    subscription.unsubscribe();
  };
});
Copy the code

UseState and useReducer applications

useState

const [state, setState] = useState(initialState);

Returns a state and a function to update the state.

During initial rendering, the state returned is the same as the value of 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. There are two usages:

setState(newState);
setState(state= > state + 1);  // This can set a new value based on the previous state
Copy the code

useReducer

const [state, dispatch] = useReducer(reducer, initialArg, init);

Can be seen as an alternative to useState. It receives a Reducer of the form (state, action) => newState and returns the current state and its accompanying dispatch method.

UseReducer can be more useful than useState in some scenarios, such as when the state logic is complex and contains multiple subvalues. In addition, similar to Vuex, Reducer can encapsulate a series of actions (policy mode) to change the state, which is more flexible than useState.

Here is an example of a counter that overwrites the useState section with reducer:

const initialState = {count: 0};

function reducer(state, action) {
  // Remind not to change state.count directly, but to return a new state object
  switch (action.type) {
    case 'increment':
      return {count: state.count + 1};
    case 'decrement':
      return {count: state.count - 1};
    default:
      throw new Error();
  }
}

function Counter() {
  const [state, dispatch] = useReducer(reducer, initialState);
  return (
    <div>
      Count: {state.count}
      <button onClick={() = > dispatch({type: 'decrement'})}>-</button>
      <button onClick={()= > dispatch({type: 'increment'})}>+</button>
    <div/>
  );
}
Copy the code

The Context. The Provider and the Context. Consumer

background

In the React application, data is passed from parent to parent (props). However, for some properties required by many components in the application (such as the current authenticated user, topic, or preferred language), it is cumbersome to pass the data layer by layer. Context provides a way to share such values between components without explicitly passing props layer by layer through the component tree. (Sort of like Vue Inject/Provider)

Introduction to the

Context provides a way to pass data across the component tree without manually adding props for each layer of components.

Context.Provider

Official use Demo:

// Context allows us to pass values deep into the component tree without explicitly traversing each component.
const ThemeContext = React.createContext();

class App extends React.Component {
  render() {
    // Use a Provider to pass the current context to the following component tree.
    // No matter how deep, any component can read this value.
    return (
      <ThemeContext.Provider value="dark">
        <Toolbar />
      </ThemeContext.Provider>); }}// Intermediate components no longer have to specify the theme to pass down.
function Toolbar() {
  return (
    <div>
      <ThemedButton />
    </div>
  );
}

class ThemedButton extends React.Component {
  // Specify contextType to read the current theme context.
  // React will find the nearest theme Provider and use its value.
  // In this case, the current theme value is "dark".
  static contextType = ThemeContext;
  render() {
    return <Button theme={this.context} />; }}// Or mount the contextType property of a Context on the class. This is already mounted at 'static' in the class
// ThemedButton.contextType = ThemeContext;
Copy the code

Description: When a Provider’s value changes, all its internal consumer components are rerendered. Both the Provider and its internal consumer component are not subject to the shouldComponentUpdate function, so the consumer component can update if its ancestor exits updating.

Context.Consumer

Use to subscribe to the context in a functional component

<MyContext.Consumer>
  {value= > /* Render based on context value */}
</MyContext.Consumer>
Copy the code

This article only introduces the most simple, immediately CV to use the basic usage and introduction, more scenarios usage, notes please read the official API documentation or Google.

The 7 hooks introduced in this article are all in this Demo code example. After reading the above introduction, you can go to the Demo code to see the use example.

Appendix:

React Chinese API documentation

React online authoring platform