網(wǎng)站首頁 編程語言 正文
useEffect執(zhí)行兩次問題
在useEffect第二個參數(shù)變化的時候,需要在父組件里面更改這個值的地方加一個判斷,如果有值則設(shè)置為空,else更新這個值。useEffect第二個值可以是表達式
父組件里面?
//授權(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時reactHook中最重要,最常用的hook之一。
useEffect相當于react中的什么生命周期呢?
這個問題在react官網(wǎng)中有過介紹,在使用的過程中,容易被忽略,在面試的時候卻經(jīng)常被問及,(面試造航母,上班擰螺絲?),開個玩笑這個問題并不難回答,下面是react官方的原話:
如果你熟悉 React class 的生命周期函數(shù),你可以把 useEffect Hook 看做 componentDidMount,componentDidUpdate 和 componentWillUnmount 這三個函數(shù)的組合。
-
componentDidMount
組件掛載 -
componentDidUpdate
組件更新 -
componentWillUnmount
組件將要摧毀
useEffect需要傳遞兩個參數(shù),第一個參數(shù)是邏輯處理函數(shù),第二個參數(shù)是一個數(shù)組
用法
useEffect(() => { /** 執(zhí)行邏輯 */ },[])
重要理解
一、第二個參數(shù)存放變量,當數(shù)組存放變量發(fā)生改變時,第一個參數(shù),邏輯處理函數(shù)將會被執(zhí)行
二、第二個參數(shù)可以不傳,不會報錯,但瀏覽器會無線循環(huán)執(zhí)行邏輯處理函數(shù)。
useEffect(() => { /** 執(zhí)行邏輯 */ })
三、第二個參數(shù)如果只傳一個空數(shù)組,邏輯處理函數(shù)里面的邏輯只會在組件掛載時執(zhí)行一次 ,不就是相當于 componentDidMount
useEffect(() => { /** 執(zhí)行邏輯 */ },[])
四、第二個參數(shù)如果不為空數(shù)組,如下
const [a, setA] = useState(1); const [b, setB] = useState(2); useEffect(() => { /** 執(zhí)行邏輯 */ },[a,b])
邏輯處理函數(shù)會在組件掛載時執(zhí)行一次和(a或者b變量在棧中的值發(fā)生改變時執(zhí)行一次) 這是不是相當于componentDidMount 和 componentDidUpdate 的結(jié)合
五、useEffect第一個參數(shù)可以返回一個回調(diào)函數(shù),這個回調(diào)函數(shù)將會在組件被摧毀之前和再一次觸發(fā)更新時,將之前的副作用清除掉。這就相當于componentWillUnmount。
useEffect去除副作用。我們可能會在組件即將被掛載的時候創(chuàng)建一些不斷循環(huán)的訂閱(計時器,或者遞歸循環(huán))。在組件被摧毀之前,或者依賴數(shù)組的元素更新后,應(yīng)該將這些訂閱也給摧毀掉。
比如以下的情況(沒有去除計時器,增大不必要的開銷和代碼風(fēng)險)?
const [time, setTime] = useState(0) useEffect(() => { ?? ?const InterVal = setInterval(() => { ?? ??? ?setTime(time + 1) ?? ?},1000) },[])
利用第五點,在組件被摧毀前去除計時器。
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)這種情況可能有兩種原因。
沒傳第二個參數(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ù)依賴元素的地址的值。當依賴元素的地址的值發(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(() => { /** 當組件掛載時執(zhí)行一次changeA */ changeA () },[]) /**當changeA執(zhí)行卻沒有打印 a*/ useEffect(() => { /** 執(zhí)行邏輯 */ console.log(a) },[a])
是因為changeA沒有真正的改變a在棧中的值(地址的值),只是改變了a在堆中的值。
useEffect監(jiān)測不到堆中值得變化,所有引用類型數(shù)據(jù)都應(yīng)該注意這一點。
解決的辦法:
const [a, setA] = useState({ b: 'dx', c: '18', }) const changeA = () => { ?? ?setA((old) => { ?? ?const newA = {...old} ?? ?newA .b = 'yx' ?? ?return newA? ?? ?}) } useEffect(() => { /** 當組件掛載時執(zhí)行一次changeA */ changeA () },[]) /**當changeA執(zhí)行打印 ?{b:'yx',c:'18'} ?*/ useEffect(() => { /** 執(zhí)行邏輯 */ console.log(a) },[a])
原文鏈接:https://blog.csdn.net/weixin_47769562/article/details/121222531
相關(guān)推薦
- 2022-03-16 C#?使用Fluent?API?創(chuàng)建自己的DSL(推薦)_C#教程
- 2022-05-26 flutter底部彈出BottomSheet詳解_Android
- 2022-07-01 Python判斷Nan值的五種方式小結(jié)_python
- 2022-07-17 絕對、相對導(dǎo)入以及包和常見內(nèi)置模塊
- 2022-04-10 python中的單向鏈表實現(xiàn)_python
- 2022-09-26 利用C++實現(xiàn)?然連接操作算法_C 語言
- 2022-03-27 Android實現(xiàn)房貸計算器功能_Android
- 2022-06-08 FreeRTOS實時操作系統(tǒng)的任務(wù)創(chuàng)建和刪除_操作系統(tǒng)
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支