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

aij0ehis  于 2023-01-08  发布在  React
关注(0)|答案(1)|浏览(176)

我在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()上更新。

实际发生的情况:

  • 回调函数updateTime被成功调用,并且控制台日志打印正确的值。但是setState函数updateTime()发生的是我从TimeFeedback.tsx获得控制台日志,并且打印出期望值tString。但是setState函数setSimTime从未被调用,所以div中的文本仍然是“starting time”。这是为什么?

我已经调查过,当调用Daemon内部的打印事件时,我得到:

function() {
    [native code]
}

我尝试删除TimeFeedback.tsx中的.bind(this),但除了打印内容外没有任何变化:

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

我还使用了调试器,updateSimTime * 确实 * 被调用,但没有任何效果。
为什么updateSimTime没有效果?

qacovj5a

qacovj5a1#

无需在组件中使用.bind

updateTime.bind(this)在函数组件中没有意义,因为函数组件不像类组件那样具有thisupdateTime函数可以直接传递给Daemon.getInstance函数。
您还需要删除Daemon构造函数中的this.data = data,因为没有data变量'(正如注解中@Konrad所指出的)。
作为最佳实践,我建议将代码移到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 Link

相关问题