Reputation: 1030
I have a singleton class in 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());
}
}
Then in a separate file, Timefeedback.tsx
, I have:
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>
);
};
What I expect to happen:
What actually happens:
updateTime
is successfully called, and the console log prints the correct values. But the setState function updateTime()
What happens is I get console logs from TimeFeedback.tsx
with the expected value of tString
printed out. But the setState function setSimTime
never gets called, so the text in the div remains "starting time". Why is this?I have investigated, when calling print events inside of Daemon I get:
function() {
[native code]
}
I tried to remove the .bind(this)
inside TimeFeedback.tsx
, but nothing changes except the print instead says:
tString => {
setSimTime(tString);
console.log(`update time called, val: ${tString}`);
}
I also walked through with the debugger and updateSimTime
does get called but it has no effect.
Why is that updateSimTime
has no effect?
Upvotes: 1
Views: 859
Reputation: 42170
.bind
in the componentupdateTime.bind(this)
doesn't make sense in a function component because a function component doesn't have a this
like a class component does. Your updateTime
function can be passed directly to the Daemon.getInstance
function.
You also need to remove the this.data = data
in the Daemon
constructor because there is no data
variable` (as pointed out by @Konrad in the comments).
As a best practice, I would recommend moving the code into a useEffect
hook.
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>;
};
Upvotes: 2