關(guān)于useEffect執(zhí)行兩次的問(wèn)題及解決
useEffect執(zhí)行兩次問(wèn)題
在useEffect第二個(gè)參數(shù)變化的時(shí)候,需要在父組件里面更改這個(gè)值的地方加一個(gè)判斷,如果有值則設(shè)置為空,else更新這個(gè)值。useEffect第二個(gè)值可以是表達(dá)式
父組件里面
//授權(quán)樹(shù)展示
? ? 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è)問(wèn)題在react官網(wǎng)中有過(guò)介紹,在使用的過(guò)程中,容易被忽略,在面試的時(shí)候卻經(jīng)常被問(wèn)及,(面試造航母,上班擰螺絲?),開(kāi)個(gè)玩笑這個(gè)問(wèn)題并不難回答,下面是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ù)將會(huì)被執(zhí)行
二、第二個(gè)參數(shù)可以不傳,不會(huì)報(bào)錯(cuò),但瀏覽器會(huì)無(wú)線循環(huán)執(zhí)行邏輯處理函數(shù)。
useEffect(() => {
/** 執(zhí)行邏輯 */
})
三、第二個(gè)參數(shù)如果只傳一個(gè)空數(shù)組,邏輯處理函數(shù)里面的邏輯只會(huì)在組件掛載時(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ù)會(huì)在組件掛載時(shí)執(zhí)行一次和(a或者b變量在棧中的值發(fā)生改變時(shí)執(zhí)行一次) 這是不是相當(dāng)于componentDidMount 和 componentDidUpdate 的結(jié)合
五、useEffect第一個(gè)參數(shù)可以返回一個(gè)回調(diào)函數(shù),這個(gè)回調(diào)函數(shù)將會(huì)在組件被摧毀之前和再一次觸發(fā)更新時(shí),將之前的副作用清除掉。這就相當(dāng)于componentWillUnmount。
useEffect去除副作用。我們可能會(huì)在組件即將被掛載的時(shí)候創(chuàng)建一些不斷循環(huán)的訂閱(計(jì)時(shí)器,或者遞歸循環(huán))。在組件被摧毀之前,或者依賴(lài)數(shù)組的元素更新后,應(yīng)該將這些訂閱也給摧毀掉。
比如以下的情況(沒(méi)有去除計(jì)時(shí)器,增大不必要的開(kāi)銷(xiāo)和代碼風(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常見(jiàn)跳坑
1、useEffect執(zhí)行函數(shù)被循環(huán)執(zhí)行。
出現(xiàn)這種情況可能有兩種原因。
沒(méi)傳第二個(gè)參數(shù)
useEffect(() => {
/** 執(zhí)行邏輯 */
})2、你在useEffect執(zhí)行函數(shù)里面改變了useEffect監(jiān)測(cè)的變量
const [a, setA] = useState(1);
useEffect(() => {
/** 執(zhí)行邏輯 */
setA(a + 1)
},[a])解決的方法 不要在useEffect第一參數(shù)執(zhí)行函數(shù)中去改變第二參數(shù)依賴(lài)元素的地址的值。當(dāng)依賴(lài)元素的地址的值發(fā)生改變,又會(huì)執(zhí)行一次執(zhí)行函數(shù),這不是無(wú)限循環(huán)么。
3、useEffect監(jiān)測(cè)不到依賴(lài)數(shù)組元素的變化。
只有一種可能,依賴(lài)數(shù)組元素的地址的值根本就沒(méi)變,比如:
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í)行卻沒(méi)有打印 a*/
useEffect(() => {
/** 執(zhí)行邏輯 */
console.log(a)
},[a])是因?yàn)閏hangeA沒(méi)有真正的改變a在棧中的值(地址的值),只是改變了a在堆中的值。
useEffect監(jiān)測(cè)不到堆中值得變化,所有引用類(lèi)型數(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中value與defaultValue的區(qū)別及說(shuō)明
這篇文章主要介紹了react中value與defaultValue的區(qū)別及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-05-05
React?Native性能優(yōu)化紅寶書(shū)方案詳解
React?Native?是Facebook在React.js?Conf2015推出的開(kāi)源框架,使用React和應(yīng)用平臺(tái)的原生功能來(lái)構(gòu)建Android和iOS應(yīng)用,這篇文章主要介紹了React?Native性能優(yōu)化紅寶書(shū),需要的朋友可以參考下2024-06-06
聊聊ant?design?charts?獲取后端接口數(shù)據(jù)展示問(wèn)題
今天在做項(xiàng)目的時(shí)候遇到幾個(gè)讓我很頭疼的問(wèn)題,一個(gè)是通過(guò)后端接口成功訪問(wèn)并又返回?cái)?shù)據(jù),但拿不到數(shù)據(jù)值。其二是直接修改state中的data,console中數(shù)組發(fā)生變化但任然數(shù)據(jù)未顯示,這篇文章主要介紹了ant?design?charts?獲取后端接口數(shù)據(jù)展示,需要的朋友可以參考下2022-05-05
30分鐘精通React今年最勁爆的新特性——React Hooks
這篇文章主要介紹了30分鐘精通React今年最勁爆的新特性——React Hooks,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-03-03
webpack入門(mén)+react環(huán)境配置
webpack是一個(gè)前端資源模塊化管理和打包工具,說(shuō)白了就是方便我們管理自己的常用的一些代碼,比如你開(kāi)發(fā)中用到sass以及jade同時(shí)用到es6,開(kāi)發(fā)時(shí)你不可能改動(dòng)某個(gè)地方就挨個(gè)命令去轉(zhuǎn)換再到瀏覽器去看效果,那樣效率是非常低的。所以webpack幫我們省去了那些多余的步驟。2017-02-02
Zustand介紹與使用 React狀態(tài)管理工具的解決方案
本文主要介紹了Zustand,一種基于React的狀態(tài)管理庫(kù),Zustand以簡(jiǎn)潔易用、靈活性高及最小化原則等特點(diǎn)脫穎而出,旨在提供簡(jiǎn)單而強(qiáng)大的狀態(tài)管理功能2024-10-10
react使用websocket實(shí)時(shí)通信方式
這篇文章主要介紹了react使用websocket實(shí)時(shí)通信方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09

