react中遇到过那些过期闭包的坑吗?怎么解决?
1、useEffect中过期闭包的表现
import React, { useState, useEffect, useContext } from 'react';
export default function hook() {
const [count, setCount] = useState(0)
/**
* 每次点击都会调用,没切都是原来的值
*/
useEffect(() => {
// 是一个过时的闭包
setInterval(() => {
console.log(count)
}, 2000)
}, [])
return (
<div>
{count}
<button onClick={() => setCount(count + 1)}> 加1 </button>
</div>
)
}
2、useEffect解决方案
让useEffect()知道定时器的方法里面中的闭包依赖于count
import React, { useState, useEffect, useContext } from 'react';
export default function hook() {
const [count, setCount] = useState(0)
/**
* 每次点击都会调用,没切都是原来的值
*/
useEffect(() => {
// 是一个过时的闭包
const ter = setInterval(() => {
console.log(count)
}, 2000)
// 每次调用前先清空定时器,或者说重新创建
return () => {
clearInterval(ter)
}
// 这行是重点,count变化后重新渲染useEffect
}, [count])
return (
<div>
{count}
<button onClick={() => setCount(count + 1)}> 加1 </button>
</div>
)
}
3、useState过期闭包的表现
点击 +1 然后立即点击 +2,count 只更新到 1。这是因为 delay() 是一个过时的闭包
import React, { useState, useEffect, useContext } from 'react';
export default function hook() {
const [count, setCount] = useState(0);
/**
*
* delay() 是一个过时的闭包,它使用在初始渲染期间捕获的过时的 count 变量
*/
function add() {
setTimeout(function delay() {
setCount(count + 1);
}, 1000);
}
const add2 = () => {
setCount(count + 2)
}
return (
<div>
{count}
<button onClick={() => add()}>+1 </button>
<button onClick={() => add2()}>+2</button>
</div>
)
}
4、useState解决方案
import React, { useState, useEffect, useContext } from 'react';
export default function hook() {
const [count, setCount] = useState(0);
/**
*
* delay() 是一个过时的闭包,它使用在初始渲染期间捕获的过时的 count 变量
*/
function add() {
setTimeout(function delay() {
setCount((a) => a + 1);
}, 1000);
}
const add2 = () => {
setCount(count + 2)
}
return (
<div>
{count}
<button onClick={() => add()}>+1 </button>
<button onClick={() => add2()}>+2</button>
</div>
)
}
5 useCallback如果依赖项传一个空数组内部也会形成过期闭包
import React, { useState, useEffect, useContext } from 'react';
export default function hook() {
const [count, setCount] = useState(0);
/**
*
* delay() 是一个过时的闭包,它使用在初始渲染期间捕获的过时的 count 变量
*/
function add() {
setTimeout(function delay() {
setCount((a) => a + 1);
}, 1000);
}
const add2 = () => {
setCount(count + 2)
}
useCallback(() => {
// 值永远不会更新
console.log(count)
}, [])
return (
<div>
{count}
<button onClick={() => add()}>+1 </button>
<button onClick={() => add2()}>+2</button>
</div>
)
}
猜你喜欢LIKE
相关推荐HOT
更多>>servlet底层原理是什么?
1、ServletAPI核心类与接口2、Servlet类处理请求的流程创建servlet类的步骤:创建一个命名为TestServlet继承javax.servlet.http.HttpServlet类详情>>
2023-05-30 10:41:22多线程的优势与劣势分别是什么?
多线程是指在同一个程序中,同时运行多个线程,每个线程都可以独立执行不同的任务,相互之间不会干扰。多线程的优势和劣势如下:优势:提高程序...详情>>
2023-05-30 10:32:12设计模式之生产者与消费者的代码实现
本文主要讲述生产者和消费者模式,文中会使用通俗易懂的案例,使你更好地学习本章知识点并理解原理,做到有道无术。什么是生产者和消费者模式生...详情>>
2023-05-30 10:25:46从零开始学Java之interface接口
一.接口简介简介Java中的接口(interface)类似于是一种特殊的抽象类,它也是众多抽象方法的集合。接口的定义方式、组成部分都与抽象类相似,却比...详情>>
2023-05-29 11:26:17热门推荐
如何进行mysql数据备份?
沸什么是servlet的生命周期?servlet请求处理流程是怎样的?
热servlet底层原理是什么?
热怎样编写java程序?
新多线程的优势与劣势分别是什么?
ssm框架的作用与原理是什么?
设计模式之生产者与消费者的代码实现
接口和抽象类有什么区别?4个方面对比
从零开始学Java之interface接口
从零开始学Java之Java中的内部类是怎么回事?
一分钟带你了解MySQL——基础与介绍
在java中,super关键字怎样使用
什么是事件流以及事件流的传播机制 ?
弹性盒有哪些属性是在父元素身上?