Javascript 反作用useCallback与debounce一起使用旧值,如何获取实际状态值?
我不能满足所有条件:Javascript 反作用useCallback与debounce一起使用旧值,如何获取实际状态值?,javascript,reactjs,use-effect,usecallback,Javascript,Reactjs,Use Effect,Usecallback,我不能满足所有条件: 我需要useCallback中的一些函数,因为我将它设置为子组件的道具(用于重新渲染) 我需要使用debounce,因为我的函数是“端点”,可以每秒调用约100次 我需要得到当前(实际值)后,去盎司 我对最后一点有问题,我的去盎司(1000ms)后的值已经过时了 如何使用useCallback+debounce获取当前值?(警报中的值必须与第页相同) //ES6常量,让 //ES6解构 const{Component,useCallback,useState,useff
useCallback
中的一些函数,因为我将它设置为子组件的道具(用于重新渲染)debounce
,因为我的函数是“端点”,可以每秒调用约100次useCallback
+debounce
获取当前值?(警报中的值必须与第页相同)
//ES6常量,让
//ES6解构
const{Component,useCallback,useState,useffect}=React;
const SUBChildComponent=(道具)=>(带去盎司的GetValue);
常量ChildComponent=()=>{
//一些不稳定状态
const[someVal1,setSomeVal1]=useState(0);
const[someVal2,setSomeVal2]=useState(0);
const[someVal3,setSomeVal3]=useState(0);
//一些回调开关处理状态,并从subClild组件调用
const getVal=useCallback(u.debounce(()=>{
警报(`someVal1}\n${someVal2}\n${someVal3}`);
}[someVal1,someVal2,someVal3]);
//一些综合变化
useffect(()=>{
const id=setInterval(()=>setSomeVal1(someVal1+1),50);
return()=>clearInterval(id);
},[someVal1]);
//一些综合变化
useffect(()=>{
const id=setInterval(()=>setSomeVal2(someVal2+1),100);
return()=>clearInterval(id);
},[someVal2]);
//一些综合变化
useffect(()=>{
const id=setInterval(()=>setSomeVal3(someVal3+1),250);
return()=>clearInterval(id);
},[someVal3]);
返回
{someVal1}
{someVal2}
{someVal3}
;
};
类应用程序扩展组件{
render(){
返回();
}
}
render(,document.querySelector(“.container”)代码>
首先,您必须注意,debounce函数在创建时设置其闭包的状态。现在,该函数在几秒钟后执行,到那时,状态将发生变化。此外,每次更新状态时,都会创建一个新的debounce实例,因此,如果使用onClick的debounce函数,它将无法正常工作,因为不同的调用将调用不同的debounce函数实例,而不是同一个实例
这种情况下的解决方案是将状态值作为参数传递给debounce函数,而不是让它依赖于闭包。但是,它仍然使用调用debounce时使用的值,正如您在下面的代码段中所看到的
//ES6常量,让
//ES6解构
const{Component,useCallback,useState,useffect}=React;
const SUBChildComponent=({getVal,someVal1,someVal2,someVal3})=>(getVal(someVal1,someVal2,someVal3)}>GetValue带去盎司);
常量ChildComponent=()=>{
//一些不稳定状态
const[someVal1,setSomeVal1]=useState(0);
const[someVal2,setSomeVal2]=useState(0);
const[someVal3,setSomeVal3]=useState(0);
//一些回调开关处理状态,并从subClild组件调用
const getVal=useCallback(u.debounce((val1,val2,val3)=>{
警报(`${val1}\n${val2}\n${val3}`);
},1000),[]);//只创建一次解盎司函数
//一些综合变化
useffect(()=>{
const id=setInterval(()=>setSomeVal1(someVal1+1),50);
return()=>clearInterval(id);
},[someVal1]);
//一些综合变化
useffect(()=>{
const id=setInterval(()=>setSomeVal2(someVal2+1),100);
return()=>clearInterval(id);
},[someVal2]);
//一些综合变化
useffect(()=>{
const id=setInterval(()=>setSomeVal3(someVal3+1),250);
return()=>clearInterval(id);
},[someVal3]);
返回
{someVal1}
{someVal2}
{someVal3}
;
};
类应用程序扩展组件{
render(){
返回();
}
}
render(,document.querySelector(“.container”)代码>
这是否回答了您的问题?我不明白你为什么要干掉那个人。设置状态并简单地将当前状态作为道具传递下去不是更有意义吗?@trixn,没有。这是一个库,我只为用户代码提供了save()
方法。用户代码不知道任何库私有状态及其值。他们只是用
制作组件,并多次调用save()
@JDansercoer不,这是一个类似的问题,但不是相同的问题,解决方案完全不同。@MixerOID因此在您的实际应用程序中,getVal
是save
,而不是altert
ing,您想将当前值从您的状态保存到后端(触发api调用)?@trixn,是的。这段代码只是以最简单的方式显示问题的“简化示例”。使用ref
可以很好地解决问题。正如我看到的,您可以在最终代码中删除someVal1={someVal1}someVal2={someVal2}someVal3={someVal3}
。但是为什么每次都会重新渲染子childComponent
?我和你使用了useCallback
作为道具,我希望避免使用子组件渲染器。你可以通过使用React.memo
reactjs.org实现。文档说useCallback(fn,deps)等同于usecmemo(()=>fn,deps)
。但在我看来,这是不一样的。我认为默认情况下,在功能组件中使用静态/记忆化的道具,我也会像使用常规组件一样防止重新渲染。但显然情况并非如此。它们可以用于相同的目的,但有不同的语法。但是,为了防止重新呈现,您需要React.memo
以及usecallback来记忆函数