I'm learning React for only a few days now. I'm making a Todo app and I would like to add the following feature: when I mark a task as done
, it should move to bottom. If I make the same task as undone
then it should maintain its original position.
My code starting from the App structure:
import './App.css';
import Header from './components/Header';
import List from './components/List';
function App() {
return (
<div className="Todo App">
<Header />
<List />
</div>
);
}
export default App;
const Header = () => {
return (
<h1>My Todo App</h1>
);
};
export default Header;
import Item from './Item';
import './AllComponents.css'
function List({ }) {
const [value, setValue] = useState("");
const [todos, setTodos] = useState([]);
const handleSubmit = e => {
e.preventDefault();
if (!value) return;
addTodo(value);
setValue("");
};
const addTodo = text => {
const newTodos = [...todos, { text }];
setTodos(newTodos);
};
const markTodo = index => {
const newTodos = [...todos];
newTodos[index].isDone = !newTodos[index].isDone;
setTodos(newTodos);
};
const removeTodo = index => {
const newTodos = [...todos];
newTodos.splice(index, 1);
setTodos(newTodos);
};
return (
<div className="container">
<form onSubmit={handleSubmit}>
<input
type="text"
value={value}
placeholder="Add an item"
onChange={e => setValue(e.target.value)} />
<button type="submit">Add</button>
</form>
<li className="li-items">
{todos.map((todo, index) => (
<Item
key={index}
index={index}
todo={todo}
markTodo={markTodo}
removeTodo={removeTodo}
/>
))}
</li>
</div>
)
};
export default List;
import React from "react";
const Item = ({ todo, index, markTodo, removeTodo }) => {
return (
<div className="full-element">
<span className="todo-item" style={{ textDecoration: todo.isDone ? "line-through" : "" }}>{todo.text}</span>
<div className="buttons">
<button onClick={() => markTodo(index)}>✓</button>{' '}
<button onClick={() => removeTodo(index)}>✕</button>{' '}
</div>
</div>
)
};
export default Item;
My App looks like this now:
Can someone with more experience please take a look and point me in the right direction? Thank you
CodePudding user response:
Display two lists, one not done and one done, one after another
{todos.filter(todo => !todo.isDone).map((todo, index) => (
<Item
key={index}
index={index}
todo={todo}
markTodo={markTodo}
removeTodo={removeTodo}
/>
))}
{todos.filter(todo => todo.isDone).map((todo, index) => (
<Item
key={index}
index={index}
todo={todo}
markTodo={markTodo}
removeTodo={removeTodo}
/>
))}
P.S.
<li>
is list item, not list, you should use <ul>
and each item should be <li>
P.S. 2
index
isn't a good key