简体   繁体   English

React 组件正在无限次重新渲染

[英]React Components are re-rendering Infinite times

All most all components in the router file runs infinitely.路由器文件中的所有大多数组件都无限运行。 Don't know what's the problem.不知道是什么问题。 The ajax request sends infinite GET requests due to this issue.由于此问题,ajax 请求发送无限 GET 请求。

All the files look like something similar to this.所有文件看起来都与此类似。

import React, { useState, useEffect } from "react";
import { connect } from "react-redux";
import { apiCall } from "../handlers/api";
import BasicTable from "../reusable/table";
import { loadFields } from "../store/actions/actionCreators";

const header = [
  "Sl.No",
  "Item Code",
  "Item Name",
  "Item Type",
  "UoM",
  "HSN CODE",
  "Specifications",
  "Description",
  "Brand",
  "Price",
];

function Item(props) {
  const [fields, setFields] = useState([]);
  const [render, setRender] = useState(0);
  console.log(fields);

  // useEffect(() => {
  //   props
  //     .loadFields("/items", 0, 20)
  //     .then((res) => {
  //       console.log(res);
  //     })
  //     .catch((err) => console.log(err));
  //   // eslint-disable-next-line react-hooks/exhaustive-deps
  // }, []);
  apiCall("get", "/product", {})
    .then((data) => setFields(data.product))
    .catch((err) => console.log(err));

  const reRender = () => {
    setRender(render + 1);
  };

  return (
    <div>
      <h1>Items</h1>
      <BasicTable reRender={reRender} header={header} body={fields} />
    </div>
  );
}

const mapStateToProps = (state) => ({
  item: state.Items.fields,
});

export default connect(mapStateToProps, { loadFields })(Item);

Routes file: Here, all the routes are defined. Routes 文件:这里定义了所有的路由。

import React from "react";
import { Route, BrowserRouter as Router, Switch } from "react-router-dom";
import Home from "./home";
import Supplier from "./supplier";
import Item from "./item";
import Menubar from "./menubar";
import Project from "./project";
import Fields from "./fields";
import User from "./user";
import GeneratePO from "./generatePo";
import PODetails from "./poDetails";
import AddButton from "./addButton";
import AddFields from "./addFields";
import { connect } from "react-redux";
import ViewItems from "../reusable/viewItems";
import AddMaterialForm from "../reusable/addMaterialForm";
import ViewMaterialFormItem from "../reusable/viewMaterialFormItem";
import InventoryHeader from "./inventoryHeader";
import InventoryDetails from "./inventoryDetails";
import AddIntentTable from "../reusable/addIntentTable";
import InventoryIssues from "./inventoryIssues";
import InventoryIndents from "./inventoryIndents";
import ItemForm from "../reusable/itemForm";
import POReport from "../reports/poReport";

