[英]Can't persist checkstate in reactjs and nodejs
这将是我第一次这样做,我似乎无法找到解决办法。 我想在 react.js 中保留复选框 state 并希望在没有我的 MongoDB 数据库的情况下完成此操作。 到目前为止,这是我的代码:我正在从我的 MongoDB 数据库中获取订阅者列表,如下所示:
const [allSubscribers, setAllSubscribers] = useState([]);
const response = await axiosPrivate.get(`${BASE_URL}/emailsub/subscribers?page=${pageNumber})
setAllSubscribers(response.data)
每页显示 9 个订阅者。 在下一页,调用了新的 API 并列出了另外 9 个订阅者,直到最后一组项目。 这就是我通过查询处理分页的方式。
要创建输入复选框,我必须根据从数据库中获取的订阅者的大小创建另一个数组。
const [checkedState, setCheckedState] = useState();
const totalPosts = allSubscribers.length // to get the length of the items fetched from database
const fillArray = new Array(totalPosts).fill( false)//created new array and fill it with initial value of `false`
//useEffecct to set the check state whenever the all subscriber state changes
useEffect(()=>{
setCheckedState(fillArray)
}, [allSubscribers])
单击复选框时,它返回与匹配项的值相反的值。 并且订阅者 ID 被传递到一个名为const [selectedSubscriberId, setSelectedSubscriberId] = useState([]);
的 state 数组中。
const arrayOfSelectedPostId = (subscriberId, indexPosition) =>{
setSelectedSubscriberId(prevArray => [...prevArray, subscriberId]);
const updatedCheckedState = checkedState.map((item, index) =>
index == indexPosition ? !item : item
)
setCheckedState(updatedCheckedState);
}
取消选中时,我从selectedSubscriberId
数组中删除了匹配的subscriberId。
//handle deselecting of a selected postid
const handleChangeState = (subscriberId)=>{
selectedSubscriberId.map((item)=>{
console.log(item === subscriberId)
if(item === subscriberId){
const newArray = selectedSubscriberId.filter((item) => item !==subscriberId)
setSelectedSubscriberId(newArray);
}
})
};
这是复选框输入:
<input type="checkbox" id={index} checked={checkedState[index]} onChange={()=>{arrayOfSelectedPostId(subscriberId, index); handleChangeState(subscriberId)}}/>
在页面加载或刷新时,我想检查selectedSubscriberId
数组,并且在那里找到的任何订阅者 id 都应该保持选中状态。 有没有办法我可以处理这个? 如果可能的话,我不介意重新编写代码。
我认为您使您的 state 有点过于复杂了。 您可以使用仅包含已检查项目的 id(例如)的 1 个数组来实现复选框 state 处理。 还有 2 个实用函数,1 个检查项目是否被检查,1 个实际从这个 id 数组中添加或删除项目。
接下来 - 你需要 2 个 useEffects。 一个 useEffect 将在第一个组件渲染时从 localstorage 加载检查的 ids 数组,第二个将在更新 ids 数组时更新 localstorage。
import { useState, useEffect, useCallback } from "react";
const DATA = [
{ id: 1, name: "sub1" },
{ id: 2, name: "sub2" },
{ id: 3, name: "sub3" },
{ id: 4, name: "sub4" },
{ id: 5, name: "sub5" }
];
const CHECKED_SUBSCRIBERS_IDS_KEY = "checked_subscribers_ids";
const ITEMS_PER_PAGE = 2;
export default function App() {
const [allSubscribers, setAllSubscribers] = useState([]);
const [page, setPage] = useState(0);
// initial state for it is "undefined"!
const [checkedSubscribersIds, setCheckedSubscribersIds] = useState();
// initial load of checked items from localstorage
useEffect(() => {
const json = localStorage.getItem(CHECKED_SUBSCRIBERS_IDS_KEY);
setCheckedSubscribersIds(json ? JSON.parse(json) : []);
}, []);
// update localstorage on checked items changed.
useEffect(() => {
// initial load needs to be ignored
if (!checkedSubscribersIds) return;
const json = JSON.stringify(checkedSubscribersIds);
localStorage.setItem(CHECKED_SUBSCRIBERS_IDS_KEY, json);
}, [checkedSubscribersIds]);
// dummy data set and pagination, ignore
useEffect(() => {
const items = [...DATA].slice(
page * ITEMS_PER_PAGE,
page * ITEMS_PER_PAGE + ITEMS_PER_PAGE
);
setAllSubscribers(items);
}, [page]);
const isChecked = useCallback(
(item) => {
if (!checkedSubscribersIds) return false;
return checkedSubscribersIds.includes(item.id);
},
[checkedSubscribersIds]
);
const handleCheckedClick = useCallback(
(item) => {
const idx = checkedSubscribersIds.findIndex((x) => x === item.id);
if (idx >= 0) {
checkedSubscribersIds.splice(idx, 1);
} else {
checkedSubscribersIds.push(item.id);
}
setCheckedSubscribersIds([...checkedSubscribersIds]);
},
[checkedSubscribersIds]
);
// ignore
const onPrevPageClick = () => {
setPage(page <= 0 ? 0 : page - 1);
};
// ignore
const onNextPageClick = () => {
setPage(page + 1 >= DATA.length / ITEMS_PER_PAGE ? page : page + 1);
};
return (
<div className="App">
<table>
<thead>
<tr>
<th>Checked</th>
<th>Id</th>
<th>Name</th>
</tr>
</thead>
<tbody>
{allSubscribers.map((x) => (
<tr key={x.id}>
<td>
<input
type="checkbox"
checked={isChecked(x)}
onChange={() => handleCheckedClick(x)}
/>
</td>
<td>{x.id}</td>
<td>{x.name}</td>
</tr>
))}
</tbody>
</table>
<button type="button" onClick={onPrevPageClick}>
Previous
</button>
<button type="button" onClick={onNextPageClick}>
Next
</button>
</div>
);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.