【发布时间】:2022-01-24 04:21:06
【问题描述】:
我从 API 获取数据并从前端更改值以将其显示在表格中。我获取对象列表并将其存储在一个状态中并在 html 表中显示该状态下的对象。该表有一个复选框来显示一个布尔值。如果该值为 true,则复选框中的 defaultChecked 为 true。表格标题中有一个复选框可以选中或取消选中所有项目。
以下是我获取的json对象。
{
completed: false
id: 1
title: "delectus aut autem"
userId: 1
}
如果我选中表头中的复选框,我想在所有 200 个项目中将 completed 设置为 true。
以下是设置所有项目为真或假的代码。
const checkAllHandler = (e) => {
let val = e.target.checked;
console.log(val);
let allTodoList = [];
if (val === true) {
if (todo.length > 0) {
for (let index = 0; index < todo.length; index++) {
const newObject = {
userId: todo[index].userId,
id: todo[index].id,
title: todo[index].title,
completed: true,
};
allTodoList.push(newObject);
}
setTodo(allTodoList);
}
} else if (val === false) {
if (todo.length > 0) {
for (let index = 0; index < todo.length; index++) {
const newObject = {
userId: todo[index].userId,
id: todo[index].id,
title: todo[index].title,
completed: false,
};
allTodoList.push(newObject);
}
setTodo(allTodoList);
}
}
};
当我控制todo 状态时,所有值都会更新为真或假,但它不会显示在表格上。
该表具有过滤功能。如果我过滤一个单词并返回,那么整个表的值都会发生变化。我想在单击复选框时显示更改,而不是在搜索和返回时显示更改。我该怎么做?
组件的完整代码如下。
const DataTable = () => {
const { loading, items } = useSelector((state) => state.allData);
// console.log(items)
const dispatch = useDispatch();
// const history = useNavigate();
const [searchText, setsearchText] = useState("");
const [todo, setTodo] = useState(items);
console.log("todo");
console.log(todo);
const [isFetch, setisFetch] = useState(false);
const [checkedloading, setcheckedLoading] = useState(false);
const [isChecked, setisChecked] = useState(false);
console.log(isChecked);
useEffect(() => {
const setDataToState = () => {
if (loading === false) {
setTodo(items);
}
};
setDataToState();
}, [loading]);
useEffect(() => {
dispatch(getData());
// setTodo(items)
// console.log(items)
}, [dispatch]);
//etTodo(items)
const handleSearch = (event) => {
//let value = event.target.value.toLowerCase();
setsearchText(event.target.value);
};
const onChangeHandler = (e, item) => {
console.log(e.target.checked);
console.log(item);
if (e.target.checked === true) {
// const item = todo.filter(x=> x.id === id)
// console.log("added")
// console.log(item)
for (let index = 0; index < todo.length; index++) {
if (todo[index].id === item.id) {
console.log(todo[index]);
console.log("deleting");
todo.splice(index, 1);
console.log("deleted");
const newObject = {
userId: item.userId,
id: item.id,
title: item.title,
completed: true,
};
console.log("adding updated object");
todo.splice(index, 0, newObject);
console.log("added");
console.log(todo);
}
}
} else {
// const item = todo.filter(x=> x.id === id)
// console.log("removed")
// console.log(item)
for (let index = 0; index < todo.length; index++) {
if (todo[index].id === item.id) {
console.log(todo[index]);
console.log("deleting");
todo.splice(index, 1);
console.log("deleted");
const newObject = {
userId: item.userId,
id: item.id,
title: item.title,
completed: false,
};
console.log("adding updated object");
todo.splice(index, 0, newObject);
console.log("added");
console.log(todo);
}
}
}
};
const onSubmitHandler = () => {
localStorage.setItem("items", JSON.stringify(todo));
};
const getItem = () => {
const items = localStorage.getItem("items");
console.log("local storage items");
console.log(JSON.parse(items));
};
const checkAllHandler = async (e) => {
const { checked } = e.target;
console.log(checked);
setTodo((todos) =>
todos.map((todo) => ({
...todo,
completed: checked,
}))
);
};
return (
<>
{console.log("todo in render")}
{console.log(todo)}
<div className={styles.container}>
<div className={styles.top}>
<div className={styles.search_bar}>
<input
type="text"
onChange={(e) => handleSearch(e)}
placeholder="search by name"
/>
</div>
</div>
<div className={styles.btn_container}>
<button onClick={onSubmitHandler}>Submit</button>
</div>
<div className={styles.data_table_container}>
{checkedloading === false ? (
<>
<div className={styles.data_table}>
{loading || todo === null || todo === undefined ? (
<>
<p>Loading!!</p>
</>
) : (
<>
<table>
<tr>
<th>ID</th>
<th>userId</th>
<th>Title</th>
<th>
<>
Completed
<input type="checkbox" onChange={checkAllHandler} />
</>
</th>
</tr>
<tbody>
{todo
.filter((val) => {
if (searchText === "") {
return val;
} else if (
val.title.toLowerCase().includes(searchText)
) {
return val;
}
})
.map((item) => (
<>
<tr key={item.id}>
<td>{item.id}</td>
<td>{item.userId}</td>
<td>{item.title}</td>
<td>
<input
type="checkbox"
defaultChecked={item.completed}
onClick={(e) => onChangeHandler(e, item)}
/>
</td>
</tr>
</>
))}
</tbody>
</table>
</>
)}
</div>
</>
) : (
<>Loading</>
)}
</div>
</div>
</>
);
};
代码沙盒链接:https://codesandbox.io/s/flamboyant-proskuriakova-60t19
【问题讨论】:
-
代码似乎没问题。该问题可能导致其他地方。代码也有点冗长。您可以使用 map 重构代码,例如 setTodo(todo.map(e=>({...e, completed: val})))
标签: javascript html reactjs react-hooks use-state