【问题标题】:How to properly deconstruct an array of arrays using hooks in react如何在反应中使用钩子正确解构数组数组
【发布时间】:2020-04-29 22:18:33
【问题描述】:

我正在尝试将一长串对象(帐户)转换为 6 个或更少的较小数组。我这样做是因为我的 react 组件中有一个表格,其中列出了所有帐户,但是,它不能容纳超过 6 个帐户。我创建了分页和所有内容,并认为它会起作用,但当前页面似乎永远不会更新。

const [pageNum, setPageNum] = useState(1);
const [numOfPages, setNumOfPages] = useState(Math.ceil(accounts.length / 6));
const [page, setPage] = useState([]);
const [pages, setPages] = useState([null]);

const onClick = (e) => {
    setPageNum(pageNum + 1);
    setPage(pages[pageNum]);
};

useEffect(() => {
    if (numOfPages > 1) {
        for (let i = 0; i < 6; i++) {
            setPages(pages.push(accounts.slice(i * 6, i * 6 + 6)));
        }
    }
    console.log(pages[1][1]);
    console.log(pages[2][2]);
    setPage([pages[1][1], pages[1][2]]);
    console.log(page);
}, []);

这不是最终代码,而是我故障排除的一部分,我也认为问题出在哪里。当我控制台日志页面[1][1] 和页面[1][2] 时,我得到两个单独的对象。那么在使用 setPage 并将两个“对象”放在一个数组中之后,页面的控制台日志会以空数组的形式出现吗?我试过重构很多东西。我已经将页面更改为对象而不是数组,我尝试过用另一种方法而不是 useEffect 来做,各种各样的事情。但问题的根源似乎是我的“setPage”和“setPageNum”方法常常无缘无故地失败。

【问题讨论】:

    标签: javascript arrays reactjs react-hooks


    【解决方案1】:

    useMemo 准备 pages 数组(它只会在accounts 改变时改变)。

    const { useState, useMemo, useCallback } = React;
    
    const Pager = ({ accounts }) => {
      const [pageNum, setPageNum] = useState(0);
    
      const pages = useMemo(() => {
        const pages = [];
    
        for (let i = 0; i < accounts.length; i += 6) {
          pages.push(accounts.slice(i, i + 6));
        }
    
        return pages;
      }, [accounts]);
      
      // console.log(pages);
    
      const numOfPages = pages.length;
    
      const page = pages[pageNum];
    
      const next = useCallback(() => {
        setPageNum(pageNum => pageNum + 1);
      }, []);
      
      const prev = useCallback(() => {
        setPageNum(pageNum => pageNum - 1);
      }, []);
      
      return (
        <div>
          <button disabled={pageNum === 0} onClick={prev}>Prev</button>
          <button disabled={pageNum === numOfPages - 1} onClick={next}>Next</button>
          <ul>
            {pages[pageNum].map((s, i) => <li key={i}>{s}</li>)}
          </ul>
        </div>
      );
    };
    
    const accounts = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
    
    ReactDOM.render(
      <Pager accounts={accounts} />,
      root
    )
    <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
    
    <div id="root"></div>

    你代码中的主要问题是你使用setPages的方式:

    setPages(pages.push(accounts.slice(i * 6, i * 6 + 6)));
    

    Array.push() 返回数组的新长度。所以你的pages 状态实际上是最后一个数字。这是最后一个数字,因为setState 替换了状态,并且没有添加它。

    【讨论】:

    • 那我该如何设置页面呢?我尝试使用这种变体,但它仍然不允许我设置页面。 const [page, setPage] = useState(pages[1]); console.log(page); console.log(pages);这种情况下page的控制台日志还是一个空数组
    • 不需要设置页面。该页面来源于pagespageNumpage = pages[pageNum];
    • 你实际上可以做到。您正在映射一个数组,因为 pages[0] 是一个数组。你的问题是你的初始页面是1。只需将初始状态更改为0即可。
    • 您还需要处理页面不存在(没有项目)的情况
    • 我已经更新了一个工作示例 - 错误出现在这一行 pages.push(accounts.slice(i, i + 6));。我将 i 增加了 6,但保留了原来的切片 i * 6, i * 6 + 6
    【解决方案2】:

    您要查找的术语是chunk。 由于您要分块的数据来自道具,因此您不需要 useEffect 挂钩中的分块。这不是副作用。

    这是我在网上找到的一个chunk函数:

    function chunkArray(myArray, chunk_size){
        var index = 0;
        var arrayLength = myArray.length;
        var tempArray = [];
    
        for (index = 0; index < arrayLength; index += chunk_size) {
            myChunk = myArray.slice(index, index+chunk_size);
            // Do something if you want with the group
            tempArray.push(myChunk);
        }
    
        return tempArray;
    }
    

    【讨论】:

      猜你喜欢
      • 2020-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-19
      • 2021-06-22
      • 1970-01-01
      相关资源
      最近更新 更多