關(guān)于useEffect執(zhí)行兩次的問題及解決
useEffect執(zhí)行兩次問題
在useEffect第二個(gè)參數(shù)變化的時(shí)候,需要在父組件里面更改這個(gè)值的地方加一個(gè)判斷,如果有值則設(shè)置為空,else更新這個(gè)值。useEffect第二個(gè)值可以是表達(dá)式
父組件里面
//授權(quán)樹展示
? ? const handleRoleModalVisible = (RoleModelVisibel: boolean, record?: any) => {
? ? ? ? setRoleModalVisible(RoleModelVisibel);
? ? ? ? // console.log(record)
? ? ? ? if(RoleModelVisibel==undefined){
? ? ? ? ? ? setroleAuth(undefined)
? ? ? ? }else{
? ? ? ? ? ? setroleAuth(record)
? ? ? ? }
? ? };子組件里面
?const {roleAuth, treeData, roleModalVisible, handleRoleModalVisible} = props;
? ? useEffect(() => {
? ? ? ? queryTreeId({role_id: roleAuth.roleId}).then(res => {
? ? ? ? ? ? setCheckedKeys(res.data.content)
? ? ? ? ? ? setSelectedKeys(res.data.content)
? ? ? ? })
? ? }, [roleAuth!==undefined])在最后
?{
? ? ?roleAuth&&<Authority roleAuth={roleAuth} ?treeData={treeData}
? ? ?roleModalVisible={roleModalVisible} handleRoleModalVisible={handleRoleModalVisible}/>
?}react使用useEffect及踩坑
useEffect 介紹
useEffect時(shí)reactHook中最重要,最常用的hook之一。
useEffect相當(dāng)于react中的什么生命周期呢?
這個(gè)問題在react官網(wǎng)中有過介紹,在使用的過程中,容易被忽略,在面試的時(shí)候卻經(jīng)常被問及,(面試造航母,上班擰螺絲?),開個(gè)玩笑這個(gè)問題并不難回答,下面是react官方的原話:
如果你熟悉 React class 的生命周期函數(shù),你可以把 useEffect Hook 看做 componentDidMount,componentDidUpdate 和 componentWillUnmount 這三個(gè)函數(shù)的組合。
componentDidMount組件掛載componentDidUpdate組件更新componentWillUnmount組件將要摧毀
useEffect需要傳遞兩個(gè)參數(shù),第一個(gè)參數(shù)是邏輯處理函數(shù),第二個(gè)參數(shù)是一個(gè)數(shù)組
用法
useEffect(() => {
/** 執(zhí)行邏輯 */
},[])重要理解
一、第二個(gè)參數(shù)存放變量,當(dāng)數(shù)組存放變量發(fā)生改變時(shí),第一個(gè)參數(shù),邏輯處理函數(shù)將會被執(zhí)行
二、第二個(gè)參數(shù)可以不傳,不會報(bào)錯,但瀏覽器會無線循環(huán)執(zhí)行邏輯處理函數(shù)。
useEffect(() => {
/** 執(zhí)行邏輯 */
})
三、第二個(gè)參數(shù)如果只傳一個(gè)空數(shù)組,邏輯處理函數(shù)里面的邏輯只會在組件掛載時(shí)執(zhí)行一次 ,不就是相當(dāng)于 componentDidMount
useEffect(() => {
/** 執(zhí)行邏輯 */
},[])四、第二個(gè)參數(shù)如果不為空數(shù)組,如下
const [a, setA] = useState(1);
const [b, setB] = useState(2);
useEffect(() => {
/** 執(zhí)行邏輯 */
},[a,b])邏輯處理函數(shù)會在組件掛載時(shí)執(zhí)行一次和(a或者b變量在棧中的值發(fā)生改變時(shí)執(zhí)行一次) 這是不是相當(dāng)于componentDidMount 和 componentDidUpdate 的結(jié)合
五、useEffect第一個(gè)參數(shù)可以返回一個(gè)回調(diào)函數(shù),這個(gè)回調(diào)函數(shù)將會在組件被摧毀之前和再一次觸發(fā)更新時(shí),將之前的副作用清除掉。這就相當(dāng)于componentWillUnmount。
useEffect去除副作用。我們可能會在組件即將被掛載的時(shí)候創(chuàng)建一些不斷循環(huán)的訂閱(計(jì)時(shí)器,或者遞歸循環(huán))。在組件被摧毀之前,或者依賴數(shù)組的元素更新后,應(yīng)該將這些訂閱也給摧毀掉。
比如以下的情況(沒有去除計(jì)時(shí)器,增大不必要的開銷和代碼風(fēng)險(xiǎn))
const [time, setTime] = useState(0)
useEffect(() => {
?? ?const InterVal = setInterval(() => {
?? ??? ?setTime(time + 1)
?? ?},1000)
},[])利用第五點(diǎn),在組件被摧毀前去除計(jì)時(shí)器。
const [time, setTime] = useState(0)
useEffect(() => {
?? ?const InterVal = setInterval(() => {
?? ??? ?setTime(time + 1)
?? ?},1000)
?? ?return () => {
? ??? ??? ?clearInterval(InterVal )
? ??? ?}
},[])useEffect常見跳坑
1、useEffect執(zhí)行函數(shù)被循環(huán)執(zhí)行。
出現(xiàn)這種情況可能有兩種原因。
沒傳第二個(gè)參數(shù)
useEffect(() => {
/** 執(zhí)行邏輯 */
})2、你在useEffect執(zhí)行函數(shù)里面改變了useEffect監(jiān)測的變量
const [a, setA] = useState(1);
useEffect(() => {
/** 執(zhí)行邏輯 */
setA(a + 1)
},[a])解決的方法 不要在useEffect第一參數(shù)執(zhí)行函數(shù)中去改變第二參數(shù)依賴元素的地址的值。當(dāng)依賴元素的地址的值發(fā)生改變,又會執(zhí)行一次執(zhí)行函數(shù),這不是無限循環(huán)么。
3、useEffect監(jiān)測不到依賴數(shù)組元素的變化。
只有一種可能,依賴數(shù)組元素的地址的值根本就沒變,比如:
const [a, setA] = useState({
b: 'dx',
c: '18',
})
const changeA = () => {
?? ?setA((old) => {
?? ?old.b = 'yx'
?? ?return old
?? ?})
}
useEffect(() => {
/** 當(dāng)組件掛載時(shí)執(zhí)行一次changeA */
changeA ()
},[])
/**當(dāng)changeA執(zhí)行卻沒有打印 a*/
useEffect(() => {
/** 執(zhí)行邏輯 */
console.log(a)
},[a])是因?yàn)閏hangeA沒有真正的改變a在棧中的值(地址的值),只是改變了a在堆中的值。
useEffect監(jiān)測不到堆中值得變化,所有引用類型數(shù)據(jù)都應(yīng)該注意這一點(diǎn)。
解決的辦法:
const [a, setA] = useState({
b: 'dx',
c: '18',
})
const changeA = () => {
?? ?setA((old) => {
?? ?const newA = {...old}
?? ?newA .b = 'yx'
?? ?return newA?
?? ?})
}
useEffect(() => {
/** 當(dāng)組件掛載時(shí)執(zhí)行一次changeA */
changeA ()
},[])
/**當(dāng)changeA執(zhí)行打印 ?{b:'yx',c:'18'} ?*/
useEffect(() => {
/** 執(zhí)行邏輯 */
console.log(a)
},[a])以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
React官方團(tuán)隊(duì)完善原生Hook閉包陷阱
這篇文章主要為大家介紹了React官方團(tuán)隊(duì)出手,補(bǔ)齊原生Hook短板閉包陷阱的示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07
React ant 點(diǎn)擊導(dǎo)航條閃爍問題解決
很多小伙伴反饋React ant 點(diǎn)擊導(dǎo)航條閃爍,沒有傳遞具體的參數(shù)給點(diǎn)擊事件 , 導(dǎo)致在函數(shù)內(nèi)部無法準(zhǔn)確判斷要展示哪個(gè)子菜單,可能導(dǎo)致頁面狀態(tài)的短暫變化,出現(xiàn)閃爍效果,下面給大家分享解決方法,感興趣的的朋友跟隨小編一起看看吧2024-04-04
ReactHook使用useState更新變量后,如何拿到變量更新后的值
這篇文章主要介紹了ReactHook使用useState更新變量后,如何拿到變量更新后的值問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-03-03
React中使用collections時(shí)key的重要性詳解
這篇文章主要給大家介紹了關(guān)于在React.js中使用collections時(shí)key的重要性,注意:一定不能不能忘了key,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面跟著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2017-08-08
React Ref Callback使用場景最佳實(shí)踐詳解
這篇文章主要為大家介紹了React Ref Callback使用場景最佳實(shí)踐詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01
React合成事件原理及實(shí)現(xiàn)(React18和React16)
本文主要介紹了React合成事件原理及實(shí)現(xiàn),包含React18和React16兩種版本,具有一定的參考價(jià)值,感興趣的可以了解一下2025-02-02

