I have a class instance in my react state and it's like below:
class Room {
name;
participant;
constructor(name) {
this.name = name;
this.participant = {
screensharing: false,
};
}
sendReinvite() {
console.log("reinvite");
}
}
after changing screen share and using the spread operator for mutating state, sendReinvite method is deleted and causes an error in the second click:
const SpreadOperator = () => {
const [room, changeRoom] = useState(new Room());
const toggleScreenSharing = () => {
console.log("room", room);
room.participant.screensharing = !room.participant.screensharing;
room.sendReinvite();
changeRoom({...room});
};
return (
<div>
<h1>spread operator</h1>
<button onClick={toggleScreenSharing}>Screen share</button>
</div>
);
};
export default SpreadOperator;
error: Uncaught TypeError: room.sendReinvite is not a function how can I change screen share without losing methods, by the way, that instance comes from some library and I can't change that,
check this like for a real one:
CodePudding user response:
Do not use spread operator in class instances
Check this link to see Why can I not use the spread operator on a class function?
Consider the following snippet:
class A {
constructor() {
this.a = 'a', this.b = 'b'
}
mymethod() {
return true
}
}
If you do:
const a = new A();
a.mymethod(); // true
And if you use spread operator in it:
const a = new A();
const b = { ...a };
b.mymethod(); // b.mymethod is not a function
b.a; // 'a'
Do not modify your state directly
Again, Why can't I directly modify a component's state, really?
You do it in:
room.participant.screensharing = !room.participant.screensharing;
So, replace:
room.participant.screensharing = !room.participant.screensharing;
room.sendReinvite();
changeRoom({...room});
with:
const myNewRoomState = new Room(); // Create another state object
myNewRoomState.participant.screensharing = !room.participant.screensharing;
myNewRoomState.sendReinvite();
changeRoom(myNewRoomState);
This is still doubtful because you are using a mutable class instance to store your immutable state, I recommend you to check this post: Is there a react way to store a mutable class instance objects in state?
But in summary:
- Avoid spread operator in class instances.
- Do not modify your state directly, change it's properties through
changeRoom
function (which is the function responsible for changing your room state).
CodePudding user response:
Alex did a good job answering this, but I want to add something to help you understand more.
sendReinvite
exist in Room.prototype
and doing {...rom}
wont clone the prototype.