ReactJs 超过最大更新深度
Posted
技术标签:
【中文标题】ReactJs 超过最大更新深度【英文标题】:ReactJs Maximum update depth exceeded 【发布时间】:2020-01-04 19:24:16 【问题描述】:我正在尝试实现登录视图,但不断出现错误:
已超过最大更新深度。这可能发生在组件 在 componentWillUpdate 内重复调用 setState 或 组件更新。 React 将嵌套更新的数量限制为 防止无限循环。
点击提交按钮时。
import './LoginView.css'
import React, useState from 'react'
import Button, TextField, CircularProgress from '@material-ui/core'
import Auth from '../../utils/Auth'
import Redirect from 'react-router-dom'
import Network from '../../utils/Network'
import Toast, IToastData, ToastType from '../Toast/Toast'
import AdManager from '../../utils/AdManager'
import pkg from '../../../package.json'
import Logo from "../../assets/logo.png"
export default function LoginView()
const [username, setUsername] = useState('')
const [password, setPassword] = useState('')
const [isLoading, setIsLoading] = useState(false)
const [toastData, setToastData] = useState<IToastData | undefined>(undefined)
const onSubmit = async () =>
try
setIsLoading(true)
await Network.instance.login(username, password)
const success = Auth.instance.isLoggedIn()
if (success)
await AdManager.instance.start()
catch (error)
setToastData(
type: ToastType.Error,
message: "Something went wrong!"
)
finally
setIsLoading(false) // According to react this is the culprit
const createInputFields = () =>
return (
<>
<TextField
className="textField"
label="Username"
type="email"
margin="normal"
onChange=x => setUsername(x.target.value)
required=true
/>
<TextField
className="textField"
label="Password"
type="password"
margin="normal"
onChange=x => setPassword(x.target.value)
required=true
/>
</>
)
if (Auth.instance.isLoggedIn())
const path = (AdManager.instance.sources.length === 1) ? '/' : '/selection'
return <Redirect to=path />
return (
<>
<div className="root">
<img src=Logo className="Logo" />
<div className="TextFieldsContainer">
isLoading ? <CircularProgress /> : createInputFields()
</div>
<Button className="button" variant="contained" component="span" disabled=isLoading || (!username || !password) onClick=onSubmit>
Log in
</Button>
!!toastData && <Toast open=true message=toastData.message type=toastData.type />
</div>
<div className="VersionNumber">pkg.version</div>
</>
)
【问题讨论】:
setState
是异步操作。所以你应该把try ...
放在setState
的回调中。把它们锁起来。
捕获后使用finally
如果 setState 你的意思是 onSubmit,那么它已经是异步的了。我最后加了(谢谢),但结果是一样的。
您可以将其发布为答案以帮助未来的读者。此错误消息似乎并不少见。
同意 ford04
【参考方案1】:
我已经解决了这个问题,虽然错误是由 React 抱怨的指定行间接调用的;实际原因是重定向到的组件中的一行代码。
总结一下。 React 在其错误消息中是正确的,但不够具体,无法提供任何实际帮助。我使用git bisect 发现了错误。经常提交并确定提交范围是这里的救星。
【讨论】:
不知道 bisect,谢谢。其他组件中的问题实际上是一些导致上述错误的 setState/render 循环吗? @ford04 错误的行导致重定向回 LoginComponent 进而重定向回具有错误行的组件等。基本上是一个来回调用<redirect ...>
的条件。以上是关于ReactJs 超过最大更新深度的主要内容,如果未能解决你的问题,请参考以下文章
超过最大更新深度。当组件在 componentWillUpdate 中重复调用 setState 时,可能会发生这种情况