javascript - 如何防止反应组件中的无限循环?
问题描述
嗨,我是新来的反应,不幸的是我得到了这个代码的无限循环,我不知道为什么。这是有问题的代码:
if (projectInfo) {
console.log('Length is', projectInfo.length);
for (let i = 0; i < projectInfo.length; i++) {
setValues({ ...values, fromDates: projectInfo[i].fromDate });
console.log('i is', i);
}
}
整个组件在这里:
import React from 'react';
import Grid from '@material-ui/core/Grid';
import Box from '@material-ui/core/Box';
import Map from '../../shared/components/Map/Map';
export default function FieldworkInofrmation(props) {
const projectInfo = props.props.fieldwork;
const [values, setValues] = React.useState({
fromDates: ' ',
});
if (projectInfo) {
console.log('Length is', projectInfo.length);
for (let i = 0; i < projectInfo.length; i++) {
setValues({ ...values, fromDates: projectInfo[i].fromDate });
console.log('i is', i);
}
}
return (
<Grid container spacing={3}>
<Grid item xs={12}>
<Box fontWeight="fontWeightBold" m={1}>
Fieldwork Information
</Box>
</Grid>
<Grid item xs={12}>
<Box fontWeight="fontWeightLight" m={1}>
Click on map point to view details for the point
</Box>
</Grid>
<Grid item xs={12}>
<Map />
</Grid>
<Grid item xs={1}>
<Box fontWeight="fontWeightLight" m={1}>
Type:
</Box>
</Grid>
<Grid item xs={1}>
<Box fontWeight="fontWeightLight" m={1}>
Period:
</Box>
</Grid>
<Grid item xs={1}>
<Box fontWeight="fontWeightLight" m={1}>
From:
</Box>
</Grid>
<Grid item xs={1}>
<Box fontWeight="fontWeightLight" m={1}>
To:
</Box>
</Grid>
<Grid item xs={6}>
<Box fontWeight="fontWeightLight" m={1}>
Coordinates:
</Box>
</Grid>
<Grid item xs={1}>
<Box fontWeight="fontWeightLight" m={1}>
Station:
</Box>
</Grid>
<Grid item xs={1}>
<Box fontWeight="fontWeightLight" m={1}>
Location:
</Box>
</Grid>
</Grid>
);
}
我尝试在 for 循环的末尾插入“i++”,但仍然出现错误:“重新渲染太多。React 限制了渲染的数量以防止无限循环”。我能做些什么来解决这个问题?
解决方案
正如其他人所提到的,您获得无限循环的原因是因为您在渲染期间更新了状态,这会导致重新渲染,从而再次更新状态,等等。
由于您要做的只是有效地设置初始状态,因此无需使用“setState”方法(或在您的情况下为“setValues”)。
只需执行以下操作:
const projectInfo = props.props.fieldwork;
const initialValues = {
fromDates: ' ',
};
if (projectInfo) {
for (let i = 0; i < projectInfo.length; i++) {
initialValues = { ...initialValues, fromDates: projectInfo[i].fromDate };
}
}
const [values, setValues] = React.useState(initialValues);
但是,在您当前的实现中,您不断地覆盖“fromDates”的值。我怀疑这values
应该是一个对象数组,每个对象都有自己的“fromDates”字段。例如:
const projectInfo = props.props.fieldwork;
const initialValues = [{
fromDates: ' ',
}] // this is now an array
if (projectInfo) {
for (let i = 0; i < projectInfo.length; i++) {
initialValues.push({ fromDates: projectInfo[i].fromDate });
}
}
const [values, setValues] = React.useState(initialValues); // `values` will now have an array of objects [{ fromDate: ' ' }, { fromDate: 'Oct 14th, 2019' }, ...]
最后,如果您确实打算覆盖“fromDate”并且您只关心最新值,则根本不需要循环。只需设置projectInfo
数组中的最新值:
const projectInfo = props.props.fieldwork;
const initialValues = {
fromDates: ' ',
};
if (projectInfo) {
initialValues.fromDates = projectInfo[projectInfo.length -1].fromDates;
}
const [values, setValues] = React.useState(initialValues);
@Ghojzilla 在评论中也提到了最后一个解决方案。
推荐阅读
- reactjs - 使用 React/Webpack 加载图像
- c++ - GLSL 照明数学搞砸了,找不到错误
- java - 将没有任何循环的 2D 数组的 C++ 递归填充实现转换为 Java?
- git - 如何在 .git/hooks/pre-commit 文件上提交我的更改
- git - Heroku 登录在 git bash 中无法正常工作
- algorithm - 如何使用优先队列?
- python - 无法将视图从主 Django 项目文件夹导入应用程序 views.py
- r - 尝试在 R 中创建带有箭头的图形,但不能将离散值应用于连续比例
- css - 下拉菜单在悬停时没有延迟。“引导程序4”
- java - 向序列化 JSON 对象添加额外字段