1.默认情况下,useEffect会在组件渲染完成后调用,并且每次渲染完成后调用
useEffect(() => {
console.log("默认执行Effect")
})
2.useEffect可以传递第二个参数,为数组,数组中可以指定useEffect的依赖项,只有当依赖项发生变化时,useEffect才会被触发
import { useState, useEffect } from 'react'
const App = () => {
const [count, setCount] = useState<number>(0)
const handleAdd = () => {
setCount(count + 1)
}
useEffect(() => {
console.log(count)
}, [count])
return (
<div>
<div>{count}</div>
<button onClick={handleAdd}>+</button>
</div>
)
}
export default App
当count的值发生变化的时候,才会触发useEffect(useEffect第二个值可以传递多个)
通常实际开发中,useEffect中使用的所有变量都应该设置为依赖项
3.如果依赖项设置了一个空数组,则useEffect只会在组件初始化的时候触发一次(如果希望只触发一次,可以这样写)
import { useState, useEffect } from 'react'
const App = () => {
const [count, setCount] = useState<number>(0)
const handleAdd = () => {
setCount(count + 1)
}
useEffect(() => {
console.log("只执行一次")
console.log(count) // => 只打印一次渲染之前的值
}, [])
return (
<div>
<div>{count}</div>
<button onClick={handleAdd}>+</button>
</div>
)
}
export default App
需要注意的是,ueEffect的第二个参数不能为引用类型,因为引用类型比较不出来数据的变化,会造成死循环
import { useState, useEffect } from 'react'
const App = () => {
const [count, setCount] = useState({
userName: ""
})
const handleAdd = () => {
setCount({ userName: "AAA" })
}
useEffect(() => {
console.log(count)
setCount({ userName: "死循环了" })
}, [count])
return (
<div>
<div>{count.userName}</div>
<button onClick={handleAdd}>change</button>
</div>
)
}
export default App
自己写了一个简单的商品展示搜索demo,还望指正
3.useEffect清理函数
import { useEffect, useState } from "react"
const App = () => {
const [searchName, setQueryName] = useState("")
useEffect(() => {
console.log("useEffect执行了")
// 默认先执行清理函数
// 可以做一些工作来清除上次useEffect执行所带来的影响
return () => {
console.log("useEffect的返回函数执行了") // => 在下次执行useEffect函数执行时执行
}
}, [searchName])
return (
<div></div>
)
}
export default App
做一个例子,比如我们实现一个表单输入防抖
import { ChangeEvent, useEffect, useState } from "react"
const App = () => {
const [searchName, setQueryName] = useState<string>("")
const handleSearch = () => {
console.log(searchName)
}
const handleValue = (e: ChangeEvent<HTMLInputElement>) => {
setQueryName(e.target.value)
}
useEffect(() => {
const timer = setTimeout(() => {
setQueryName(searchName) // 4.为searchName设置出发之后的值
if (searchName) {
console.log(searchName)
}
}, 1000) // 3.又开启了一个新的计时器,当一秒之后没有,值没有变化,执行一次计时器
return () => {
clearTimeout(timer) // 2.当触发useEffect函数的时候,默认执行清除函数,并且清除计时器
}
}, [searchName]) // 1.当表单中的searchName发生变化的时候,触发useEffect函数
// 每当值发生变化的时候,不停的清除计时器开启新的计时器,直到值没有变化时,最终执行一次计时器
return (
<div>
<div>
<input type="search" placeholder='请输入要搜索的商品名称' onChange={handleValue} defaultValue={searchName} />
<button onClick={handleSearch}>Search</button>
</div>
</div>
)
}
export default App