React's Hook allows function components to have the characteristics of class components

Keywords: node.js Front-end npm React

1, What problems have been solved?

Hook is a special function starting with use (useState, useEffect, etc.), which can only be used inside the function component. It allows you to use state and other React features without writing class. For example, useState is equivalent to the state object in the class component.

1. Update instructions for Library

Hook is a new feature of React 16.8. The stable implementation of React Hook is included in the following modules:

React DOM
React Native
React DOM Server
React Test Renderer
React Shallow Renderer

React Native 0.59 And above version support Hook. 

Note that to enable Hook,All React dependent package Must be upgraded to 16.8.0 Or later. If you forget to update React DOM Something like that package,Hook Will not run.
2, Hook rules and plug-ins
1. Rules
  • Hook can only be used in function components of React and custom hook.
  • Hook can only be called on the outermost level of the function, and it is not allowed in the loop, conditional judgement or subfunction.
2. Plug in

Eslint plugin react hooks is a plug-in used to check whether the Hook code complies with the rules.

npm install eslint-plugin-react-hooks
3. Plug in link:

We recommend enabling eslint-plugin-react-hooks Medium exhaustive-deps Rules. This rule warns when adding a wrong dependency and suggests a fix.

3, State Hook

State Hook refers to the special function useState, which allows you to use the state feature without writing a class. In other words, let the function component have the state feature. Detailed usage, Look here!

4, Effect Hook

Effect Hook refers to the special function useEffect, which allows function components to perform custom operations after component rendering. Detailed usage, Look here!

5, Customize Hook

Custom Hook is a custom function starting with use, which can call Hook internally.

1. Customize Hook
import { useState, useEffect } from 'react';

function useFriendStatus(friendID) {
    const [isOnline, setIsOnline] = useState(null);

    useEffect(() => {
        function handleStatusChange(status) {
            setIsOnline(status.isOnline);
        }

        ChatAPI.subscribeToFriendStatus(friendID, handleStatusChange);
        return () => {
            ChatAPI.unsubscribeFromFriendStatus(friendID, handleStatusChange);
        };
    });

    return isOnline;
}
2. Use custom Hook
const friendList = [
    { id: 1, name: 'Phoebe' },
    { id: 2, name: 'Rachel' },
    { id: 3, name: 'Ross' },
];

function ChatRecipientPicker() {
    const [recipientID, setRecipientID] = useState(1);
    const isRecipientOnline = useFriendStatus(recipientID);

    return (
        <>
            <Circle color={isRecipientOnline ? 'green' : 'red'} />
            <select
                value={recipientID}
                onChange={e => setRecipientID(Number(e.target.value))}
            >
                {friendList.map(friend => (
                    <option key={friend.id} value={friend.id}>
                        {friend.name}
                    </option>
                ))}
            </select>
        </>
    );
}
6, Context Hook

Context Hook refers to the special function useContext, which solves the trouble of props transmitting data in special scenarios. Detailed usage, Look here!

7, useReducer

useReducer is an upgraded version of useState. It splits the setState operation. Different logical calculations can be performed according to different types, and finally changes the state object. Detailed usage, Look here!

8, Uselayouteeffect

The use of uselayouteeffect is the same as that of useEffect, except that the time point called is different. useEffect is called after the browser drawing is completed, and uselayouteeffect is called before the browser drawing.

9, useDebugValue

Display custom hook tags in the React developer tool.

function useFriendStatus(friendID) {
    const [isOnline, setIsOnline] = useState(null);

    // Display the tag next to the Hook in the developer tool
    // e.g. "FriendStatus: Online"
    useDebugValue(isOnline ? 'Online' : 'Offline');

    return isOnline;
}

// The second parameter can add debugging output information
useDebugValue(date, date => date.toDateString());
10, useCallback

Set a callback function that is called only when the value of the dependency changes. As follows, the arrow function is called only when the dependency array [a,b] changes. When optimizing performance, remove some unnecessary rendering components.

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

[note] useCallback(fn, deps) is equivalent to usememo (() = > FN, DEPs).

11, useMemo

Pass the arrow function and array [a,b] to useMemo as parameters. When the value of array [a,b] changes, the arrow function will be called during rendering. If there is no second parameter [a,b], the arrow function is called during each rendering.

Write code that can be executed without useMemo first -- then add useMemo to your code to optimize performance.

const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

[note] useCallback(fn, deps) is equivalent to usememo (() = > FN, DEPs).

React.memo is equivalent to PureComponent, but it only compares props. (you can also specify a user-defined comparison function through the second parameter to compare the old and new props. If the function returns true, the update will be skipped.)

React.memo does not compare States because there is no single state object to compare. But you can also make child nodes pure components.

12, useImperativeHandle
// Expose yourself to the parent component for the parent component's operation to access its own interior.
useImperativeHandle(ref, createHandle, [deps])

useImperativeHandle should be used with forwardRef:

// input exposes itself to the parent component, which can call its focus method.
function FancyInput(props, ref) {
    const inputRef = useRef();
    useImperativeHandle(ref, () => ({
        focus: () => {
            inputRef.current.focus();
        }
    }));
    return <input ref={inputRef} ... />;
}
FancyInput = forwardRef(FancyInput);
Render <FancyInput ref={inputRef} /> The parent component of can call inputRef.current.focus(). 
10, Related links:

Posted by Ryodox on Tue, 16 Nov 2021 17:24:23 -0800