Effect几种使用方式

使用 Effect Hook

Effect Hook 可以让你在函数组件中执行副作用操作,什么是副作用:有时候,我们只想在 React 更新 DOM 之后运行一些额外的代码。比如发送网络请求,手动变更 DOM,记录日志,这些都是常见的无需清除的副作用。还有一些副作用是需要清除的。例如订阅外部数据源。这种情况下,清除工作是非常重要的,可以防止引起内存泄露!

class中的钩子函数

1
2
3
4
5
6
7
componentDidMount()
// componentDidMount() 会在组件挂载后(插入 DOM 树中)立即调用。依赖于 DOM 节点的初始化应该放在这里。如需通过网络请求获取数据,此处是实例化请求的好地方。
componentDidUpdate()
// componentDidUpdate() 会在更新后会被立即调用。首次渲染不会执行此方法。
componentWillUnmount()
// componentWillUnmount() 会在组件卸载及销毁之前直接调用。在此方法中执行必要的清理操作,例如,清除 timer,取消网络请求或清除在 componentDidMount() 中创建的订阅等。
// componentWillUnmount() 中不应调用 setState(),因为该组件将永远不会重新渲染。组件实例卸载后,将永远不会再挂载它。

使用方式1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import { useEffect, useState } from 'react'
const Count = () => {
const [count, setCount] = useState(0)
const addCount = () => {
setCount((pre) => pre + 1)
}
// 写法1
useEffect(() => {
console.log('useEffect钩子函数执行')
})
// 相当于调用componentDidMount() + componentDidUpdate()
return (
<div>
<div>{count}</div>
<button onClick={addCount}>+1</button>
</div>
)
}

使用方式2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import { useEffect, useState } from 'react'
const Count = () => {
const [count, setCount] = useState(0)
const addCount = () => {
setCount((pre) => pre + 1)
}
// 写法2
useEffect(() => {
console.log('useEffect钩子函数执行')
},[])
// 相当于调用componentDidMount()
return (
<div>
<div>{count}</div>
<button onClick={addCount}>+1</button>
</div>
)
}
export default Count

使用方式3

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import { useEffect, useState } from 'react'
const Count = () => {
const [count, setCount] = useState(0)
const addCount = () => {
setCount((pre) => pre + 1)
}
// 写法3
useEffect(() => {
console.log('useEffect钩子函数执行')
},[count])
// 相当于调用componentDidMount() + componentDidUpdate(),
// 注意componentDidUpdate()被调用是有条件的,只有数组中的 count 更新时才会更新
return (
<div>
<div>{count}</div>
<button onClick={addCount}>+1</button>
</div>
)
}
export default Count

使用方式4

1
2
3
4
5
6
7
8
9
10
11
useEffect(() => {
function handleStatusChange(status) {
setIsOnline(status.isOnline)
}
ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange)
// Specify how to clean up after this effect:
return function cleanup() {
ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange)
}
})
// 相当于调用componentDidMount() + componentWillUnmount(),

useEffect应用-发送请求

在组件中,可以使用useEffect Hook来发送请求(side effect)获取数据
注意:effect只能时一个同步函数,不能使用async
因为如果effect时async的,此时返回值时Promise对象。这样的话,就无法保证函数被立即调用
为了使用async/awair语法,可以在effect内部创建async函数,并调用
核心代码:

1
2
3
4
5
6
7
8
9
10
11
// 错误演示:不要给effect添加async
useEffect(async() => {
const res = await axios.get('http://xxx')
},[])
// 正确使用
useEffect(() => {
const loadData = async () => {
const res = await axios.get('http://xxx')
}
loadData()
},[])