Reputation: 37
The following component is meant to be a To-Do list. I got multiple checkboxes. As soon as all checkboxes are checked, a console.log("all checked")
should appear.
My idea is to check if the todo.lengh === checked.length
, but it doesn't work.
Problem: trying to console.log(checked.length)
doesn't work either so there must be the problem.
Can someone help me how to reach the checked.length?
import React from 'react';
import { AiOutlinePlusCircle } from 'react-icons/ai';
import { useState } from 'react';
function Checkboxes() {
const [todo, setToDo] = React.useState('');
const [todos, setToDos] = React.useState([]);
const [checked, setChecked] = useState(false);
function handleToDoSubmit(e) {
e.preventDefault();
const newToDo = {
id: new Date().getTime(),
text: todo,
completed: false,
};
setToDos([...todos].concat(newToDo));
setToDo('');
}
function toggleCompleteToDo(id) {
const updatedToDos = [...todos].map((todo) => {
if (todo.id === id) {
todo.completed = !todo.completed;
}
return todo;
});
setToDos(updatedToDos);
}
function allChecked(checked) {
if (todo.length === checked.length) {
console.log('all checked');
}
}
return (
<div className="ToDoList">
<form className="goalInputToDo" onSubmit={handleToDoSubmit}>
<input
className="goalInput"
type="text"
onChange={(e) => setToDo(e.target.value)}
value={todo}
/>
<button className="AddGoalBtn" type="submit">
.
<AiOutlinePlusCircle size="2em" />
</button>
</form>
{todos.map((todo) => (
<div className="goalItem">
<div key={todo.id}>
<div>{todo.text}</div>
<input
type="checkbox"
onChange={() => {
toggleCompleteToDo(todo.id), allChecked(todo.checked);
}}
checked={todo.completed}
/>
</div>
</div>
))}
</div>
);
}
export default Checkboxes;
Upvotes: 1
Views: 2751
Reputation: 23161
todo
is a string, checked
is a boolean, so I'm not sure how you wanted to use them to check if all the checkboxes are checked. What you could do instead is to check your todos
array and check if every single item's completed
prop is true
.
You can use Array#every()
to do this. It tests whether all elements in the array pass the test implemented by the provided function:
function allChecked() {
return todos.every(item => item.completed)
}
function App() {
const [todo, setToDo] = React.useState('');
const [todos, setToDos] = React.useState([{
id: new Date().getTime(),
text: 'First item',
completed: false,
}]);
function handleToDoSubmit(e) {
e.preventDefault();
const newToDo = {
id: new Date().getTime(),
text: todo,
completed: false,
};
setToDos(todos.concat(newToDo));
setToDo('');
}
function toggleCompleteToDo(id) {
const updatedToDos = todos.map((item) => {
if (item.id === id) {
item.completed = !item.completed;
}
return item;
});
setToDos(updatedToDos);
}
function allChecked() {
if (!todos.length) return false;
return todos.every((item) => item.completed);
}
return (
<div className="ToDoList">
<form className="goalInputToDo" onSubmit={handleToDoSubmit}>
<input
className="goalInput"
type="text"
onChange={(e) => setToDo(e.target.value)}
value={todo}
/>
<button className="AddGoalBtn" type="submit">
Add
</button>
</form>
{todos.map((item) => (
<div className="goalItem">
<div key={item.id}>
<input
type="checkbox"
onChange={() => {
toggleCompleteToDo(item.id), allChecked(item.checked);
}}
checked={item.completed}
/>
<span>{item.text}</span>
</div>
</div>
))}
<p>All checked: {allChecked() ? 'Yes' : 'No'}</p>
</div>
);
}
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
<div id="root"></div>
<script src="https://unpkg.com/react/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom/umd/react-dom.production.min.js"></script>
Upvotes: 1