New to React.
I was trying to update the boolean value 'done' whenever the user clicks on it.
For some reasons, this code doesn't work
var updateTodo = todos;
updateTodo[Number(id)].done = !updateTodo[Number(id)].done;
setTodos(updateTodo);
but this does
var updateTodo = [...todos];
updateTodo[Number(id)].done = !updateTodo[Number(id)].done;
setTodos(updateTodo);
As far as I think todos
and [...todos]
both return the same values i.e. todos array, then why won't the first code snippet work?
Here is working App.tsx
for reference, not working snippet present in the function handleDone
.
import React from "react";
type item = {
itemId: number;
todo: string;
done: boolean;
};
var id = 0;
const App: React.FC = () => {
const [newTodo, setNewTodo] = React.useState<string>("");
const [todos, setTodos] = React.useState<item[]>([]);
const handleChange = (event: any) => {
const { value } = event.target;
setNewTodo(value);
};
const handleSubmit = (event: any) => {
setTodos([...todos, { itemId: id, todo: newTodo, done: false }]);
id++;
setNewTodo("");
event.preventDefault();
};
const handleDone = (item: any) => {
// Not Working
var updateTodo = todos;
updateTodo[Number(id)].done = !updateTodo[Number(id)].done;
setTodos(updateTodo);
// Working Code
// var updateTodo = [...todos];
// updateTodo[Number(id)].done = !updateTodo[Number(id)].done;
// setTodos(updateTodo);
};
return (
<>
<form>
<input onChange={handleChange} value={newTodo} type="text" name="todo" placeholder="Enter Todo" />
<button onClick={handleSubmit}>Add</button>
</form>
<ul>
{todos.map((item, index) => {
return item.done ? (
<li id={`${item.itemId}`} onClick={handleDone} style={{ textDecoration: "line-through" }}>
{item.todo}
</li>
) : (
<li id={`${item.itemId}`} onClick={handleDone} style={{ textDecoration: "none" }}>
{item.todo}
</li>
);
})}
</ul>
</>
);
};
export default App;