错误:无法对未安装的组件执行 React 状态更新
Posted
技术标签:
【中文标题】错误:无法对未安装的组件执行 React 状态更新【英文标题】:Error : Can't perform a React state update on an unmounted component 【发布时间】:2021-07-07 08:49:03 【问题描述】:这是完全错误
警告:无法对未安装的组件执行 React 状态更新。 这是一个空操作,但它表明您的应用程序中存在内存泄漏。 要修复,请取消 useEffect 中的所有订阅和异步任务 清理功能。 在注册页面
这是我的 siguppage.js 文件
import React, useState from 'react'
import withFirebase from '../firebase/Context'
import useHistory from 'react-router-dom'
import compose from 'recompose'
import withAuthUser from '../UserData/withAuthUser'
const SignUpPage = (props) =>
const [Email, setEmail] = useState('')
const [PasswordOne, setPasswordOne] = useState('')
const [PasswordTwo, setPasswordTwo] = useState('')
const [UserName, setUserName] = useState('')
const [error, setError] = useState('')
let history = useHistory()
const [AuthUser, setAuthUser] = props.AuthUser()
const onSubmit = () =>
props.firebase
.createUserWithEmailAndPassword(Email, PasswordOne)
.then((authUser) =>
history.push('/home')
setAuthUser(authUser)
)
.catch((error) =>
setError(error)
console.log(error)
)
const IsInvalid =
Email === '' ||
PasswordOne === '' ||
PasswordTwo === '' ||
UserName === '' ||
PasswordTwo !== PasswordOne
return (
<div>
<h1>Sign Up</h1>
<input
type='text'
placeholder='UserName'
value=UserName
onChange=(UserName) =>
const value = UserName.target
setUserName(value)
></input>
<input
type='text'
placeholder='email'
value=Email
onChange=(Email) =>
const value = Email.target
setEmail(value)
></input>
<input
type='password'
placeholder='PasswordOne'
value=PasswordOne
onChange=(pass) =>
const value = pass.target
setPasswordOne(value)
></input>
<input
type='password'
placeholder='PasswordTwo'
value=PasswordTwo
onChange=(pass) =>
const value = pass.target
setPasswordTwo(value)
></input>
<button disabled=IsInvalid onClick=onSubmit type='submit'>
Submit
</button>
error && <p>error.message</p>
</div>
)
export default compose(withFirebase, withAuthUser)(SignUpPage)
我为此使用了 HOC,我通过类似这样的 withAuthUser 传递了props.AuthUser
const withAuthUser = (Component) => (props) =>
return (
<AuthUserContext.Consumer>
(AuthUser) => <Component ...props AuthUser=AuthUser></Component>
</AuthUserContext.Consumer>
)
AuthUser
是一个函数
export const Value = () =>
const [AuthUser, setAuthUser] = useState(null)
return [AuthUser, setAuthUser]
我将此函数传递给主 index.js
中的 Provider usign 上下文
所以我试图通过调用 props.setAuthUser 来更新 AuthUser
的状态,但它给出了这个错误..
【问题讨论】:
你能把你的代码放到codesandbox吗,因为这样很难理解 ok..把它放到发送箱 【参考方案1】:当您在离开屏幕后尝试更新屏幕内的状态时会出现此错误。为了解决这个问题,我们需要一个使用 useEffect
钩子的清理函数
所以你的SignupPage.js
应该是这样的
import React, useEffect, useState from "react";
import withFirebase from "../firebase/Context";
import useHistory from "react-router-dom";
import compose from "recompose";
import withAuthUser from "../UserData/withAuthUser";
const SignUpPage = (props) =>
const [Email, setEmail] = useState("");
const [PasswordOne, setPasswordOne] = useState("");
const [PasswordTwo, setPasswordTwo] = useState("");
const [UserName, setUserName] = useState("");
const [error, setError] = useState("");
let history = useHistory();
const [AuthUser, setAuthUser] = props.AuthUser();
useEffect(() =>
return () => ;
, []);
const onSubmit = () =>
props.firebase
.createUserWithEmailAndPassword(Email, PasswordOne)
.then((authUser) =>
history.push("/home");
setAuthUser(authUser);
)
.catch((error) =>
setError(error);
console.log(error);
);
;
const IsInvalid =
Email === "" ||
PasswordOne === "" ||
PasswordTwo === "" ||
UserName === "" ||
PasswordTwo !== PasswordOne;
return (
<div>
<h1>Sign Up</h1>
<input
type="text"
placeholder="UserName"
value=UserName
onChange=(UserName) =>
const value = UserName.target;
setUserName(value);
></input>
<input
type="text"
placeholder="email"
value=Email
onChange=(Email) =>
const value = Email.target;
setEmail(value);
></input>
<input
type="password"
placeholder="PasswordOne"
value=PasswordOne
onChange=(pass) =>
const value = pass.target;
setPasswordOne(value);
></input>
<input
type="password"
placeholder="PasswordTwo"
value=PasswordTwo
onChange=(pass) =>
const value = pass.target;
setPasswordTwo(value);
></input>
<button disabled=IsInvalid onClick=onSubmit type="submit">
Submit
</button>
error && <p>error.message</p>
</div>
);
;
export default compose(withFirebase, withAuthUser)(SignUpPage);
试试这个并告诉我。
【讨论】:
我能够解决错误,但状态没有更新。我在问题中添加了一个代码沙箱链接,请查看...【参考方案2】:您正在尝试在未安装的组件上设置状态。
const onSubmit = () =>
props.firebase
.createUserWithEmailAndPassword(Email, PasswordOne)
.then((authUser) =>
history.push("/home"); //This causes the current component to unmount
setAuthUser(authUser); //This is an async action, you are trying to set state on an unmounted component.
)
.catch((error) =>
setError(error);
console.log(error);
);
;
【讨论】:
【参考方案3】:未安装的组件是您的 SignUpPage 组件。找到在挂载上使用它的组件时停止 onSubmit 的方法。首先,当使用这个函数和这个 onSubmit 的组件挂载时运行一个清理函数,所以将清理函数放在 onSubmit 中并返回它,这样在 useEffect 中返回一个值并且该值是一个函数,然后当使用的组件这个 useEffect 它触发返回的清理函数。您可以创建诸如 AbortController() 之类的东西来捕获错误并更新状态。
【讨论】:
这没有提供问题的答案。一旦你有足够的reputation,你就可以comment on any post;相反,provide answers that don't require clarification from the asker。 - From Review以上是关于错误:无法对未安装的组件执行 React 状态更新的主要内容,如果未能解决你的问题,请参考以下文章
“警告:无法对未安装的组件执行 React 状态更新。” [关闭]
路由器事件在构造函数上使用时会导致错误警告:无法对未安装的组件执行 React 状态更新