React uses useEffect and stepping on the pit

Introduction to useEffect

UseEffect is one of the most important and commonly used hooks in reactHook.

What life cycle is useEffect equivalent to in react?
This question has been introduced on the official website of React. It is easy to be ignored during the use process, but it is often asked during the interview. (Interviewing aircraft carrier, screwing screws at work?), it is not difficult to answer this question as a joke , The following is the official original words of
React : If you are familiar with the life cycle functions of React class, you can think of useEffect Hook as a combination of componentDidMount, componentDidUpdate and componentWillUnmount.

componentDidMount component mount
componentDidUpdate component update
componentWillUnmount component will be destroyed

useEffect needs to pass two parameters, the first parameter is a logical processing function, the second parameter is an array
usage

useEffect(() => {
    
    
/** 执行逻辑 */
},[])

Important appreciated that
a, the second parameter is variable, when the array storage variable is changed, the first parameter, the processing logic function will be performed
two, the second parameter may not pass, not given, but the wireless browsers Execute logic processing functions in a loop.

useEffect(() => {
    
    
/** 执行逻辑 */
})

3. If only an empty array is passed as the second parameter, the logic in the logic processing function will only be executed once when the component is mounted, which is not equivalent to componentDidMount

useEffect(() => {
    
    
/** 执行逻辑 */
},[])

Fourth, if the second parameter is not an empty array, as follows

const [a, setA] = useState(1);
const [b, setB] = useState(2);
useEffect(() => {
    
    
/** 执行逻辑 */
},[a,b])

The logic processing function will be executed once when the component is mounted and (once when the value of the a or b variable changes in the stack) is this equivalent to the combination of componentDidMount and componentDidUpdate
5. The first parameter of useEffect can return a callback function , This callback function will be executed before the component is destroyed. This is equivalent to componentWillUnmount

useEffect removes side effects. We might create some recurring subscriptions (timers, or recursive loops) when the component is about to be mounted. Before the component is destroyed, these subscriptions should also be destroyed.

For example, the following situation (without removing the timer, increasing unnecessary overhead and code risk)

const [time, setTime] = useState(0)

useEffect(() => {
    
    
	const InterVal = setInterval(() => {
    
    
		setTime(time + 1)
	},1000)
},[])

Use the fifth point to remove the timer before the component is destroyed.

const [time, setTime] = useState(0)

useEffect(() => {
    
    
	const InterVal = setInterval(() => {
    
    
		setTime(time + 1)
	},1000)
	return () => {
    
    
   		clearInterval(InterVal )
   	}
},[])

UseEffect common jump pit

1. The useEffect execution function is executed cyclically.

There may be two reasons for this situation.

  1. The second parameter is not passed
useEffect(() => {
    
    
/** 执行逻辑 */
})

the solution

useEffect(() => {
    
    
/** 执行逻辑 */
},[])
  1. You changed the variables monitored by useEffect in the useEffect execution function
const [a, setA] = useState(1);
useEffect(() => {
    
    
/** 执行逻辑 */
setA(a + 1)
},[a])

Solution: Don't change the value of the address of the second parameter dependent element in the execution function of the first parameter of useEffect. When the value of the address of the dependent element changes, the execution function will be executed again. Isn't this an infinite loop?

2. UseEffect cannot detect the changes of dependent array elements.

There is only one possibility, the value of the address of the dependent array element has not changed at all, such as:

const [a, setA] = useState({
    
    
b: 'dx',
c: '18',
})

const changeA = () => {
    
    
	setA((old) => {
    
    
	old.b = 'yx'
	return old
	})
}

useEffect(() => {
    
    
/** 当组件挂载时执行一次changeA */
changeA ()
},[])

/**当changeA执行却没有打印 a*/
useEffect(() => {
    
    
/** 执行逻辑 */
console.log(a)
},[a])

It is because changeA does not really change the value of a in the stack (the value of the address), but only changes the value of a in the heap.
UseEffect cannot detect the value change in the heap, and all reference type data should pay attention to this.
The solution

const [a, setA] = useState({
    
    
b: 'dx',
c: '18',
})

const changeA = () => {
    
    
	setA((old) => {
    
    
	const newA = {
    
    ...old}
	newA .b = 'yx'
	return newA 
	})
}

useEffect(() => {
    
    
/** 当组件挂载时执行一次changeA */
changeA ()
},[])

/**当changeA执行打印  {b:'yx',c:'18'}  */
useEffect(() => {
    
    
/** 执行逻辑 */
console.log(a)
},[a])

Guess you like

Origin blog.csdn.net/glorydx/article/details/114107703