react hooks introduction booklet

Strongly recommend this react hooks tutorial: https://github.com/puxiao/react-hook-tutorial

react hooks

What is react hooks?

(1). Hook is a new feature / syntax added to React 16.8.0
(2). You can use state and other React features in function components

Three commonly used hooks
(1). State Hook: React.useState()
(2). Effect Hook: React.useEffect()
(3). Ref Hook: React.useRef()

useState

(1). State Hook allows function components to have state and read and write state data
(2). Syntax: const [XXX, setXXX] = react useState(initValue);
(3). useState() Description:
Parameter: the specified value is cached internally during the first initialization
Return value: an array containing two elements. The first is the internal current status value, and the second is the function that updates the status value
(4). Setxxx() can be written in two ways:

  • setXxx(newValue): the parameter is a non function value, which directly specifies a new status value and internally overwrites the original status value. If it is called continuously for several times, only the last value will be updated (merge and update the status once).
  • SetXXX (value = > newvalue): the parameter is a function that receives the original status value and returns a new status value, which is used internally to overwrite the original status value. If multiple consecutive calls are made, the parameter value is the latest value, and the status will be updated multiple times.
function Demo() {
  // useState function parameter. The value specified in initialization will be cached internally
  // If you want to use multiple states, you need to write react multiple times useState()
  const [count, setCount] = React.useState(1);
  const [name, setName] = React.useState("Xiao Ming");

  function add() {
    // setCount(count + 1);
    // The second way to write setCount
    setCount(count => count + 1);
  }

  function changeName() {
    setName("Xiaoming");
  }

  return (
    <div>
      <h2>The sum is:{count}</h2>
      <h2>full name:{name}</h2>
      <button onClick={add}>+1</button>
      <button onClick={changeName}>Change name</button>
    </div>
  );
}

setXxx is in the form of "asynchronous direct assignment" and does not "asynchronous comparison and cumulative assignment" like setState() in class components.
"Asynchronous"? Asynchrony here means the same as asynchrony in setState in class components. It is deliberately done to optimize the performance of React rendering. That is, you cannot get the latest value immediately after setXxx.

"Direct assignment":
1. In Hook, simple type data, such as number and string, can be assigned directly through setXxx(newValue).
2. However, for complex type data, such as array and object types, if you want to modify the value of one attribute without affecting other attributes, you need to copy a copy first, modify an attribute, and then assign a value as a whole.

Set the new value through setXxx, but if the new value is exactly the same as the current value, will React re render be triggered? According to the official document of React, when setXxx is used for assignment, Hook will use object Is() to compare the current value with the new value. If the result is true, it will not be rendered, and if the result is false, it will be re rendered.

useEffect

(1) Effect Hook allows you to perform side-effect operations in function components (used to simulate life cycle hooks in class components).
(2) Side effect operation in React

  • Send ajax request for data acquisition
  • Set subscription / start timer
  • Manually change the real DOM

(3) Syntax and Description: the useEffect(effect,[deps]) function can pass in two parameters. The first parameter is the execution function defined by us, and the second parameter is the dependency (optional parameter). If multiple useeffects are defined in a function component, their actual execution order is in the order defined in the code.

useEffect(() => { 
  // Any operation with side effects can be performed here
  return () => { // Execute before component uninstallation
    // Do some finishing work here, such as clearing timer / unsubscribing, etc
  }
}, [stateValue]) // If [] is specified, the callback function will only be executed after the first render()

(4) useEffect Hook can be regarded as a combination of the following three functions

  • componentDidMount()
  • componentDidUpdate()
  • componentWillUnmount()

(5) There are two common side effects in the React component: those that need to be cleared and those that do not need to be cleared.

  • Sometimes we just want to * * run some extra code after React updates the dom** For example, sending network requests, manually changing DOM, and logging are common operations that do not need to be cleared. Because we can ignore them after performing these operations.
  • Some side effects need to be eliminated. For example, subscribe to external data sources. In this case, clearing is very important to prevent memory leakage!

If react Useeffect only passes in the first function parameter, which is equivalent to detecting all States. It will be executed once when the page is loaded for the first time, and it will also be executed whenever there is a status update, that is, it will be executed every time it is rendered. Equivalent to componentDidMount and componentDidUpdate.

function Example() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    document.title = `You clicked ${count} times`;
  });
}

Some side effects may need to be eliminated. This can return a function, which is equivalent to componentWillUnmount

