join us!
Mountain" , provides technical-related information and a series of basic articles for front-end developers. For a better user experience, please move to our official website novices (16100dd532d319 https://xhs-rookies.com/ ) to learn and get the latest articles in time.
"Code tailor" , if you are interested in our article or want to make some suggestions, follow Mountain" public account, contact us, you can also watch it on WeChat Our article. Every suggestion or approval is a great encouragement to us!
Preface
In this article, our main purpose is to understand the use of shared state hook (useEffect)
useEffect
definition
Effect Hook
allows you to perform side-effect operations in function components. In other words, it can complete some functions similar to the life cycle in Class.
how to use
useEffect()
is as follows.
useEffect(() => {
dosomeing(); // 执行一些副作用操作
},[]);
useEffect requires parameters
- The first parameter: The
Hook
receives a function that contains imperative and may have side-effect code. - The second parameter: the
useEffect
will be re-executed when thestate
What did useEffect do?
Through useEffect
of Hook
, you can tell React
to perform certain operations after rendering; and useEffect
requires us to pass a function, React
performs the update DOM
operation. By default, no matter what After the component is rendered for the first time, or after the component is updated, this function will be executed. We can perform some work similar Class
component in the function to be passed, such as: changing the DOM, adding subscriptions, and setting Timer, record log, etc. should know that these side-effect operations in the function component are not allowed before useEffect Hook
prompt
If you are familiar with the life cycle function of
React class
useEffect
Hook as a combination of the three functionscomponentDidMount
,componentDidUpdate
andcomponentWillUnmount
Clear effect
In the Class
component, we need to clear some side-effect codes in componentWillUnmount
, such as our creation timer and clear timer. Similarly, when the function component is uninstalled, we also need to clear the resources such as subscription or timer ID created by effect
. To achieve this, the useEffect
function needs to return a clear function. The following is an example of creating a timer:
const [count, addCount] = useState(0)
const [timer, addTimer] = useState(1000)
useEffect(() => {
const interval = setInterval(() => {
// 创建计时器
addCount((val) => val + 1)
}, timer)
return () => {
// 返回清除函数
clearInterval(interval) // 清除计时器
}
})
To prevent memory leaks, the cleanup function will be executed before the component is unloaded. In addition, if the component repeatedly exaggerated (usually the case), then in the implementation of the next effect
before, on a effect
had been cleared . In the above example, it means that every update of the component will create a new timer. If you want to avoid triggering effect
every time you update, you need to use the second parameter of useEffect
Conditional execution of effect
By default, effect
will be executed after each round of component rendering is completed. In this case, once effect
changes, it will be recreated.
However, doing so may be overkill in some scenarios. For example, in the timer example above, we do not need to create a new timer every time the component is updated, but only need to source prop
it when 06100dd532d87f changes.
The second parameter accepted by useEffect
used here, which is an array of values on effect
The updated example is as follows:
const [count, addCount] = useState(0)
const [timer, addTimer] = useState(1000)
useEffect(() => {
const interval = setInterval(() => {
// 创建定时器
addCount((val) => val + 1)
}, timer)
return () => {
clearInterval(interval) // 清除定时器
}
}, [count])
When the second parameter is passed in, the count
changed. That is to say, useEffect
will decide whether to execute this update according to the second parameter we passed in.
note
- If you want to use this optimization, make sure that the array contains variable of all external and scope vary in effect in , or your code references to previously rendered the old variable.
- If you want to execute an effect that runs only once (only executed when the component is mounted and unmounted), you can pass an empty array (
[]
) as the second parameter.
Comparison component
I believe you already useEffect
something about 06100dd532da01, so let's use a simple example to feel the difference between Hook
and Class
There is a simple timer that 1000ms
at the time interval of 06100dd532da19 by default. After clicking the plus button, the time interval increases and the timer counts down.
Class component implementation
First, we need to declare a variable count
in the class component to count, a variable timer
to control the counting interval, every timer
time, count
plus one, and then add a button, each time you click, timer
increase 1000ms
. At the same time, the increase rate of count
class Example extends React.Component {
constructor(props) {
super(props)
this.state = {
count: 0,
timer: 1000,
}
}
componentDidMount() {
this.interval = setInterval(() => {
// 创建定时器
this.setState({
count: this.state.count + 1,
})
}, this.state.timer)
}
componentDidUpdate() {
clearInterval(this.interval) // 先清除上一个定时器
this.interval = setInterval(() => {
// 创建以 更新后的timer 计时间隔定时器
this.setState({
count: this.state.count + 1,
})
}, this.state.timer)
}
componentWillUnmount() {
clearInterval(this.interval) // 卸载时清除定时器
}
render() {
return (
<div>
<p>当前count值为:{this.state.count}</p>
<p>当前计数时间间隔为:{this.state.timer}ms</p>
<button onClick={() => this.setState({ timer: this.state.timer + 1000 })}>Click me</button>
</div>
)
}
}
We can find that in this class, we need to write duplicate code in two life cycle functions. It is also necessary to clear the timer when the component is uninstalled. A large amount of duplicate code is very cumbersome. So what is the use of Effect Hook
in the function component?
Use Effect Hook to achieve
import React, { useState, useEffect } from 'react'
function Example() {
const [count, addCount] = useState(0)
const [timer, addTimer] = useState(1000)
useEffect(() => {
const interval = setInterval(() => {
addCount((val) => val + 1)
}, timer)
return () => {
clearInterval(interval)
}
}, [count])
return (
<div>
<p>当前count的值为:{count}</p>
<p>当前计数时间间隔为: {timer}ms</p>
<button onClick={() => addTimer((val) => val + 1000)}>Click me</button>
</div>
)
}
After reading this example, are you surprised to find that Class
component is constructor
functions written in the three life cycles are solved useEffect
Does it look very streamlined. I believe you have the following questions:
What did
useEffect
By using this
Hook
, you can tell theReact
component to perform certain operations after rendering.React
will save the function you passed (we call it "effect") and call it afterDOM
Why call in the internal components
useEffect
?The
useEffect
internal components so that we can put ineffect
direct access to thecount state
variable (or otherprops
).useEffect
be executed after every rendering?Yes, by default, it after the first rendering and after each update will be executed (you can control the rendering conditions by the second argument mentioned earlier). Moreover,
React
ensures that every timeeffect
isDOM
has been updated.
summary
useEffect Hook
actually brings us the ability to handle side effects in function components. It is like a combination of the three functionscomponentDidMount
,componentDidUpdate
andcomponentWillUnmount
- The life cycle of the
useEffect Hook
andClass
useEffect
after the DOM has been updated,componentDidMount
is called immediately after the component is hung (inserted into the DOM tree), andcomponentDidUpdate()
is called immediately after the update. This method will not be executed for the first rendering.componentWillUnmount()
will be called directly before the component is unloaded and destroyed. useEffect Hook
the emergence of 06100dd532e097, component development will gradually be flooded with state logic and side effects. Each life cycle often contains some irrelevant logic. And its appearance helps us to better split these state logics, not forcing the division according to the life cycle, and adds many possibilities for development.
Preview of the next section
In the next section, we will introduce useRefs
to everyone, so stay tuned!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。