簡體   English   中英

無法在 reactjs 和 nodejs 中保留檢查狀態

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM