Reputation: 163
Making a small todo app, I want to add the functionality that when the task is checked, the checked task goes into an array. On first click the task consoles an empty array, then when unchecked and checked again, my array gets updated. Any reason as to why it takes two click for array to update?
function SelectTodo({ todo }) {
const [checkboxChecked, setCheckboxChecked] = React.useState([]);
const handleInputChange = (e) => {
const checked = e.target.checked;
let value = e.target.value;
if (checked) {
setCheckboxChecked((prevChecked) => [...prevChecked, value]);
console.log("checkBoxArrray:" + checkboxChecked);
} else {
console.log("unchecked");
}
};
return (
<label className="todo-list__label">
<div className="form-check form-check-inline">
<input
className="form-check-input"
type="checkbox"
name="task"
id="inlineCheckboxh1"
value={todo}
onChange={handleInputChange}
/>
<label className="form-check-label" htmlFor="inlineCheckboxh1">
{todo}
</label>
</div>
</label>
);
}
ReactDOM.render(<SelectTodo todo={5} />, document.getElementById("root"));
<div id="root" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
Upvotes: 0
Views: 1580
Reputation: 47
Check following solution , there is some condition for adding data you can skip , from this you can get instant updated array
const [updated_chat, setUpdatedChat] = useState([]);
const [messages_array, setMessagesArray] = useState([]);
if (onMessage && userData?.user != text["userId"]) {
if (updated_chat) {
updated_chat.push(text);
setMessagesArray(prevChecked => [...prevChecked, text]);
}
}
console.log(messages_array);
Upvotes: 0
Reputation: 4266
You can't access the updated state from the current state. See useState set method not reflecting change immediately for more info.
What you can do is trigger an effect when a state variable gets updated and print your updated array there:
React.useEffect(() => {
console.log("checkBoxArrray:" + checkboxChecked);
}, [checkboxChecked]);
The solution proposed by Nisanth Reddy also works.
Fully working example:
function SelectTodo({ todo }) {
const [checkboxChecked, setCheckboxChecked] = React.useState([]);
const handleInputChange = (e) => {
const checked = e.target.checked;
let value = e.target.value;
if (checked) {
setCheckboxChecked((prevChecked) => [...prevChecked, value]);
} else {
console.log("unchecked");
}
};
React.useEffect(() => {
console.log("checkBoxArrray:" + checkboxChecked);
}, [checkboxChecked]);
return (
<label className="todo-list__label">
<div className="form-check form-check-inline">
<input
className="form-check-input"
type="checkbox"
name="task"
id="inlineCheckboxh1"
value={todo}
onChange={handleInputChange}
/>
<label className="form-check-label" htmlFor="inlineCheckboxh1">
{todo}
</label>
</div>
</label>
);
}
ReactDOM.render(<SelectTodo todo={5} />, document.getElementById("root"));
<div id="root" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
Upvotes: 1
Reputation: 6405
Setting state is as async
process in React.
This means, calling setCheckboxChecked
and the immediately trying to read the value of checkboxChecked
is going to give you the current value and not the update value.
This means that the array is actually getting updated, but you are only logging the old value, so it seems like it is taking two clicks.
If you want to check the updated value, do this.
setCheckboxChecked((prevChecked) => {
const updated = [...prevChecked, value];
console.log(updated);
return updated;
});
Upvotes: 1