反应中分页功能的重新渲染太多

时间:2021-04-11 13:38:15

标签: reactjs

我正在使用 useContext 和 useReducer 和
jobInfo 每次渲染都会获取数据 useEffect
对于分页,我需要设置本地状态“pageInfo”和
获取数据 jobInfo 的时间很短,所以我不得不
在获取 pageInfo 后设置 jobInfo 的状态。
无论如何,由于pageInfo 的状态renuwal,jobInfo 再次被提取,并导致pageInfo 的setState。 (无限循环)
如何防止无限循环重新渲染?

import React, { useContext, useEffect, useState } from 'react';
import CheckboxFilter from '../components/filters/checkBoxFilter';
import DropdownFilter from '../components/filters/dropDownFilter';
import { JobInfoContext } from '../context/dataStore';
import { Link, useHistory } from 'react-router-dom';
import SearchFilter from '../components/filters/searchFilter';
import { Paginate } from '../utils/paginate';
import Pagination from '../utils/pagination';

const JobList = () => {
  const { jobInfo, loading } = useContext(JobInfoContext);
  console.log(jobInfo);
  const history = useHistory();
  const [pageInfo, setPageInfo] = useState({
    pageSize: 0,
    currentPage: 0,
  });

  // let pageSize;
  // let currentPage;
  let count;
  let infoForPaging;
  if (!loading && jobInfo) {
    setPageInfo({ pageSize: jobInfo.count, currentPage: jobInfo.page });
    count = jobInfo.count;
    infoForPaging = Paginate(jobInfo['data'],jobInfo.currentPage,jobInfo.pageSize
    );
  }

  let info;
  let showTable = (
    <TableRow key={uuid()}>
      <TableCell component="th" scope="row">
        loading...
      </TableCell>
    </TableRow>
  );
  if (!loading && jobInfo['data']) {
    info = jobInfo['data'].map((info) => info);
    showTable = infoForPaging.map((info) => (
      <TableRow key={uuid()}>
        <TableCell align="right">
          {info.due_at === null ? info.deadline : info.due_at}
        </TableCell>
        <TableCell align="right">
          {info.role === null ? '-' : info.role}
        </TableCell>
        <TableCell align="right">
          {ReactHtmlParser(info.industry === '' ? '-' : info.industry)}
        </TableCell>
      </TableRow>
    ));
  }

  const moveToNextPage = (page) => {
    // currentPage = page;
  };

  return (
    <>
      <button onClick={moveToJobPost}>NEW POST</button>

      <div className={styles.container}>
        <div className={styles.filters}>
          <DropdownFilter value={webSiteName} filterName="웹사이트 선택" />
          <SearchFilter info={info} filterName="조회" />
        </div>
        <TableContainer component={Paper}>
          <Table className={classes.table} aria-label="simple table">
            <TableHead>
              <TableRow>
                <TableCell>Post date</TableCell>
                <TableCell align="right">Due date</TableCell>
                <TableCell align="right">Role</TableCell>
                <TableCell align="right">Industry</TableCell>
              </TableRow>
            </TableHead>
            <TableBody>{showTable}</TableBody>
          </Table>
        </TableContainer>

        <div className={styles.pagination}>
          {!loading && jobInfo && (
            <Pagination
              itemsCount={count}
              pageSize={jobInfo.pageSize}
              currentPage={jobInfo.currentPage}
              onPageChange={moveToNextPage}
            />
          )}
        </div>
      </div>
    </>
  );
};

export default JobList;

1 个答案:

答案 0 :(得分:2)

如果我理解正确,PageInfo 状态只是指向 jobInfo 值。

Consiedr 直接指向 jobInfo,并切断了中间人。

无论如何,您的主要问题是直接在组件主体上调用 setPageInfo 而不是通过生命周期(在这种情况下 useEffectjobInfo 更改触发),同样的 jobInfo value 不会创建另一个重新渲染(请注意,如果您遵循这种方式而不是第一个建议,请不要将类型对象链接为触发器而是 id 或类似的)

useEffect(()=>{
if (!loading && jobInfo) {
    setPageInfo({ pageSize: jobInfo.count, currentPage: jobInfo.page });
    count = jobInfo.count;
    infoForPaging = 
    Paginate(jobInfo['data'],jobInfo.currentPage,jobInfo.pageSize
    );
  }
 }, [jobInfo.count,jobInfo.page])