useEffect(() => {
  function handleStatusChange(status) {
    setIsOnline(status.isOnline);
  }
	
  // subscribe
  ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
  return () => {
    // Unsubscribe
    ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
  };
});

Multiple effect hooks can be used, which allows us to separate them according to the purpose of the code, rather than like the life cycle function. React will call the functions in the component in the order of effect declaration_ Each_ effect.

function FriendStatusWithCounter(props) {
  const [count, setCount] = useState(0);
  useEffect(() => {
    document.title = `You clicked ${count} times`;
  });

  const [isOnline, setIsOnline] = useState(null);
  useEffect(() => {
    function handleStatusChange(status) {
      setIsOnline(status.isOnline);
    }

    ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
    return () => {
      ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
    };
  });
  // ...
}

If the second parameter passed in is an empty array, the first function parameter will be executed only once and no one will monitor it. Then the first function parameter is equivalent to componentDidMount

If the second parameter passed in is not an empty array and there is a corresponding element [count] in the array, only the change of the state will be detected, and the function will be re executed when the state changes.

useEffect(() => {
  document.title = `You clicked ${count} times`
}, [count]); // Update only when count changes

Summary: the second parameter of useEffect can be divided into the following situations.
1. By default, the useEffect will be triggered every time before the component is mounted, re rendered, or unloaded (return function);
2. If the value is passed, it must be an array. The content of the array is the variable defined by useState in the function component or the variable in props passed by the parent component. It will be executed once when the component is mounted, and then useEffect will be triggered only when the variables in the array change;
3. If the value is passed, but the empty array [] is passed, it means that the content in the useEffect will only be executed once after "after the mount is completed and before the component is about to be unloaded (return function)";

common problem

In the following case, the value of count will not change after changing from 0 to 1? Why?

function Demo() {
  const [count, setCount] = React.useState(1);

  // Using the life cycle hook is equivalent to the combination of componentDidMount and componentWillUnmount
  React.useEffect(() => {
    let timer = setInterval(() => {
      setCount(count + 1);
    }, 1000);
    return function () {
      clearInterval(timer);
    };
  }, []);
  
  // Uninstall components
  function unMount() {
    ReactDom.unmountComponentAtNode(document.getElementById("root"));
  }

  return (
    <div>
      <h2>{count}</h2>
      <button onClick={unMount}>Uninstall components</button>
    </div>
  );
}

The key point is that we pass in an empty array for useEffect and use setCount(count + 1);

If you pass in an empty dependency array [], it means that the hook will only run once when the component is mounted, not when it is re rendered. However, there will be problems. In the callback of setInterval, the value of count will not change. Because when the effect is executed, we will create a closure and save the value of count in the closure, and the initial value is 0. Every second, the callback executes setCount(0 + 1), so the count will never exceed 1.

This problem can be solved by changing to setcount (count = > count + 1). This update no longer depends on the external count variable.

Official website explanation: https://zh-hans.reactjs.org/docs/hooks-faq.html#what-can-i-do-if-my-effect-dependencies-change-too-often

useRef

(1). Ref Hook can store / find tags or any other data in the function component
(2). Syntax: const refcontainer = react useRef()
useRef can get the reference of "some objects owned after some components are mounted or re rendered", and ensure that the reference is fixed throughout the life cycle of the component, and can accurately find the object we are looking for.

Two usages of useRef Association object:
1. For JSX components (native tags), they are associated through the attribute ref={xxxRef}.
2. For the variables in useEffect, use xxref Current.

//First define an xxRef reference variable to "hook" some objects owned only after some components are mounted or re rendered
const xxRef = useRef(null);

//For JSX components, they are associated through the attribute ref={xxxRef}
<xxx ref={xxRef} />

//For the variables in useEffect, use xxref Associate with current
useEffect(() => {
   xxRef.current = xxxxxx;
},[]);

Supplementary notes:
1. useRef is specifically for function components. If it is a class component, use react createRef().
2,React.createRef() can also be used in function components.
Just react The reference created by createref cannot guarantee that the reference is fixed after each re rendering. If you just use react It is OK for createref to "hook" the real DOM object corresponding to the converted JSX component, but it is impossible to "hook" the variable created in useEffect. If you want to "hook" both, you can only use useRef.

Online case: https://codesandbox.io/s/useref-40sxf5

Use case 1

If we have a component that has only one input box, we want to automatically get the input focus when the component is attached to the web page.
Demand analysis: you need to use useRef to "hook" the input box. When it is mounted to the web page, you can assign the focus to the input box by operating the native html method.

