javascript - React 组件正在无限次重新渲染
问题描述
路由器文件中的所有大多数组件都无限运行。不知道是什么问题。由于这个问题,ajax 请求会发送无限的 GET 请求。
所有文件看起来都与此类似。
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 文件:这里定义了所有的路由。
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 文件:这是大多数文件动态使用的可重用组件。
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
);
请帮忙
解决方案
每当它们的状态或道具发生变化时,React 组件会自动重新渲染。状态的简单更新会导致所有用户界面 (UI) 元素自动重新呈现。在您的第一个文件中,您正在进行一些 API 调用,成功更改状态。这将告诉反应重新渲染组件,然后它会再次执行 API 并继续。
使用适当的依赖数组在 useEffect 函数中执行 API 调用等所有副作用。
推荐阅读
- c# - 在这种情况下,我需要对密码进行加密吗?
- c - 为 CS50 Lab1 学习 C:人口增长 - 我的程序运行但没有达到我的预期
- discord.js - 在 discord.js 中,client.user 为空
- css - CSS:溢出:隐藏和翻译 X 掩盖了句子的其余部分,只是将字母移动到左侧的所有内容上
- python - 如何在熊猫中按行分组数据
- javascript - 使用 Pug 无法在 Express Js 中加载图像
- neural-network - DeepLearning4J 如何将图层动态添加到多层网络
- python - 我该如何解决这个愚蠢的python语法错误
- c# - 比较编辑器和 Observablecollection 中的对象之间的字符串
- python-3.x - 使用重复值在索引上重新索引数据帧