I have simplified my issue in a code-sandbox for ease of a demo. Think of this counter class as a more complex external Lib.
Explanation
I have a Class that has a property of a count and method that will increment that count.
interface Counter {
count: number;
increment(): void;
autoIncrement(): void;
}
export class MyCounter implements Counter {
public count: number;
constructor() {
this.count = 0;
}
public increment() {
this.count = this.count 1;
console.log(this.count);
}
autoIncrement() {
setInterval(() => {
this.count = this.count 1;
}, 1000);
}
}
In a react app I initialise the class and put it in a Memo to prevent unnecessary initialisations of it.
const counter = useMemo(() => {
return new MyCounter();
}, []);
Then I display the count in my React App along with a button to increment it.
I then "observe" the changes of the button click in a useEffect like this:
useEffect(() => {
console.log("counter", counter.count);
}, [counter]);
but clicking the button and incrementing the count does not update in the React component.
Why is that? In my understanding of Hooks it should work but I might be fundamentally miss understanding what is happening here.
I have tried passing the class instance to a Child component and using it as props, still to no avail.
CodePudding user response:
...but clicking the button and incrementing the count does not update in the React component.
Why is that?
Because the value in counter, which is a reference to the Counter object, didn't change; modifying the count property doesn't create a new object. If you want to observe changes to counter.count, that's what should be in the dependency array:
useEffect(() => {
console.log("counter", counter.count);
}, [counter.count]);
// ^^^^^^
(Or you might use [counter, counter.count].)
But, if you're using counter.count when rendering, it should be in state so changes to it cause re-rendering. (And if counter is in state, you need to create a new instance each time you increment the counter, because you can't directly modify state objects.)
CodePudding user response:
React js component re-render only if state changed or props changed here in your case. the counter.count is not a props and not a state so your App.js will not re-render to display the new value of count variable. I didn't get why you use new class to do that you can simply do it with state.
