I have a component in React with two states using useState. The first one is used to Save the current Object from a form and the other one is used to store all objects by id. To make the code simpler here it is just an array of objects, which also has the same bug.
export default function () {
const [a, setA] = useState({ hello: "world" });
const [b, setB] = useState([]);
const Submit = () => {
const newB = b;
newB.push(a);
setB(newB);
console.log(b);
};
return (
<>
<input
type="text"
onChange={(event) => {
setA(Object.assign(a, { hello: event.target.value }));
}}
/>
<button onClick={() => Submit()}>Submit</button>
</>
);
}
When You submit one first and change the input and then submit again the first object also changes while it is not being altered by this code.
If you change the object in state a to only be a string it works correctly, however in my project I need it to be an object because it has multiple keys.
3
Answers
If your aim is to append a value to the array, you could use the spread operator to set the new value
So you could instead write the Submit function as
...
is known as the spread operator and it opens up the array or object associated with it.For example if you have an array
B = [{A}, {B}, {C}]
then
...B = {A}, {B}, {C}
and[...B, {D}] = [{A}, {B}, {C}, {D}]
You could learn more about it here
Hope this helps!
One way you could copy a object is using the spread operator (…). This will set
b
to a new array with all the other values ofb
and adda
.For you
onChange
you can use the same logic. You also might want to add avalue
prop to the input since it currently is no a controlled input.If really want to use
Object.assign
you can use it like this. Here you assign a new object{}
to also a new object with ahello
property.setState
is asynchronous function, you shouldn’tconsole.log
your state just aftersetState
is called. You copy your array wrong, you need to use spread operator for that. Also your input is not controlled, which means your value is not sync with what is typed in input. Here what I think that should be done: