React hooks 闭包陷阱
react Hooks 陷阱
1、useState 陷阱
陷阱:【异步陷阱】
function Index() {
const [count, setCount] = useState(0);
function add(){
setCount( count 1 );
console.log(count); // 0
}
return (
<div>
<span>{count}</span>
<button @click=()=>{ add() }> </button>
</div>
);
}
- 点击添加按钮,发现值更新了,打印的值却还是上次的
- 什么 useState 修改状态 是异步
解决方法:
- 所以我们不能修改后,把值去拿去其他操作 (应该拿 count 1)
- 可以通过 promise 来 .then 获取 最新 👇
new Promise((resolve) => {
setCount((count) => {
resolve(count 1);
return count 1;
});
}).then((res) => {
// 下一步操作
console.log(res)
});
陷阱:【只更新最后1个】
function Index() {
const [count, setCount] = useState(0);
function add(){
setCount( count 1 );
setCount( count 2 );
setCount( count 3 );
}
return (
<div>
<span>{count}</span>
<button @click=()=>{ add() }> </button>
</div>
);
}
- 此时 只执行了 最后一个 setCount , 导致数据不是部分逻辑未执行
- 如果出现这种 判断条件多次 操作 useState 怎么解决 👇
function add(){
let num = count;
if(...) { num = 1; }
if(...) { num = 2; }
if(...) { num = 3; }
setCount( num );
}
2、useEffect 陷阱
陷阱:【过期闭包】
function Index() {
const [count, setCount] = useState(0);
useEffect(()=>{
setInterval(() => { console.log(`Count: ${count}`) }, 1000);
}, []);
return (
<div>
<span>{count}</span>
<button @click=()=>{ setCount(count 1) }> </button>
</div>
);
}
- 通过计时器,每 1 秒 打印下 count
- 点击按钮,count 已增加 ,打印的值一直不变
- 说明此时的 useEffect 中的 count ,还是取的 过期的值
解决方法:
- 需要,添加依赖项 count ,
- 并且每次更新,添加计时器,结束改变计时器
function Index() {
const [count, setCount] = useState(0);
useEffect(()=>{
const time = setInterval(() => { console.log(`Count: ${count}`) }, 1000);
return () => { clearInterval(time) };
}, [count]);
return (
<div>
<span>{count}</span>
<button @click=()=>{ setCount(count 1) }> </button>
</div>
);
}
3、useCallback 陷阱
- useCallback 本来拿来优化性能,当依赖变化不用重新注册该函数
- 使用不当也会,出现一定的问题
陷阱:【获取父组件的值,不是最新】
function Parent() {
let [count, setCount] = useState(0);
return (
<div>
<button onClick={() => setCount(count 1)}> 1 </button>
// 子组件
<Child count={count} />
</div>
);
}
function Child(props){
let log = useCallback(() => { console.log(props.count) }, [])
return (
<div>
count: {props.count}
<button onClick={() => log()}> 打印 </button>
</div>
);
}
- 此时我们在 父组件点击 增加按钮
- 子组件的 count 发生改变 ,我们在点击打印按钮,发现count 一直是0
- 说明useCallback 依赖为【】数组,取到count 已经过期了 ,
解决方法:
- 方法1 :等于没有优化 (依赖更新,useCallback重写一次)
let log = useCallback(() => { console.log(props.count) }, [props.count])
- 方法2 :将获取 count 的方法 创建到父组件,子组件调用父组件方法
function Parent() {
let [count, setCount] = useState(0);
let log = useCallback(() => { console.log(count) }, [])
return (
<div>
<button onClick={() => setCount(count 1)}> 1 </button>
// 子组件
<Child count={count} log={log} />
</div>
);
}
function Child(props){
return (
<div>
count: {props.count}
<button onClick={() => props.log()}> 打印 </button>
</div>
);
}
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhicifbf
系列文章
更多
同类精品
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
excel下划线不显示怎么办
PHP中文网 06-23 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
微信运动停用后别人还能看到步数吗
PHP中文网 07-22 -
excel打印预览压线压字怎么办
PHP中文网 06-22