javascript - 在我的情况下,如何解决“超出最大更新深度”?
问题描述
我正在使用 React 在 Ionic 中开发应用程序,但出现此错误:
Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.
我创建了一个表单来更新一些在后端调用 api 请求的数据。
Request: put /xx/xx/update
Body Request:
{
"titleId": "1",
"firstName": "Ani",
}
Response:
{
"title": {
"1": "Dr"
},
"firstName": "Ani",
}
在功能组件 MyData.tsx 内部:
const MyData: React.FC = () => {
//title and firstName come from React Context, I'm using them in the whole app
const {
firstName,
setFirstName,
title,
setTitle,
iserror,
setIserror,
} = React.useContext(AuthContext);
const history = useHistory();
const authHeader = AuthHeader.getAuthHeader();
const updateData = () => {
const data = {
titleId: title,
firstName: firstName,
};
axios
.put("/xx/xx/update", data, { headers: authHeader })
.then((response) => {
setTitle(response.data.title);
setFirstName(response.data.firstName);
return response.data;
})
.catch((error) => {
setMessage(
"Please check your data and try again"
);
setIserror(true);
});
};
return (
<React.Fragment>
<IonPage className="ion-page" id="main-content">
<IonContent className="ion-padding">
<h1>Change your data</h1>
<form className="ion-padding">
<IonItem>
<IonLabel position="floating">Title</IonLabel>
<IonSelect
value={Object.keys(title)} // this row causes the problem
onIonChange={(e) => setTitle(e.detail.value!)}
>
<IonSelectOption value="0"></IonSelectOption>
<IonSelectOption value="1">Dr</IonSelectOption>
<IonSelectOption value="2">Dr.-Ing</IonSelectOption>
<IonSelectOption value="3">Professor</IonSelectOption>
<IonSelectOption value="4">Prof.-Dr</IonSelectOption>
</IonSelect>
</IonItem>
<IonItem>
<IonLabel position="floating">Name*</IonLabel>
<IonInput
required
value={firstName}
onIonChange={(e) => setFirstName(e.detail.value!)}
></IonInput>
</IonItem>
<IonButton
className="ion-margin-top"
expand="block"
onClick={(e) => {
e.preventDefault();
updateData();
history.goBack();
}}
>
Save changes
</IonButton>
</form>
</IonContent>
</IonPage>
</React.Fragment>
);
};
export default MyData;
value={Object.keys(title)} ==> 我需要在打开表单时显示所选字段 'Title' 的实际值,这就是我需要 'value' 属性的原因,但这会导致错误。如果我删除这行代码,我可以成功更新标题和名称。当我再次打开表单时,没有显示标题的实际值,只有“名称”。
我是 React/Ionic/Typescript 的新手,任何帮助都将不胜感激。
谢谢!阿尼
解决方案
您需要将您的请求移动axios
到useEffect反应钩子中:
React.useEffect(() => {
axios
.put("/xx/xx/update", data, { headers: authHeader })
.then((response) => {
setTitle(response.data.title);
setFirstName(response.data.firstName);
return response.data;
})
.catch((error) => {
setMessage(
"Please check your data and try again"
);
setIserror(true);
});
};
}, [])
问题是您的 axios 请求会导致重新渲染,而重新渲染会导致 axios 请求,而 axios 请求会导致重新渲染...
因此,如果您将您的 axios 请求包装在 useEffect 中,您的请求将只发出一次。
推荐阅读
- python - 如何用 1 和 0 替换时间戳?
- javascript - 如何将计数器变量从数字更改为字母?
- java - Viewmodel 无法创建类 Android Java MVVM 的实例
- cucumber - Wdio.conf:如何在 oncomplete 挂钩中使用结果对象
- cucm - 在 Cisco AXL CUCM 中获取所有没有过滤器的结果
- java - 重复ID错误膨胀片段,android
- java - 使用spring数据jpa存储库进行Hql查询后的flush()
- javascript - 反斜杠“\”后忽略字符 - javascript
- java - 使用 JVM 内存默认值运行 Java Web 应用程序
- android - Flutter 应用生命周期回调函数