useEffect 永远是在 DOM渲染完成之后执行
1.理解函数副作用
什么是副作用?
对于React组件来说,主作用是根据数据(state/props)渲染UI,除此之外都是副作用(比如手动修改DOM、发送ajax请求)。
常见的副作用
- 数据请求(发送ajax)
- 手动修改 DOM
- localstorage操作
useEffect 函数的作用就是为react函数组件
提供副作用
2.基础使用
使用步骤
- 导入
useEffect
函数 - 调用
useEffect
函数,并传入回调函数 - 在回调函数中编写副作用处理
- 修改数据状态
- 检测副作用是否生效
示例代码
import {useState, useEffect} from 'react';
function App() {
const [count, setCount] = useState(0);
useEffect(() => {
console.log("触发副作用");
document.title = `点击了${count}次`;
});
return (
<div>
<button onClick={() => setCount(count + 1)}>点击{count}次</button>
</div>
)
}
3.依赖项控制
副作用执行时机
1.默认状态(无依赖项)
上边的示例中,组件初始化时先触发一次(console出内容),之后每次点击按钮,都会触发 副作用。
useEffect 可执行多次。
2.依赖项 为空
useEffect 函数还可以接收第二个参数,作为该副作用的依赖项,当第二个参数 传入一个空数组[] 时,表明只有 组件初始化的时候执行一次:
咱们对上边的案例做下 微调
function App() {
const [count, setCount] = useState(0);
useEffect(() => {
console.log("触发副作用");
document.title = `点击了${count}次`;
}, []); // 注意这里,传入 []
return (
<div>
<button onClick={() => setCount(count + 1)}>点击{count}次</button>
</div>
)
}
可以看到当点击按钮时,title 不再改变。
3.依赖特定项
当依赖项数组中传入值时,那么该副作用会在 组件初始化的时候执行一次,依赖的特定项变化时会再次执行
function App() {
const [count, setCount] = useState(0);
const [name, setName] = useState('李白');
useEffect(() => {
console.log('触发渲染')
document.title = `clicked ${count} times`;
console.log('name: ', {name});
},[count]) // 这里我们传入 count,不传name
return (
<>
<p>当前次数:{count}</p>
<p><button onClick={() => setCount(count + 1)}>累计</button></p>
<p><button onClick={() => setName("杜甫")}>改名{name}</button></p>
</>
)
}
如上,当我们点击 “累计” 按钮时,会console内容,title也会改变,但是我们点击 “改名”时,不会发生变化,就是因为我们在依赖项数组中传入了 “count” 而没有 “name”。
4.注意事项
只要在 useEffect 回调函数中用到的数据状态就应该出现在依赖项数组中声明,否则可能会有bug。
5.清除副作用
在组件被销毁时,如果有些副作用操作需要被清理,比如常见的定时器等,可通过useEffect return回调函数
的方式清理副作用。
语法如下:
useEffect(() => {
console.log('副作用函数执行');
return () => {
console.log('清理副作用的函数执行');
// 这里执行 清理副作用的代码
}
})
示例:
function Test() {
useEffect(() => {
let timer = setInterval(() => {
console.log('this is effect');
}, 1000)
// 这里return 一个回调函数,在函数中清除副作用
return () => {
clearInterval(timer);
}
})
return (
<div>Test</div>
)
}
function App() {
const [flag, setFlag] = useState(true);
return (
<div>
{flag ? <Test/> : null}
<div>
<button onClick={() => setFlag(!flag)}>点击</button>
</div>
</div>
)
}
6.发送网络请求
不可以直接在 useEffect 的回调函数外层直接包裹await,因为异步会导致清理函数无法立即返回
❌错误示例:
useEffect(async () => {
const res = await getData('url');
console.log(res);
})
可在 useEffect 中定义一个请求数据方法,调用。
正确示例
:
useEffect(() => {
async function initData() {
const res = await getData('url');
console.log(res);
}
initData()
}, []) // 仅组件初始化时调用
到此这篇关于React-hooks中的useEffect的文章就介绍到这了,更多相关React-hooks useEffect内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!