function Routers(props) {
  return (
    <React.Fragment>
      <Router>
        <header className="width-max navbar">
          <Menubar />
          <AddButton />
        </header>
        <Switch>
          <Route exact path="/">
            <Home />
          </Route>
          <Route exact path="/users">
            <User />
          </Route>
          <Route exact path="/items">
            <Item />
          </Route>
          <Route exact path="/suppliers">
            <Supplier />
          </Route>
          <Route exact path="/fields">
            <Fields />
          </Route>
          <Route exact path="/projects">
            <Project />
          </Route>
          <Route exact path="/generatepo">
            <GeneratePO />
          </Route>
          <Route exact path="/inventoryheader">
            <InventoryHeader />
          </Route>
          <Route exact path="/inventorydetails">
            <InventoryDetails />
          </Route>
          <Route path="/items/add">
            <ItemForm type="POST" />
          </Route>
          <Route path="/users/add">
            <AddFields field="/users" data={{}} type="POST" />
          </Route>
          <Route path="/suppliers/add">
            <AddFields field="/suppliers" data={{}} type="POST" />
          </Route>
          <Route path="/fields/add">
            <AddFields field="/fields" data={{}} type="POST" />
          </Route>
          <Route path="/projects/add">
            <AddFields field="/projects" data={{}} type="POST" />
          </Route>
          <Route path="/generatepo/add">
            <AddMaterialForm field="/generatepo" data={{}} type="POST" />
          </Route>
          <Route path="/inventoryheader/add">
            <AddIntentTable field="/inventoryheader" data={{}} type="POST" />
          </Route>
          <Route path="/items/edit/:ID">
            <ItemForm type="PUT" />
          </Route>
          <Route path="/users/edit/:ID">
            <AddFields field="/users" data={props.user} type="PUT" />
          </Route>
          <Route path="/suppliers/edit/:ID">
            <AddFields field="/suppliers" data={props.supplier} type="PUT" />
          </Route>
          <Route path="/fields/edit/:ID">
            <AddFields field="/fields" data={props.field} type="PUT" />
          </Route>
          <Route path="/projects/edit/:ID">
            <AddFields field="/projects" data={props.project} type="PUT" />
          </Route>
          <Route exact path="/inventory/edit">
            <InventoryHeader />
          </Route>
          <Route path="/purchase/edit">
            <GeneratePO />
          </Route>
          <Route path="/generatepo/edit/:ID">
            <AddMaterialForm
              field="/generatepo"
              data={props.materialForm}
              type="PUT"
            />
          </Route>
          <Route path="/inventoryheader/edit/:ID">
            <AddIntentTable
              field="/inventoryheader"
              data={props.inventoryTable}
              type="PUT"
            />
          </Route>
          <Route path="/items/view/:ID">
            <ViewItems field="/items" data={props.item} />
          </Route>
          <Route path="/users/view/:ID">
            <ViewItems field="/users" data={props.user} />
          </Route>
          <Route path="/suppliers/view/:ID">
            <ViewItems field="/suppliers" data={props.supplier} />
          </Route>
          <Route path="/fields/view/:ID">
            <ViewItems field="/fields" data={props.field} />
          </Route>
          <Route path="/projects/view/:ID">
            <ViewItems field="/projects" data={props.project} />
          </Route>
          <Route path="/generatepo/view/:ID">
            <ViewMaterialFormItem
              field="/generatepo"
              data={props.materialForm}
            />
          </Route>
          <Route path="/inventoryheader/view/:ID">
            <ViewItems field="/inventoryheader" data={props.inventoryTable} />
          </Route>
          <Route path="/inventoryissues">
            <InventoryIssues />
          </Route>
          <Route path="/inventoryindents">
            <InventoryIndents />
          </Route>
          <Route path="/podetails">
            <PODetails />
          </Route>
          <Route path="/poreport">
            <POReport />
          </Route>
        </Switch>
      </Router>
    </React.Fragment>
  );
}

const mapStateToProps = (state) => ({
  item: state.Items.fields,
  field: state.Fields.fields,
  project: state.Projects.fields,
  supplier: state.Suppliers.fields,
  user: state.Users.fields,
  materialForm: state.MaterialForm.fields,
  inventoryTable: state.InventoryTable.fields,
});

export default connect(mapStateToProps, null)(Routers);

table.js file: This is a reusable component that most of the files use dynamicly. table.js 文件:这是大多数文件动态使用的可重用组件。

import React, { useState, useEffect } from "react";
import { makeStyles } from "@material-ui/core/styles";
import Table from "@material-ui/core/Table";
import TableBody from "@material-ui/core/TableBody";
import TableCell from "@material-ui/core/TableCell";
import TableContainer from "@material-ui/core/TableContainer";
import TableHead from "@material-ui/core/TableHead";
import TableRow from "@material-ui/core/TableRow";
import Paper from "@material-ui/core/Paper";
import Button from "@material-ui/core/Button";
import VisibilityIcon from "@material-ui/icons/Visibility";
import EditIcon from "@material-ui/icons/Edit";
import DeleteIcon from "@material-ui/icons/Delete";
import { BottomScrollListener } from "react-bottom-scroll-listener";
import { connect } from "react-redux";
import { loadFields, removeFields } from "../store/actions/actionCreators";
import { useLocation, useHistory } from "react-router-dom";

