Detailed analysis of useEffect
UseEffecf Basic use
Continuing the previous article, we explained the State Hook in the previous article, we can already define state in functional components through this hook
We know that there can be lifecycle functions in class components, so how do we define functions similar to lifecycle in function components?
Effect Hook allows you to complete some functions similar to the life cycle in class;
In fact, similar to network requests, manual update of DOM, and listening of some events are some side effects of React updating DOM (Side Effects);
So the Hook that completes these functions is called the Effect Hook;
If we have a requirement now: the title in the page always displays the counter number, and use the class component and the Hook to implement it respectively:
Class component implementation
import React, { PureComponent } from 'react' export class App extends PureComponent { constructor() { super() = { counter: 100 } } // When entering the page, the title displays counter componentDidMount() { = } // When the data changes, let the title change together componentDidUpdate() { = } render() { const { counter } = return ( <div> <h2>{counter}</h2> <button onClick={() => ({counter: counter+1})}>+1</button> </div> ) } } export default App
Implementation of function component plus Hook:
- Through the useEffect Hook, you can tell React to perform certain operations after rendering;
- useEffect requires us to pass in a callback function, which will call back this function after React has completed the update DOM operation (that is, after the component is rendered);
- By default, this callback function will be executed after the first rendering or after each update; generally, we write side effects operations in this callback function (such as network request, operation DOM, event listening)
- Therefore, it should be noted that there are many sayings that useEffect is used to simulate life cycles, but it is not actually; useEffect can simulate life cycles, but its main function is to perform side effects.
Therefore, it should be noted that there are many sayings that useEffect is used to simulate life cycles, but it is not actually; useEffect can simulate life cycles, but its main function is to perform side effects.
import React, { memo, useEffect, useState } from 'react' const App = memo(() => { const [counter, setCounter] = useState(200) // UseEffect passes in a callback function, which will be automatically executed after the page rendering is completed useEffect(() => { // Generally, in this callback function, writing side effects code (network request, operation DOM, event listening) = counter }) return ( <div> <h2>{counter}</h2> <button onClick={() => setCounter(counter+1)}>+1</button> </div> ) }) export default App
Clear side effects (Effect)
During the writing process of class components, we need to clear the code for some side effects in componentWillUnmount:
For example, we manually call subscribe in our previous event bus or Redux;
All need to have corresponding unsubscribe in componentWillUnmount;
How does Effect Hook simulate componentWillUnmount?
useEffect passed inCallback function A
There can be a return value itself, and this return value is anotherCallback function B
:
type EffectCallback = () => (void | (() => void | undefined));
Why return a function in effect?
This is the optional cleanup mechanism of effect. Each effect can return a clear function;
This way, it can be
Add and remove
The logic of subscriptions is put together;They are all part of the effect;
When does React clear effect?
React will perform a clear operation when components are updated and uninstalled, canceling the last listener, leaving only the current listener;
As I learned before, effect is executed every time it is rendered;
import React, { memo, useEffect } from 'react' const App = memo(() => { useEffect(() => { // The listening store data has changed const unsubscribe = (() => { }) // The return value is a callback function, which is executed when the component is re-rendered or uninstalled return () => { // Cancel the monitoring operation unsubscribe() } }) return ( <div> <h2>App</h2> </div> ) }) export default App
Using multiple useEffect
One of the purposes of using Hook is to solve the problem that the life cycle in the class often puts a lot of logic together:
For example, network requests, event listening, and manual DOM modification are often placed in componentDidMount;
Multiple Effect Hooks can be used in a function component, and we can separate the logic into different useEffects:
import React, { memo, useEffect } from 'react' const App = memo(() => { // listen for useEffect useEffect(() => { ("Code logic for listening") return () => { ("Canceled listening code logic") } }) // UseEffect for sending network requests useEffect(() => { ("Code logic for network requests") }) // UseEffect of DOM useEffect(() => { ("Code logic for operating DOM") }) return ( <div> App </div> ) }) export default App
Hook allows us to separate them according to the purpose of the code, rather than putting a lot of logic together like lifecycle functions:
React will be in the order of effect declarations
Called in turn
Every effect in the component;
useEffect performance optimization
By default, useEffect's callback function is re-execute every time it renders, but this causes two problems:
We just want to execute some code once (for example, network request, component execution once in the first rendering, and do not need to be executed multiple times), similar to what is done in componentDidMount and componentWillUnmount in class components;
In addition, multiple executions can also lead to certain performance problems;
How do we decide when and when should useEffect be executed?
useEffect actually has two parameters:
- Parameter 1: The executed callback function, we have used this parameter, and we won’t say more;
- Parameter 2: It is an array type, indicating which state the useEffect will be re-executed; (who will be re-executed)
Case exercises:
Effect affected by count;
import React, { memo, useEffect, useState } from 'react' const App = memo(() => { const [counter, setCounter] = useState(100) // The useEffect that sends a network request will be re-executeed only when the counter changes useEffect(() => { ("Code logic for network requests") }, [counter]) return ( <div> <h2 onClick={() => setCounter(counter+1)}>{counter}</h2> </div> ) }) export default App
However, if a function weWhen you don't want to rely on anything
, you can also pass an empty array []:
Then the two callback functions here correspond to componentDidMount and componentWillUnmount life cycle functions respectively;
import React, { memo, useEffect, useState } from 'react' const App = memo(() => { const [counter, setCounter] = useState(100) // Passing in an empty array means that it is not depended on any data useEffect(() => { // The parameter passed in at this time is the callback function: equivalent to componentDidMount ("Code logic for listening") // Parameter 1 The return value of this callback function: equivalent to componentWillUnmount return () => { ("Canceled listening code logic") } }, []) return ( <div> <h2 onClick={() => setCounter(counter+1)}>{counter}</h2> </div> ) }) export default App
Summary: useEffect can simulate the life cycle of previous class components (similar rather than equality), and it is more powerful than the original life cycle, better than the blue one
This is the article about the details of the use of React Hook useEffecfa function. For more related React Hook useEffecfa function, please search for my previous article or continue browsing the related articles below. I hope everyone will support me in the future!