Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/firebase/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 从回调访问状态_Reactjs_Typescript - Fatal编程技术网

Reactjs 从回调访问状态

Reactjs 从回调访问状态,reactjs,typescript,Reactjs,Typescript,从回调访问组件状态时遇到问题 statenum的值会正确更改,但加载时定义的回调函数看不到这些更改 import React,{useState}来自“React”; 类MyObject{ 回调:(()=>void); 构造函数(回调:()=>void){ this.callback=回调; } }; 导出常量测试页=()=>{ const[num,setNum]=useState(0); //将打印更改的值 log(`num:${num}`); 常量计数器=useState(()=>新的MyO

从回调访问组件状态时遇到问题

state
num
的值会正确更改,但加载时定义的回调函数看不到这些更改

import React,{useState}来自“React”;
类MyObject{
回调:(()=>void);
构造函数(回调:()=>void){
this.callback=回调;
}
};
导出常量测试页=()=>{
const[num,setNum]=useState(0);
//将打印更改的值
log(`num:${num}`);
常量计数器=useState(()=>新的MyObject(()=>{
//将始终打印0
log(`from callback.num:${num}`);
}))[0];
常量btnClick=()=>{
setNum((新日期()).getTime());
counter.callback();
};
返回(
测试,num:{num}
单击以更新状态
);
}
上述情况不会发生在普通的非反应代码中,如下所示

让myVar=0;
const obj=newmyobject(()=>console.log(`myVar:${myVar}`));
obj.callback();//打印0
myVar=1;
obj.callback();//印刷品1
编辑:我试图用闭包重现问题,但做不到

 const makeFun = (callback: (() => void)) => {
    return () => {
      callback();
    }
  }
  let myVar = 0;
  const f1 = makeFun(() => console.log(`myVar: ${myVar}`));
  myVar = 1;
  const f2 = makeFun(() => console.log(`myVar: ${myVar}`));
  f1(); // prints 1
  f2(); // prints 1
所以我怀疑是某种特定的反应和使用状态

有什么想法吗

编辑#2:解决方案。这是如何使它在非React代码中可见的

let callbackPersistent: (() => void);
const createCallback = (callback: (() => void)) => {
  if (!callbackPersistent) {
    callbackPersistent = callback;
  }
  return callbackPersistent;
}

const myFunction = (num:number) => {
  const callback = createCallback(() => console.log(`callback num: ${num}`));
  callback();
};
然后称之为

  myFunction(0); // prints 0
  myFunction(1); // prints 0
回调只有一个实例,它指向它第一次创建时看到的值

编辑#3

可以使用
useRef
useffect
找到合理的解决方案,如下所示:

import React, {useEffect, useRef, useState} from "react";

class MyObject {
  callback: (() => void);

  constructor(callback: () => void) {
    this.callback = callback;
  }
};

export const TestPage = () => {
  const [num, setNum] = useState<number>(0);
  const numRef = useRef(num);

  // will print the changing values
  console.log(`num: ${num}`);

  const counter = useState<MyObject>(() => new MyObject(() => {
    // will always print the latest value
    console.log(`from callback. num: ${numRef.current}`);
  }))[0];

  useEffect(()=> {numRef.current = num}, [num]);

  const btnClick = () => {
    setNum(new Date().getTime());
    counter.callback();
  };

  return (
      <div>Test, num: {num}
        <div>
          <button onClick={btnClick}>click to update state</button>
        </div>
      </div>
  );
}
import React,{useffect,useRef,useState}来自“React”;
类MyObject{
回调:(()=>void);
构造函数(回调:()=>void){
this.callback=回调;
}
};
导出常量测试页=()=>{
const[num,setNum]=useState(0);
const numRef=useRef(num);
//将打印更改的值
log(`num:${num}`);
常量计数器=useState(()=>新的MyObject(()=>{
//将始终打印最新的值
log(`from callback.num:${numRef.current}`);
}))[0];
useffect(()=>{numRef.current=num},[num]);
常量btnClick=()=>{
setNum(newdate().getTime());
counter.callback();
};
返回(
测试,num:{num}
单击以更新状态
);
}
useRef
保证
numRef
在多次调用中始终是同一个对象。当
num
的值更改时,
onEffect
调用将更新
numRef.current
值,然后由回调函数访问该值。只有一个回调实例和
numRef
实例存在,以确保正确拾取更改