const useStyles = makeStyles({
  table: {
    minWidth: 650,
  },
});

function BasicTable(props) {
  const location = useLocation();
  const history = useHistory();
  const [items, setItems] = useState([...props.body]);
  const [limit, setLimit] = useState(20);
  const classes = useStyles();

  useEffect(() => {
    const interval = setInterval(() => setItems([...props.body]), 500);
    return () => {
      clearInterval(interval);
    };
  }, [limit, props.body]);

  const handleDelete = (data) => {
    props.removeFields(location.pathname, data);
    setItems(items.filter((item) => item.id !== data.id));
    props.reRender();
  };

  const handleEdit = (id) => {
    history.push(`${location.pathname}/edit/${id}`);
  };

  const handleView = (id) => {
    history.push(`${location.pathname}/view/${id}`);
  };

  const handleScroll = () => {
    // setItems([
    //   ...items,
    //   ...props.body.slice(
    //     limit,
    //     props.body.length > limit + 20 ? limit + 20 : props.body.length
    //   ),
    // ]);
    // setLimit(limit + 20);
  };
  const tableHeader = props.header.map((item, index) => {
    if (index === 0) {
      return (
        <TableCell key={item}>
          <b>{item}</b>
        </TableCell>
      );
    } else {
      return (
        <TableCell key={item} align="right">
          <b>{item}</b>
        </TableCell>
      );
    }
  });

  const tableContent = items.map((item, index) => {
    return (
      <TableRow key={index}>
        {Object.values(item).map((row, ind) =>
          ind === 0 ? (
            <TableCell key={ind} component="th" scope="row">
              {row}
            </TableCell>
          ) : typeof row === "object" ? (
            String(row.name ? row.name : null)
          ) : (
            <TableCell key={ind} align="right">
              {location.pathname === "/users" && ind === 3 ? "**********" : row}
            </TableCell>
          )
        )}
        {location.pathname === "/inventoryindents" ? (
          <Button variant="outlined" color="primary">
            Open Indent
          </Button>
        ) : (
          <TableCell align="right">
            {/* <VisibilityIcon
              style={{ margin: "5px", cursor: "pointer" }}
              onClick={() => handleView(item.id)}
            /> */}
            <EditIcon
              onClick={() => handleEdit(item.id)}
              style={{ margin: "5px", cursor: "pointer" }}
            />
            <DeleteIcon
              onClick={() => handleDelete(item)}
              style={{ margin: "5px", cursor: "pointer" }}
            />
          </TableCell>
        )}
      </TableRow>
    );
  });

  return (
    <BottomScrollListener onBottom={() => handleScroll()}>
      <TableContainer component={Paper}>
        <Table className={classes.table} aria-label="simple table">
          <TableHead>
            <TableRow>
              {tableHeader}
              <TableCell align="right">
                <b>Actions</b>
              </TableCell>
            </TableRow>
          </TableHead>
          <TableBody>{tableContent}</TableBody>
        </Table>
      </TableContainer>
      <br />
      <br />
      <br />
    </BottomScrollListener>
  );
}

const mapStateToProps = (state) => ({
  state,
});

export default connect(mapStateToProps, { loadFields, removeFields })(
  BasicTable
);

please help请帮忙

React components automatically re-render whenever there is a change in their state or props.每当其 state 或 props 发生更改时,React 组件都会自动重新渲染。 A simple update of the state, causes all the User Interface (UI) elements to be re-rendered automatically. state 的简单更新会导致所有用户界面 (UI) 元素自动重新呈现。 In your first file, you are making some API call which on success changing the state.在您的第一个文件中,您正在进行一些 API 调用,成功更改 state。 Which will tell the react to re-render the component, and again it will do the API and it goes on.这将告诉反应重新渲染组件,它会再次执行 API 并继续。

Do all the side effects like API call in useEffect function with proper dependency array.使用适当的依赖数组在 useEffect function 中执行所有副作用,例如 API 调用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM