[英]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.