/* 会造成闭包 没有传递依赖项 useEffect只会执行一次 并且 第二个setInterval中 输出count
是引用的外部useState中定义的count 所以会造成闭包 并且只会保存刚开始实例化的count值也就是0
这样会造成 虽然我的setState一直在去+1 但是我的控制台 log的值 一直都是0
*/
import React,{useEffect,useState} from 'react' export default function LX() { let [count,setCount] = useState(0) useEffect(()=>{ setInterval(() => { setCount((c)=>c+1) },500); setInterval(()=>{ console.log(count); },500) },[]) return ( <div> </div> ) }
第一种解决方案 通过给useEffect传递依赖项 让我们的count值改变后 重新执行useEffect 让闭包的值重新获取 但是这种是需要传递依赖项
import React,{useEffect,useState} from 'react' export default function LX() { let [count,setCount] = useState(0) useEffect(()=>{ let time1 = setInterval(() => { setCount((c)=>c+1) },500); let time2 = setInterval(()=>{ console.log(count); },500) return () => { clearInterval(time1) clearInterval(time2) } },[count]) return ( <div> </div> ) }
第二种解决方案 不需要传递依赖项 我们通过useRef来实现 我们定义一个函数 在函数内部做重新赋值操作 已便于每次我调用方法的时候都可以重新获取到最新的值
然后在setIntrval中一直我去调用的是这个函数 然后每次调用都会重新赋值 重新log 重新+1
这样的话我不需要传递依赖项 也可以每次输出的都是最新的值
import React, { useEffect } from 'react' import { useLayoutEffect } from 'react'; import { useRef } from 'react'; import { useState } from 'react' export default function LX() { let [count,setCount] = useState({id:1,name:'123'}) const fn = () =>{ let newCount = { ...count } newCount.id ++ console.log(newCount.id); setCount(newCount) }; const ref = useRef(null) useLayoutEffect(()=>{ ref.current = fn; }); useEffect(()=>{ setInterval(() => { ref.current() },1000); },[]) return ( <div> </div> ) }