How to update property state without using this
I'm updating one of my state properties without using the setter and using a normal variable assignment in js, that causes me the problem that the property state only updates once, so when i want to check a checkbox more than once the state in app does not update correctly, i think that the problem causing it is that i'm messing up that property assignment.
I searched for how to update a property of a state without overwritting the whole object and every post i find answering that question is using this.setState instead of declaring a state and using the declared setter method and i don't know how to adapt that this update to my code.
For example, the top post called "How to update nested state properties in React" declares his state like this:
this.state = {
someProperty: {
flag:true
}
}
While i'm declaring my state like this:
const [EditedTask, setEditedTask] = useState({
name: props.task.name,
completed: props.task.completed,
_id: props.task._id,
});
const { name, completed } = EditedTask;
And the top answer to that question is:
this.setState(prevState => ({
...prevState,
someProperty: {
...prevState.someProperty,
someOtherProperty: {
...prevState.someProperty.someOtherProperty,
anotherProperty: {
...prevState.someProperty.someOtherProperty.anotherProperty,
flag: false
}
}
}
}))
In this solution, with which object should i replace the this in the this.setState? Or the prevState param?
In my code i need to update the checkbox/ completed state, with this solution i'm only receiving the object EditedTask in my app component when i edit the checkbox once, if i check it more than once the state doesn't update in app, meanwhile if i edit the name the state updates in app correctly with both the name and completed propertys.
import React, { useState } from "react";
import "../App.css";
const EditTask = (props) => {
const [EditedTask, setEditedTask] = useState({
name: props.task.name,
completed: props.task.completed,
_id: props.task._id,
});
const { name, completed } = EditedTask;
const onChange = (e) => {
setEditedTask({
...EditedTask,
[e.target.name]: e.target.value,
});
};
const onSubmit = (e) => {
e.preventDefault();
setEditedTask(EditedTask);
props.saveEditedTask(EditedTask);
props.changeEdit(false);
};
return (
<>
<form onSubmit={onSubmit}>
<div className="form-group">
<label>Task Id: ${props.task._id}</label>
<div className="inputEdit">
<input
type="text"
placeholder={props.msg}
name="name"
onChange={onChange}
value={name}
/>
</div>
</div>
<div className="form-check">
<input
className="form-check-input"
type="checkbox"
defaultChecked={completed}
value={completed}
onChange={() => (EditedTask.completed = !EditedTask.completed)}
name="completed"
/>
<label className="form-check-label">Completed</label>
</div>
<div className="submit">
<button type="submit">Edit</button>
</div>
</form>
</>
);
};
export default EditTask;
I tried replacing the onChange={() => (EditedTask.completed = !EditedTask.completed)}
like the top answer/ my onChange for the name value with something like this but it doesn't update the completed value
const updateCompleted = (e) => {
setEditedTask({
...EditedTask,
[e.target.name]: !e.target.value,
});
};
Solution 1:
You can try something like this in your setter functions.
const updateCompleted = (e) => {
setEditedTask((currentState) => ({
...currentState,
[e.target.name]: !e.target.value
})
)};
This solution will give you your previous state, which your can use to update your state.