太多的重新渲染。 React 限制渲染次数以防止无限循环?

时间:2021-05-28 09:00:53

标签: reactjs firebase use-state

预期 一次获取数据

如何防止出现以下错误:

重新渲染太多。 React 限制渲染次数以防止无限循环。'

我刚刚将基于类的组件更改为功能组件,但它不起作用

我的源代码

import React,{useState,useEffect} from "react";
// @material-ui/core components
import { makeStyles } from "@material-ui/core/styles";
// core components
import GridItem from "components/Grid/GridItem.js";
import GridContainer from "components/Grid/GridContainer.js";
import Table from "components/Table/Table.js";
import Card from "components/Card/Card.js";
import CardHeader from "components/Card/CardHeader.js";
import CardBody from "components/Card/CardBody.js";

import { db } from "../../firebase";
export default function TableList() {
  const [state, setstate] = useState([])
  var users = []
  db.collection("users").get().then((snapshot)=>{ 
    snapshot.forEach(doc => {
      const data =doc.data()
      users.push(data)

    })
  })
  setstate(users)
  console.log(state)

  return (
    <GridContainer>
      <GridItem xs={12} sm={12} md={12}>
        
      </GridItem>
      <GridItem xs={12} sm={12} md={12}>
        <Card plain>
          <CardHeader plain color="primary">
            <h4 className={classes.cardTitleWhite}>
              Users
            </h4>
            <p className={classes.cardCategoryWhite}>
              Here is a subtitle for this table
            </p>
          </CardHeader>
          <CardBody>
            <Table
              tableHeaderColor="primary"
              tableHead={["ID", "Name", "Country", "City", "Salary"]}
              tableData={[
                ["1", 
                "Dakota Rice", 
                "$36,738", 
                "Niger", 
                "Oud-Turnhout"
                ]
              ]}
            />
          </CardBody>
        </Card>
      </GridItem>
    </GridContainer>
  );
}

1 个答案:

答案 0 :(得分:2)

你进入一个无限循环,因为你在组件被渲染时改变了状态,从而触发了另一个改变状态的重新渲染器,依此类推到无限循环。要解决您的问题,请将您的状态更改放入 useEffect:

import React, { useState, useEffect } from "react";
// @material-ui/core components
import { makeStyles } from "@material-ui/core/styles";
// core components
import GridItem from "components/Grid/GridItem.js";
import GridContainer from "components/Grid/GridContainer.js";
import Table from "components/Table/Table.js";
import Card from "components/Card/Card.js";
import CardHeader from "components/Card/CardHeader.js";
import CardBody from "components/Card/CardBody.js";

import { db } from "../../firebase";
export default function TableList() {
  const [state, setstate] = useState([]);

  useEffect(() => {
    var users = [];
    db.collection("users")
      .get()
      .then((snapshot) => {
        snapshot.forEach((doc) => {
          const data = doc.data();
          users.push(data);
        });
      });
    setstate(users);
    console.log(state);
  }, []);

  return (
    <GridContainer>
      <GridItem xs={12} sm={12} md={12}></GridItem>
      <GridItem xs={12} sm={12} md={12}>
        <Card plain>
          <CardHeader plain color="primary">
            <h4 className={classes.cardTitleWhite}>Users</h4>
            <p className={classes.cardCategoryWhite}>
              Here is a subtitle for this table
            </p>
          </CardHeader>
          <CardBody>
            <Table
              tableHeaderColor="primary"
              tableHead={["ID", "Name", "Country", "City", "Salary"]}
              tableData={[
                ["1", "Dakota Rice", "$36,738", "Niger", "Oud-Turnhout"],
              ]}
            />
          </CardBody>
        </Card>
      </GridItem>
    </GridContainer>
  );
}

这部分 }, []);useEffect 末尾的空数组告诉它仅在第一次呈现组件时运行。如果您希望 useEffect 中的代码也被其他更改调用,请在该数组中放置一些值。每次这些值更改时,都会调用 useEffect。因为我们有一个空数组,所以 useEffect 只会被调用一次。