Follow up on the react website’s core and Advanced summary above
Hook
Introduction to the
- Hook lets you use state and other React features without writing a class.
- When you use functions to declare components, you use hooks
- The characteristics of
- Totally optional. You can try hooks in some components. But you don’t have to learn or Hook now if you don’t want to.
- 100% backward compatible. Hooks do not contain any destructive changes.
- Now available. Hook was released in V16.8.0.
- There are no plans to remove classes from React.
- Hook doesn’t affect your understanding of React concepts.
- Hooks provide a more straightforward API for known React concepts: props, state, Context, refs, and lifecycle.
motivation
-
Reusing state logic between components is difficult
- React does not provide a way to “attach” reusable behavior to components.
- Use render props and higher-order components to solve this problem. But such scenarios require reorganizing your component structure, which can be cumbersome and make your code difficult to understand.
- Components composed of providers, consumers, advanced components, render props, and other abstraction layers form a nested hell
- Use hooks to extract state logic from components so that it can be individually tested and reused. Hooks allow you to reuse state logic without modifying the component structure.
- React does not provide a way to “attach” reusable behavior to components.
-
Complex components become difficult to understand
- Each life cycle often contains unrelated logic that is gradually overwhelmed by state logic and side effects. Code that is related and needs to be modified against each other is split, while completely unrelated code is grouped together in the same method.
- This is very buggy and leads to logical inconsistencies.
- Hooks break down the interrelated parts of a component into smaller functions (such as setting up subscriptions or requesting data) rather than enforcing partitioning by lifecycle. You can also use Reducer to manage the internal state of components and make them more predictable.
- Each life cycle often contains unrelated logic that is gradually overwhelmed by state logic and side effects. Code that is related and needs to be modified against each other is split, while completely unrelated code is grouped together in the same method.
-
Hard to understand class
- Hook allows you to use more React features in non-class situations.
-
Hooks and existing code work together, and you can use them incrementally.
An overview of
Detailed overview details follow
- A Hook is a function that lets you “Hook” features like React state and lifecycle into a function component.
- Hooks cannot be used in class components — this allows you to use React without using class.
- Hooks are already saved in function scope and are easily accessible
state
,props
Such as a variable. - Hook uses JavaScript’s closure mechanism rather than introducing a specific React API when JavaScript already provides a solution.
State Hook
- Call it in the function component to add some internal state to the component. React will retain this state for repeated rendering.
useState
Returns a pair of values:The currentState and a function that lets you update it, which you can call in an event handler or some other place.useState
The only argument is the initial state. The initial state parameter is only used for the first rendering.- State hooks can be used multiple times within a component
Effect Hook
-
React will wait for the browser to finish rendering the screen before delaying the useEffect call
-
UseEffect is an Effect Hook that gives function components the ability to manipulate side effects.
- Merges the class component
componentDidMount
,componentDidUpdate
和componentWillUnmount
- By using hooks, you can group related side effects within components rather than splitting them into different lifecycle functions.
- Merges the class component
-
Perform data fetch, subscribe, or manually modify the DOM in the React component. We collectively refer to these operations as “side effects,” or simply “effects.”
-
Because side functions are declared inside the component, they can access the props and state of the component.
-
By default, React calls side effects after every render — including the first one.
-
Side effects functions can also specify how to “clear” side effects by returning a function.
-
UseEffect can be used multiple times in components
Hook usage rules
Hooks are JavaScript functions, but there are two additional rules for using them:
- A Hook can only be called on the outermost layer of a function. Do not call in loops, conditional judgments, or subfunctions.
- You can only call a Hook in the React function component. Do not call it from another JavaScript function. (Custom Hook can also be called)
Customize the Hook
- Custom hooks allow you to reuse some of the state logic between components without adding them. To replace the two main alternatives: high-level components and Render props.
- We just call
useState
和useEffect
Can extract a custom Hook from the Hook logic. - You can call the same custom Hook multiple times within a single component.
- The Hook every timecallEach has a completely separate state
- Custom hooks are more of a convention than a feature. If the function name begins with”
use
“And calls other hooks, we say this is a custom Hook.- Easier to find problems in inspection tools, such as the Linter plug-in.
Other Hook
- UseContext lets you subscribe to the React Context without using component nesting.
- UseReducer allows you to manage complex local states of components using reducer.
usestate
-
UseState provides exactly the same functionality as this.state in class. Normally, variables “disappear” after the function exits, while variables in state are retained by React.
-
The only argument in the useState() method is the initial state.
- Parameters, unlike class, can be underlying data types, not necessarily objects.
-
UseState () returns the current state and the function that updates the state, both of which need to be retrieved in pairs.
-
const [count, setCount] = useState(0); Copy the code
- JavaScript syntax is called array deconstruction. It means that we create two variables at the same time, the first variable returns the first value, and the second variable returns the second value.
Effect Hook
- Effect Hook allows you to perform side effects in function components.
- Fetching data, setting up subscriptions, and manually changing the DOM in the React component are all side effects.
- Generated every time you re-renderA new effectI’m going to replace that.
- In a sense, an effect is more like a part of a render result — each effect “belongs” to a particular render.
- Passed to the
useEffect
The function is different in each render, so we canGet the latest data value in effext without worrying about why it is out of date
useEffect
Is executed after every render (after the first render and after every update).- Can put the
useEffect
The hooks ascomponentDidMount
.componentDidUpdate
和componentWillUnmount
The combination of these three functions.- Avoid writing repetitive code in multiple lifecycle functions.
- There are two common side effects operations in the React component: those that need to be cleaned and those that do not.
- Effects that don’t need to be cleaned: Run some extra code after React updates the DOM, and then ignore them.
- Such as sending network requests, manually changing DOM, and recording logs.
- Effect to clear: for exampleSubscribing to external data sourcesCleanup is very important to prevent memory leaks!
- Each effect can return a cleanup function. This puts the logic for adding and removing subscriptions together. They are all part of Effect.
- React performs cleanup operations when components are uninstalled. Effect is executed every time it is rendered. This is why React cleans up the previous effect before executing the current effect. Each time a new effect is re-rendered.
- Effects that don’t need to be cleaned: Run some extra code after React updates the DOM, and then ignore them.
The advanced
-
Separation of concerns is achieved using multiple effects
- Hooks allow us to separate code according to its purpose,Not like a life cycle function. React calls components in the order in which effects are declaredeachEffect.
- Solve the problem that class lifecycle functions often contain unrelated logic but split the related logic into several different methods.
-
Run Effect every time you update it
useEffect
By default, the previous effect is cleaned up before a new one is called. Avoid memory leaks in component functions that cause bug problems.
-
Optimize performance by skipping Effect
-
In some cases, performing cleanup or effect after every render can cause performance problems. If certain values don’t change between rerenderers, you can tell React to skip the call to Effect by passing an array as the second optional argument to useEffect.
-
useEffect(() => { document.title = `You clicked ${count} times`; }, [count]); // Update only when count changesCopy the code
-
-
The same applies to effects that have a clean operation
-
Make sure the array contains all variables in the outer scope that will change over time and be used in effect, otherwise your code will refer to old variables from previous renderings.
-
If you want to execute effect only once (only when the component is mounted and unmounted), you can pass an empty array [] as the second argument.
- There are better ways to avoid repeating calls to Effect too often.
-
Rules of the Hook
- Use hooks only at the top level
- Make sure the hooks are called in the same order every time you render, keeping the Hook state correct.
- React relies on the sequence of Hook calls to determine which state corresponds to which useState.
- Using hooks not at the top level can break the order (if for, etc.) and cause the state to be buggy.
- Never call hooks in loops, conditions, or nested functions. Be sure to always call them at the top of your React functions and before any returns.
- Make sure the hooks are called in the same order every time you render, keeping the Hook state correct.
- Only the React function calls the Hook
- Ensure that the component’s state logic is clearly visible in the code.
- Never call a Hook in a normal JavaScript function.
Hook API
Based on the hooks
useState
const [state, setState] = useState(initialState);
- During initial rendering, the returned state (
state
) and the first argument passed (initialState
) has the same value. setState
The function is used to update state. It receives a new state value and queues a re-rendering of the component.- Two usages: ordinary and functional
setCount(x)
Pass in the parameter value directly and set the state state.setCount(x => x++)
Call a function to change the state.
setState
The identity of the function is stable and does not change when the component is re-rendered.- If your update function returns exactly the same value as the current state, subsequent rerenders will be skipped entirely.
useState
Update objects are not merged automatically.- You can use the function
setState
Combine the expansion operator to merge updated objectsreturn {... prevState, ... updatedValues};
- You can use the function
- Lazy initial state: If the initial state needs to be computed by complex calculations, you can pass in a function that computes and returns the initial state, which is called only during the initial render.
- Skip state updates: 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.
- React uses the object. is comparison algorithm to compare states.
- React may still need to render the component before it can be skipped.
- This can be used if you are performing expensive computations during rendering
useMemo
To optimize.
useEffect
useEffect(didUpdate);
- The Hook receives a function that contains imperative code that may have side effects.
- use
useEffect
Complete the side effects operation and assign touseEffect
The function is executed after the component is rendered to the screen. - 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.
- To prevent memory leaks, the cleanup function is executed before the component is unloaded.
- If the component is rendered multiple times (as it usually is), the previous effect is cleared before the next effect is executed.
useEffect
The function andcomponentDidMount
,componentDidUpdate
Different in the browser complete layout with drawingafterThe execution.- React provides an extra one for this
useLayoutEffect
Hook to handle effects that cannot be delayed. It anduseEffect
The structure is the same, but the call timing is different.- Similar to the difference between passive listening events and active listening events.
- Can you give
useEffect
Pass the second argument, which is the array of values that Effect depends on. Only when the value array changes will the rendering be re-executed.- All values referenced in the effect function should appear in the dependency array, because the dependency array is not passed to the effect function as an argument.
- In the future, compilers will get smarter and it will be possible to create arrays automatically.
useContext
const value = useContext(MyContext);
- Receive a context object (
React.createContext
And returns the current value of the context. useContext
Must beContext object itself:- Correct:
useContext(MyContext)
- Error:
useContext(MyContext.Consumer)
- Error:
useContext(MyContext.Provider)
- Correct:
- The current context value is the closest from the upper component to the current component
<MyContext.Provider>
的value
Prop the decision. - Ancestors used
React.memo
或shouldComponentUpdate
Is also used in the component itselfuseContext
When re-rendering.
Additional hooks
Additional hooks are variations of the base hooks in the previous section, and some are only used in special cases.
useReducer
const [state, dispatch] = useReducer(reducer, initialArg, init);
useState
Is an alternative to. It receives a message of the form(state, action) => newState
Reducer, and return the current state and its matchingdispatch
Methods.- use
useReducer
You can also optimize performance for components that trigger deep updates becauseYou can pass to child componentsdispatch
Instead of a callback function 。 - Lazy initialization: will
init
Function as auseReducer
The third argument is passed in, so that the initial state will be set toinit(initialArg)
. - Skip Dispatch: If the return value of the Reducer Hook is the same as the current state, React skips the rendering of the child components and the execution of the side effects.
- React uses the object. is comparison algorithm to compare states.
- The React will ensure that
dispatch
The identity of the function is stable and does not change when the component is re-rendered.
useCallback
const memoizedCallback = useCallback( () => { doSomething(a, b); }, [a, b], ); Copy the code
- Returns a Memoized callback function.
useCallback(fn, deps)
The equivalent ofuseMemo(() => fn, deps)
.- The callback function is updated only when a dependency changes.
- Used when you pass callback data to optimized and use reference equality to avoid unnecessary rendering (e.g
shouldComponentUpdate
).
useMemo
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]); Copy the code
- Returns an memoized value.
- Pass in the create function and an array of dependencies as arguments
useMemo
, it recalculates the Memoized value only when a dependency changes. - This optimization helps avoid costly calculations every time you render.
- The incoming
useMemo
Is executed during rendering.- Do not do anything inside this function that is not related to rendering.
- Operations such as side effects belong to
useEffect
Is applicable to, rather thanuseMemo
.
- If the dependency array is not provided,
useMemo
The new value is computed on each render.
useRef
const refContainer = useRef(initialValue);
useRef
Returns a mutable ref object of.current
Property is initialized as the passed parameter (initialValue
).- The ref object returned remains constant throughout the life of the component.
useRef()
比ref
Properties are more useful. It can beIt’s easy to save any variable value, similar to the way instance fields are used in class.useRef()
You create a normal Javascript object. And build your own{current: ... }
The only difference between objects is,useRef
The same ref object is returned each time it is rendered.- When the ref object’s contents change,
useRef
并Don’tLet you know. change.current
Property does not cause the component to rerender. - If you want to run some code when React binds or unbinds the REF of the DOM node, you need to use the ref callback to do so.
useImperativeHandle
useImperativeHandle(ref, createHandle, [deps])
useImperativeHandle
You can use it againref
To customize the instance value exposed to the parent component.- In most cases, imperative code like ref should be avoided.
useImperativeHandle
Should be withforwardRef
Used together
useLayoutEffect
-
Its function signature is the same as useEffect, but it calls Effect synchronously after all DOM changes.
- You can use it to read DOM layouts and trigger rerenders synchronously.
-
The update schedule inside useLayoutEffect is refreshed synchronously before the browser performs the drawing.
-
Use standard Useeffects whenever possible to avoid blocking visual updates.
-
UseLayoutEffect and componentDidMount, componentDidUpdate call phase is the same.
- It is recommended that youI’ll start with it
useEffect
Try using it only when something goes wronguseLayoutEffect
.
- It is recommended that youI’ll start with it
-
Neither useLayoutEffect nor useEffect can be executed until the Javascript code is loaded.
- Is that why the server side rendering component was introduced
useLayoutEffect
Code generates a React alarm. - Solution 1: Need to move the code logic to
useEffect
In (if this logic is not needed for the first rendering), - Solution 2: Delay displaying the component until the client rendering is complete (if until
useLayoutEffect
Execute before HTML is displayed in case of disorder). - To exclude components that depend on layout Effect from HTML rendered on the server, use the
showChild && <Child />
Make a conditional render and useuseEffect(() => { setShowChild(true); }, [])
Delay the presentation of components. This way, the UI will not appear as cluttered as before until the client rendering is complete.
- Is that why the server side rendering component was introduced
useDebugValue
useDebugValue(value)
useDebugValue
Tags used to display custom hooks in the React developer tool.- Formatting the display of values can be an expensive operation. Unless special cases of Hook need to be checked
- Accepts a formatting function as an optional second argument.
- This function is called only when the Hook is checked. It takes a debug value as an argument and returns a formatted display value.
- It is not recommended to add debug values to every custom Hook. It is most valuable when it is part of a shared library.
Official Hooks FAQ
-
The official recommendation is to use Hooks as the main way to write the React component.
-
Hooks are friendly to static typing support.
-
The Hooks rule enforces two rules :(ESLint plugin)
- A call to a Hook is either in a
Big hump method
Inside a named function (as one component) or in anotheruseSomething
Function (as a custom Hook). - Hooks are called in the same order every time you render.
- A call to a Hook is either in a
-
The lifecycle method of a Class corresponds to a Hook
constructor
Function components do not require constructors. You can do this by callinguseState
To initialize state. If it’s expensive to compute, you can pass a function touseState
.getDerivedStateFromProps
Instead of:At the time of renderingSchedule an update.shouldComponentUpdate
: seebelowReact.memo
.render
This is the body of the function component itself.componentDidMount
.componentDidUpdate
.componentWillUnmount
:useEffect
HookAll of these can be expressed (includingless commonA combination of scenes).getSnapshotBeforeUpdate
.componentDidCatch
As well asgetDerivedStateFromError
There are currently no Hook equivalents for these methods, but they will be added soon.
-
Similar instance variables: useRef() Hook can be used for more than DOM refs. The “ref” object is a generic container with a mutable current attribute that can hold any value, similar to an instance attribute of a class.
-
When defining state variables, it is recommended to split state into multiple state variables, each containing different values that change at the same time.
-
Get props or state of the previous round manually by using ref.
-
If you see stale props and state in a function.
- You want to read from some asynchronous callbackThe latestState, you can useA refTo save it, modify it, and read from it.
- Dependency array optimization was used but not all dependencies were specified correctly.
-
Use the useReducer to force a rerender even if state does not change with an increased counter
-
The basic way to get the position or size of a DOM node is to use a callback ref. React calls the callback whenever a ref is attached to another node.
-
Conditional effects can be skipped during updates, and forgetting to process updates often leads to bugs, which is why we don’t use conditional effects by default.
-
Avoid declaring functions outside of effect. It is difficult to remember which functions and states are used by functions outside effect.
- If you do not have any value in the component scope, you can safely specify the condition parameter as
[]
- If you do not have any value in the component scope, you can safely specify the condition parameter as
-
On special requirements, a ref can be used to hold a mutable variable, similar to this in class.
-
Implement shouldComponentUpdate by covering a component with react. memo to shallow compare its props
-
Using the useMemo Hook allows you to cache calculations between multiple renders by “remembering” the last one.
-
Aren’t hooks slowed down by creating functions at render time? In modern browsers, the raw performance of closures and classes differs significantly only in extreme scenarios.
-
The Hook design is more efficient in some ways:
- Hooks avoid the extra overhead required by classes, such as the cost of creating class instances and binding event handlers in constructors.
- Language-compliant code does not require deep tree nesting of components when using hooks. This is common in code bases that use higher-order components, render props, and context. The smaller the component tree, the smaller the React workload.
-
ShouldComponentUpdate optimizes how the React inline function that passes a new callback each time it renders will break subcomponents. Hook solves this problem in three ways.
useCallback
Hooks allow you to keep the same callback references between rerenders so thatshouldComponentUpdate
Continue to work- UseMemo hooks make it easier to control when specific child nodes are updated, reducing the need for pure components.
- The useReducer Hook reduces the dependence on deep-pass callbacks, as explained below.
-
If a value is constantly changing, it is recommended to pass dispatches down in the context rather than using separate callbacks in the props.
-
A Hook is only called in the React component (or a custom Hook — again, only called in the React component).
-
The reason multiple useState() calls get their own independent local state.
- Inside each component is a list of “memory cells”. They’re just JavaScript objects that we use to store some data.
- When you use
useState()
When a Hook is called, it reads the current cell (or initializes it on first rendering) and moves the pointer to the next one.
After the speech
After the official document summary is completed, the official example “Tic-Tac-toe” is reconstructed using rax.js and new functional tasks are added