import React,{useEffect,useRef} from 'react'

function Component() {
  //First, define an inputRef reference variable to "hook" the input box after mounting the web page
  const inputRef = useRef(null);

  useEffect(() => {
    //inputRef.current is the input box after it is mounted on the web page. It is a real DOM, so you can call the method focus() in html
    inputRef.current.focus();
  },[]);

  return <div>
      {/* Use the ref attribute to "hook" inputRef to this input box */}
      <input type='text' ref={inputRef} />
    </div>
}
export default Component

be careful:
1. When setting the ref attribute to a component, you only need to pass in inputRef. Never pass in inputRef current.
2. After "hooking" the rendered real DOM input box, you can and can only call the methods owned by the tag in the native html.

Use case 2

If we have a component, the functional requirements of the component are as follows:
1. There is a variable count in the component. When the component is mounted to the web page, count will automatically + 1 per second.
2. There is a button in the component. Click the button to stop count automatic + 1.

import React,{useState,useEffect,useRef} from 'react'

function Component() {
  const [count,setCount] =  useState(0);
  const timerRef = useRef(null);//First, define a timerRef reference variable to "hook" the timer created by setinterval in useEffect

  useEffect(() => {
    //Set timerref Current is "hooked" to the timer created by setinterval
    timerRef.current = setInterval(() => {
        setCount((prevData) => { return prevData +1});
    }, 1000);
    return () => {
        //Through timerref Current, clear the timer
        clearInterval(timerRef.current);
    }
  },[]);

  const clickHandler = () => {
    //Through timerref Current, clear the timer
    clearInterval(timerRef.current);
  };

  return (
    <div>
        {count}
        <button onClick={clickHandler} >stop</button>
    </div>
  )
}

export default Component

Considerations for using useRef to create timers in TS

timerRef.current = setInterval(() => {
    setCount((prevData) => { return prevData +1});
}, 1000);

If it is in TS syntax, the above code will report an error: the type "Timeout" cannot be assigned to the type "number".
The reason for this error message is:

  1. TypeScript runs in Nodejs environment, and the code compiled by TS runs in browser environment.
  2. Nodejs and window in the browser each implement their own setInterval
  3. Original code timerref Current = setInterval (...) will be considered by TS as the setInterval defined by Nodejs, and the return type of setInterval in Nodejs is Nodejs Timeout.
  4. Therefore, we need to modify the above code to: timerref current = window.setInterval (...), make it clear that we call window setInterval, not the setInterval of Nodejs.

useContext

What problem is useContext used to solve?

useContext is < xxxcontext An alternative to consumer > can greatly simplify the code for obtaining shared data values.

Supplementary notes:
1. Function components and class components, for < xxxcontext Provider>,<XxxContext. There is no difference in how consumer > is used.
2. You can continue to use < xxxcontext instead of useContext in function components Consumer >, no problem. However, after using useContext, it can make it easier to obtain the code related to shared data.

Use case

const value = useContext(MyContext);

Receive a context object (the return value of React.createContext) and return the current value of the context. The current context value is determined by < mycontext. Com, which is closest to the current component in the upper component The value of provider > is determined by prop.

When the upper layer of the component is the nearest < mycontext When the provider > is updated, the Hook will trigger re rendering and use the latest context value passed to MyContext provider.

useContext(MyContext) just allows you to_ Read_ The value of context and the change of subscription context. You still need to use < mycontext. Com in the upper component tree Provider > for the lower level components_ Provide_ context.

const themes = {
  light: {
    foreground: "#000000",
    background: "#eeeeee"
  },
  dark: {
    foreground: "#ffffff",
    background: "#222222"
  }
};

const ThemeContext = React.createContext(themes.light);

function App() {
  return (
    <ThemeContext.Provider value={themes.dark}>
      <Toolbar />
    </ThemeContext.Provider>
  );
}

function Toolbar(props) {
  return (
    <div>
      <ThemedButton />
    </div>
  );
}

function ThemedButton() {
  const theme = useContext(ThemeContext);
  return (
    <button style={{ background: theme.background, color: theme.foreground }}>
      I am styled by theme context!
    </button>
  );
}

In the example, the XxxContext is defined directly inside the component without using import, but there is no way to use the XxxContext in other components in this way. If the XxxContext is defined in an external separate module, each component can reference it.

In the following example, ContextCmp -- > middlecmp -- > ChildCmp. The ContextCmp component needs to transfer data to ChildCmp

