I am trying to mark a targeted todo as done, but instead when i press and todo as done, all the list are marked done which im trying to figure it out why, can anyone explain to me what im doing wrong ? I’m still a beginner and try to understand such behaviors.
The function handleDoneTask was suppose to run for each todo and when i press done it should be mark that specific todo in a list as done task
import { useState } from "react";
import "./App.scss";
function App() {
//Value of Input
const [val, setVal] = useState("");
const [todos, setTodos] = useState([]);
const [doneTask, setDoneTast] = useState(false);
const addTodos = (e) => {
if (val == "") return;
e.preventDefault();
setTodos([...todos, val]);
setVal("");
};
const handleDelete = (id) => {
setTodos(todos.filter((_, key) => key !== id));
};
const handleDoneTask = (id) => {
const DoneArray = [...todos];
DoneArray.map((_, key) => {
if (id === key) {
setDoneTast(true);
}
});
};
return (
<div className="App">
{/** On change values*/}
<form onSubmit={addTodos}>
<input
onChange={(e) => setVal(e.target.value)}
value={val}
type="text"
/>
<button type="submit">Add</button>
</form>
<ul>
{todos.map((todo, key) => (
<div className="arrange" key={key}>
<li className={doneTask ? "doneTask" : null}>{todo}</li>
<a onClick={() => handleDoneTask(key)}>Done</a>
<a onClick={() => handleDelete(key)}>Cancel</a>
</div>
))}
</ul>
</div>
);
}
export default App;
//css
.doneTask {
text-decoration: line-through!important;
}
3
Answers
Because all your tasks depend on one state
doneTask
which will betrue/false
for all tasks.A solution you split the task element in it’s own component and move the state to the task component.
You can create a separate component to represent a
Todo
which maintains its own state.Note that
<div>
is not valid as a direct child of an unordered list. You can, however, put it inside a list item.If you maintain an array of objects each with their own
id
,text
, anddone
status you’ll find it much easier to maintain your state. Adding theid
to each list item as a data attributes means that you can manipulate the todo objects in state more easily.In addition if you split up your code into separate components you can have your
Form
component responsible for the state of the input element, and just haveTodo
as a dumb component that just accepts and displays data.