如何将 React 回调函数传递给 typescript 对象?

How do you pass a React callback function to a typescript object?

提问人:Null Salad 提问时间:1/7/2023 更新时间:1/7/2023 访问量:406

问:

我有一个单例类Daemon.ts

export default class Daemon {
    
    private static instance : Daemon;
    callback : (tstring : string)=>void;
    t : number;

    constructor (callback: (tstring : string)=>void){
        this.data = data
        this.callback = callback;
        this.t = 0;
        window.setInterval(this.tick.bind(this), 1000)
    }

    public static getInstance(callback: (tstring : string)=>void){
        if(!Daemon.instance){ Daemon.instance = new Daemon(callback);}
        return Daemon.instance;
    }

    tick(){
        this.t = this.t + 1
        this.callback(this.t.toString());
    }

}

然后在一个单独的文件中,我有:Timefeedback.tsx

const TimeFeedback = () => {

    const [time, updateSimTime] = React.useState<string>("starting string");
    
    const updateTime = (tString : string) => {
      updateSimTime(tString);
      console.log(`update time called, val: ${tString}`)
    }

    const daemon = Daemon.getInstance(updateTime.bind(this));
  
    return (
      <div>
        {time}
      </div>
    );
  };

我期望发生的事情:

  • 时间状态在守护进程的每个 tick() 上更新。

实际发生的情况:

  • 成功调用回调函数,控制台日志打印正确的值。但是 setState 函数 updateTime() 发生的情况是,我从中获取控制台日志,其预期值为打印输出。但是 setState 函数永远不会被调用,因此 div 中的文本仍然是“开始时间”。为什么会这样?updateTimeTimeFeedback.tsxtStringsetSimTime

我已经调查过,当在 Daemon 中调用打印事件时,我得到:

function() {
    [native code]
}

我试图去除内部,但除了印刷品之外没有任何变化:.bind(this)TimeFeedback.tsx

tString => {
    setSimTime(tString);
    console.log(`update time called, val: ${tString}`);
  }

我还演练了调试器并确实被调用,但它没有效果。updateSimTime

为什么这没有效果?updateSimTime

reactjs typescript react-hooks 回调

评论

0赞 Konrad 1/7/2023
里面有什么?dataconstructor
0赞 Konrad 1/7/2023
当我删除 codesandbox.io/s/kind-julien-yzkgwj?file=/src/App.tsx 时工作正常this.data = data
0赞 Linda Paiste 1/7/2023
updateTime.bind(this)在函数组件中没有意义,因为函数组件不像类组件那样具有。this
0赞 Null Salad 1/7/2023
啊,这是我正在使用的类的简化版本,粘贴后不小心遗漏了数据字段data
0赞 Null Salad 1/7/2023
@Konrad问题在单独的.ts文件中被复制,如果与它位于同一文件中,它就会正常工作!DaemonDaemonTimeFeedback

答:

2赞 Linda Paiste 1/7/2023 #1

无需在组件中.bind

updateTime.bind(this)在函数组件中没有意义,因为函数组件不像类组件那样具有。您的函数可以直接传递给该函数。thisupdateTimeDaemon.getInstance

您还需要删除构造函数中的 ,因为没有变量“(正如注释中@Konrad指出的那样)。this.data = dataDaemondata

作为最佳实践,我建议将代码移动到钩子中。useEffect

const TimeFeedback = () => {
  const [time, updateSimTime] = useState<string>("starting string");

  useEffect(() => {
    const updateTime = (tString: string) => {
      updateSimTime(tString);
      console.log(`update time called, val: ${tString}`);
    };
  
    Daemon.getInstance(updateTime);
  }, [updateSimTime]);

  return <div>{time}</div>;
};

CodeSandbox 链接