// context.js
import React from "react";
export const PersonContext = React.createContext({ name: "a", age: 10 });

// ContextCmp.jsx
import { PersonContext } from "./context";
import MiddleCmp from "./MiddleCmp";

export default function ContextCmp() {
  return (
    <div>
      <h1>ContextCmp</h1>
      <PersonContext.Provider value={{ name: "b", age: 1 }}>
        <MiddleCmp />
      </PersonContext.Provider>
    </div>
  );
}

// MiddleCmp.jsx
import ChildCmp from "./ChildCmp";

export default function MiddleCmp() {
  return (
    <div>
      <h2>MiddleCmp</h2>
      <ChildCmp />
    </div>
  );
}

// ChildCmp.jsx
import { useContext } from "react";
import { PersonContext } from "./context";

export default function ChildCmp() {
  const data = useContext(PersonContext);
  return (
    <div>
      <h3>ChildCmp</h3>
      <div>
        {data.name}--{data.age}
      </div>
    </div>
  );
}

useContext only simplifies the code to obtain the shared data value, but for < xxxcontext The use of provider > has not changed

Why not use redux

Before the appearance of Hook, React was mainly responsible for the rendering of the view layer and not for the management of component data state. Therefore, there was a third-party Redux module to be specially responsible for the data management of React.

However, since there is a Hook, it has become feasible to use React Hook to develop function components and realize data state management. As long as useContext and useReducer are used according to the actual project requirements, common requirements can be met to a certain extent.

useReducer

The useReducer(reducer,initialValue) function usually passes in two parameters. The first parameter is a "data modification processing function caused by dispatch" defined by us, and the second parameter is the default value of user-defined data. The useReducer function will return the reference of the user-defined variable and the "dispatch" corresponding to the user-defined variable.

useReducer is an upgraded version of useState, which can realize complex logic modification instead of direct assignment modification like useState. Supplementary notes:
1. In the React source code, useState is actually implemented by useReducer, so useReducer is exactly the original version of useState.
2. No matter which Hook function is used, it is essentially driven by events to update the view layer.

Code form:

import React, { useReducer } from 'react'; //Introducing useReducer

//Define the "event handler" reducer
function reducer(state, action) {
  switch (action) {
    case 'xx':
        return xxxx;
    case 'xx':
        return xxxx;
    default:
        return xxxx;
  }
}

function Component(){
  //Declare a variable xxx and a dispatch corresponding to modifying xxx
  //Pass the event handler function reducer and the default value initialValue as parameters to useReducer
  const [xxx, dispatch] = useReducer(reducer, initialValue); 

  //If you want to get the value of xxx, you can use xxx directly
  
  //If you want to modify the value of xxx, you can modify it through dispatch
  dispatch('xx');
}

//Please note that the action in the above code is only the most basic string form. In fact, the action can be a multi-attribute object, so you can customize more attributes and parameter values
//For example, action can be {type:'xx',param:xxx}

Use case

import React, { useReducer, useState } from "react";

function reducer(state, action) {
  const { type, payload } = action;
  switch (type) {
    case "add":
      return state + payload;
    case "sub":
      return state - payload;
    case "mul":
      return state * payload;
    default:
      return state;
  }
}

export default function Count() {
  const [num, setNum] = useState(0);
  const [count, dispatch] = useReducer(reducer, 0);

  return (
    <div>
      <h3>{count}</h3>
      <input
        type="number"
        value={num}
        onChange={(e) => setNum(parseInt(e.target.value))}
      />
      <button
        onClick={() => {
          dispatch({ type: "add", payload: num });
        }}
      >
        +
      </button>
      <button
        onClick={() => {
          dispatch({ type: "sub", payload: num });
        }}
      >
        -
      </button>
      <button
        onClick={() => {
          dispatch({ type: "mul", payload: num });
        }}
      >
        *
      </button>
    </div>
  );
}

If you do not use useReducer, but use the previously learned useState, then each modification logic code of count must be written in the click event handler function of each button. After using useReducer, the logic of modifying count is centralized.

All variables in the example are defined and modified in the same component. In a real project, it must involve sharing and modifying a variable between different module components. What should I do** Use useReducer + useContext to share components at different levels globally and modify a variable (simulate the function of redux)** useReducer enables us to realize data modification of complex logic. Combined with useContext, it can achieve global data sharing and modification.

Use useContext and useReducer to operate and share data globally

Requirements:
1. Define a variable xx in the parent component;
2. Sub components at any level can easily obtain variable xx and "modify" variable xx;

