'How to persist an object that is passed by reference in React?
I'm working on this task where I need to do the following: I have this object passed by reference from 4 components
const initialStateSubjects = {
"1":{
"name": "math",
"selected": true}
"2":{
"name": "English",
"selected": true}
}
const Subjects = {
"1":{
"name": "math",
"selected": false}
"2":{
"name": "English",
"selected": true}
}
const [initialState, setInitialState] = useState(initialStateSubjects)
const [changedState, setChangedState] = useState(initialStateSubjects)
//this is the way I'm filtering but it's not working because it's comparing two identical objects
const changedSubjects = Object.keys(changedState)
.filter(key => initialState[key]?.selected !== changedState[key]?.selected
.map(key => console.log(initialState[key]?.name))
As you can see they both need to have the same object passed which is initialStateSubjects
Most of the logic is done with the changedState, and I only set the initial one once in the useEffect, but regardless, both the initialState & changedState gets changed at the same time. I want to use the initial value of Initial state to compare the difference and return the name of the subjects that selected values changed. I have tried doing in this in the console and it works brilliantly but when doing in React I am stuck with this. I have tried spread operator to make a shallow copy of it, and used a library to make a deep clone of it but it still mutates the initial object. If you do think of a different way to compare initial state without creating another state that would also work for me because all I want is to return the ones that changed upon clicking a button from their original initial state. Thanks so much in advance!
Solution 1:[1]
Not sure about what the exact requirement is since you cannot provide the entire code. But here is a working implementation for a simple dropdown that might help you. If you require a copy of the initial state only for comparison, then in that case you do not actually need to maintain 2 copies. A single state implementation can be used here.
import React from "react";
const initialStateSubjects = {
"1": {
name: "Math",
selected: false
},
"2": {
name: "English",
selected: false
}
};
export default function App() {
const [initialState, setInitialState] = React.useState(initialStateSubjects);
const handleChange = (e) => {
setInitialState((prevState) => {
return Object.values(prevState).map((val) => {
val.name === e.target.value
? (val.selected = true)
: (val.selected = false);
return val;
});
});
console.log(initialState);
};
return (
<div>
<select onChange={handleChange}>
{Object.keys(initialState).map((sub) => (
<option key={sub}>{initialState[sub].name}</option>
))}
</select>
</div>
);
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
