繁体   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