Implementation principle

  • Using useContext to realize "get global data"
  • Implement "modify global data" with userReducer

Online case: https://codesandbox.io/s/usereducer-usecontext-ymdxeh

In the case, the sub components can obtain and modify the global variable count respectively; When any sub component modifies the count, it will be immediately reflected in other sub components to realize data sharing among sub components.

useCallback

Only when the parent component has multiple sub components at the same time, it is necessary to use useCallback for performance optimization to prevent re rendering caused by one sub component from causing other sub components to re render.

The usecallback (deps) function usually passes in two parameters. The first parameter is a "processing function" defined by us, usually an arrow function. The second parameter is the dependent variable existing in the processing function. Please note that all data variables in the processing function need to be put into deps. If the handler does not have any dependent variables, you can pass in an empty array []. ​

userCallback needs to be used with sub components that are optimized and use reference equality to avoid unnecessary rendering.

  • Subcomponents are class components: use shouldComponentUpdate or PureComponent to avoid unnecessary rendering
  • Subcomponents are function components: use react Memo() to avoid unnecessary rendering

Use case

View online: https://codesandbox.io/s/usecallback-wc11kd

If we have a custom component, the code is as follows:

import React from "react";

function Button({ children, onClick }) {
  console.log(`render...${children}`);
  return <button onClick={onClick}>{children}</button>;
}

{/* Use react Memo () wraps the component to be exported */}
export default React.memo(Button);

Parent component:
After using useCallback, clicking a button does not cause another button component to be re rendered

import React, { useState, useCallback } from "react";
import Button from "./Button";

export default function CallbackCmp() {
  const [count, setCount] = useState(0);
  const [age, setAge] = useState(19);

  const changeCount = useCallback(() => {
    setCount(count + 1);
  }, [count]);

  const changeAge = useCallback(() => {
    setAge(age + 1);
  }, [age]);

  return (
    <div>
      <h1>
        Number:{count},Age:{age}
      </h1>
      <Button onClick={changeCount}>button1</Button>
      <Button onClick={changeAge}>button2</Button>
    </div>
  );
}

useMemo

useMemo can mount the calculation results (return values) of some functions to the lower prototype chain of react and return the index of the return value of the function. When the component is re rendered, if the data variable that useMemo depends on has not changed, then directly use the calculation result of the function saved on the prototype chain to skip this meaningless re calculation, so as to improve the performance of the component.

The function calculation in "unnecessary function calculation" must have a certain complexity, such as a value that needs 1000 for loops to be calculated. If the calculation amount itself is very simple, such as 1 + 2, there is no need to use useMemo. It doesn't matter to recalculate each time.

useMemo is used to "hook" the return value of some processing functions in the component. When the component is re rendered, the return values of these functions need to be used again. At this time, the operation will not be performed again, but the previously calculated return values will be used directly.

useCallback is for the function and useMemo is for the return value of the function. useMemo does not require subcomponents and must use react memo.

The parameter fn in useCallback is mainly used to process the code of various operation transactions, such as modifying the value of a variable or loading data. fn in useMemo is mainly used to deal with the code of various computing transactions. useCallback and useMemo are both designed to improve component performance, but their applicable scenarios are different, not who is who's a substitute or who's a simplified version of who. ​

Mode of use

useMemo(create,deps) function usually passes in two parameters. The first parameter is a "function with complex calculation and return value" defined by us.

The second parameter is the dependent variable existing in the processing function. Only when the dependent variable of the processing function changes will the function return result be recalculated and saved once. Please note that all data variables in the processing function need to be put into deps. If the handler does not have any dependent variables, you can pass in an empty array []. If no dependency array is provided, useMemo calculates a new value each time it renders.

const xxxValue = useMemo(() => {
    let result = xxxxx;
    //After complex calculations
    return result;
}, [xx]);

1. Use useMemo() to wrap the calculation function and take the data variable used in the calculation function as the second parameter.
2. In the calculation function body, return the calculation result in the form of return.
3. xxxValue is the return value of this function and can be used directly.

Use case

If there are two number variables num, random and two button s inside a React component, click to modify the values of num and random respectively. At the same time, the component is also required to display the sum of all prime numbers in the num range.

random is added purely to trigger component re rendering, so that we can check whether useMemo is enabled.

Demand analysis:
1. Displays the sum of all prime numbers in the num range, which is the "complex calculation" in this component.
2. As long as the value of num remains unchanged and the total number of prime numbers is fixed, we should avoid calculating it every time we re render.
3. useMemo function is to help us solve this problem.

View online: https://codesandbox.io/s/usememo-cwoqd8

useImperativeHandle

useImperativeHandle allows the parent component to get some custom functions or variables in the child component. In essence, the child component adds its internal functions or variables to the objects defined by useRef in the parent component through useImperativeHandle.

The first two parameters of useImperativeHandle(ref,create,[deps]) function are required, and the third parameter is optional.

  • The first parameter is the reference variable defined by the parent component through useRef; ​
  • The second parameter is the object that the child component wants to attach to ref, and the attribute in the object is the function (method) that the child component wants to expose to the parent component; ​
  • The third parameter is optional and is the dependent variable of the function. All data variables used in the function need to be put into deps. If the processing function does not have any dependent variables, the third parameter can be ignored.

If you want to use useImperativeHandle, you need to combine useRef and react Use with forwardref
1. useRef create reference variable
2,React.forwardRef passes the reference variable to the child component
3. useImperativeHandle adds the function defined in the child component as an attribute to the ref object in the parent component.

Use case

View online: https://codesandbox.io/s/useimperativehandle-gt8s5e

For example, if the requirements of a sub component are:
1. There is a variable count. The default value is 0
2. There is a function addCount, which executes count+1 internally
3. There is a button. Click the button to execute the addCount function
The requirements of the parent component are:
1. The above child components are used within the parent component
2. There is a button in the parent component. Click to execute the function addCount defined in the above sub component

Sub component code:

import React, { useState, useImperativeHandle } from "react";

function Count(props, ref) {
  const [count, setCount] = useState(0);
  // The child component adds addCount function to ref.current in the parent component through useImperativeHandle function
  useImperativeHandle(ref, () => ({ add }));

  const add = () => {
    setCount(count + 1);
  };

  return (
    <div>
      <h1>{count}</h1>
      <button onClick={add}>count+1</button>
    </div>
  );
}

// Subcomponents need to be exported by react Forwardref package, otherwise the parameter ref cannot be received
export default React.forwardRef(Count);

If the function component wants to receive ref, it must cooperate with react Use forwardref, otherwise an error will be reported.

Parent component code:

import React, { useRef } from "react";
import Count from "./Count";

export default function ImperativeCmp() {
  const childRef = useRef();

  const addCount = () => {
    console.log(childRef);
    // The parent component calls the add function inside the child component
    childRef.current.add();
  };

  return (
    <div>
      {/* Add the child component to the child component through the parent ref attribute,
          The child component obtains the reference and adds the internal function to childRef */}
      <Count ref={childRef} />
      <button onClick={addCount}>Buttons in parent component</button>
    </div>
  );
}

useLayoutEffect

useLayoutEffect is used to "hook" to mount or re render the two components. The life cycle function useLayoutEffect uses the same method and parameters as useEffect. The difference between them is that you can equate useLayoutEffect with componentDidMount and componentDidUpdate because their call phases are the same. useEffect is triggered only after componentDidMount and componentDidUpdate are called.

That is, when all DOM of the component is rendered, useLayoutEffect is called synchronously, and then useEffect is called. useLayoutEffect is always triggered before useEffect.

In the official document of react, it is clearly stated that useLayoutEffect should be considered only when useEffect cannot meet your component requirements. The official recommendation gives priority to useEffect.

useDebugValue

useDebugValue

Custom hook

The 10 Hooks like useState, useEffect, useContext, useReducer, useCallback, useMemo, useRef, useimprovehandle, useLayoutEffect and useDebugValue are the default built-in hooks of react, and the so-called custom hooks are those written by ourselves.

The so-called custom hook is to extract the hook related code originally written in the function component and define it as a function. The extracted hook function is called "custom hook function", which is referred to as "custom hook" for short, so as to achieve the purpose of code reuse. react stipulates that all custom hook functions must be named in the form of useXxx.

Generally, the return value of custom hook has three forms:
1. Function without return value
2. Function with normal return value
3. Function with special structure return value (we combine multiple attribute settings required by the component into one object and return it for the component to use)

Online presentation: https://codesandbox.io/s/zi-ding-yi-hook-psnqox

The front-end learning and communication QQ group 862748629 has a good atmosphere for learning and discussion in the group, and the big guys gather. Click me to join

Keywords: Javascript Front-end React hooks

Added by youngp on Mon, 28 Feb 2022 06:17:30 +0200