当尝试执行注册时,我得到这个警告:
警告:无法在未挂载的组件上执行React状态更新。这是一个无操作,但它表明应用程序中存在内存泄漏。中的所有订阅和异步任务componentWillUnmount方法。at SignUp (http://localhost:3000/static/js/main.chunk.js:4258:5)在div在SignInAndSignUpPage
我的注册页面代码如下:
import React from 'react';
import FormInput from '../form-input/form-input.component';
import CustomButton from '../custom-button/custom-button.component';
import { auth, createUserProfileDocument } from '../../firebase/firebase.utils';
import './sign-up.styles.scss';
class SignUp extends React.Component {
constructor() {
super();
this.state = {
displayName: '',
email: '',
password: '',
confirmPassword: ''
};
}
handleSubmit = async event => {
event.preventDefault();
const { displayName, email, password, confirmPassword } = this.state;
if (password !== confirmPassword) {
alert("passwords don't match");
return;
}
try {
const { user } = await auth.createUserWithEmailAndPassword(
email,
password
);
await createUserProfileDocument(user, { displayName });
this.setState({
displayName: '',
email: '',
password: '',
confirmPassword: ''
});
} catch (error) {
console.error(error);
}
};
handleChange = event => {
const { name, value } = event.target;
this.setState({ [name]: value });
};
render() {
const { displayName, email, password, confirmPassword } = this.state;
return (
<div className='sign-up'>
<h2 className='title'>I do not have a account</h2>
<span>Sign up with your email and password</span>
<form className='sign-up-form' onSubmit={this.handleSubmit}>
<FormInput
type='text'
name='displayName'
value={displayName}
onChange={this.handleChange}
label='Display Name'
required
/>
<FormInput
type='email'
name='email'
value={email}
onChange={this.handleChange}
label='Email'
required
/>
<FormInput
type='password'
name='password'
value={password}
onChange={this.handleChange}
label='Password'
required
/>
<FormInput
type='password'
name='confirmPassword'
value={confirmPassword}
onChange={this.handleChange}
label='Confirm Password'
required
/>
<CustomButton type='submit'>SIGN UP</CustomButton>
</form>
</div>
);
}
}
export default SignUp;
signinandsignupage中的代码如下:
import React from 'react';
import SignIn from '../../components/sign-in/sign-in.component';
import SignUp from '../../components/sign-up/sign-up.component';
import './sign-in-and-sign-up page.styles.scss';
const SignInAndSignUpPage=()=>(
<div className='sign-in-and-sign-up page'>
<SignIn />
<SignUp/>
</div>
);
export default SignInAndSignUpPage;
完整的代码可以在https://github.com/harsh0623/crwn-clothing
找到请帮我找出这个警告的原因。
问题很可能是成功的createUserProfileDocument()
导致此处重定向:https://github.com/harsh0623/crwn-clothing/blob/main/src/App.js#L58-L60
为了缓解这种情况,您可以在await
之后删除对this.setState
的调用。
handleSubmit = async event => {
event.preventDefault();
const { displayName, email, password, confirmPassword } = this.state;
if (password !== confirmPassword) {
alert("passwords don't match");
return;
}
try {
const { user } = await auth.createUserWithEmailAndPassword(
email,
password
);
await createUserProfileDocument(user, { displayName });
} catch (error) {
console.error(error);
// Upon error, it may make sense to reset some information here instead, e.g.
this.setState({
password: '',
confirmPassword: '',
});
}
};
如果你在SignIn
组件中有类似的重置,也可以尝试删除"符号"。路径。
如果组件在await
完成之前被卸载,您将尝试更新卸载组件的状态,这是不允许的。
为了避免这种情况,您应该跟踪组件是否已挂载,并且在组件不再挂载时防止调用setState
。
添加这个来跟踪挂载状态:
componentDidMount() {
this._isMounted = true;
}
componentWillUnmount() {
this._isMounted = false;
}
然后检查组件是否在异步操作完成时仍然挂载:
handleSubmit = async event => {
event.preventDefault();
const { displayName, email, password, confirmPassword } = this.state;
if (password !== confirmPassword) {
alert("passwords don't match");
return;
}
try {
const { user } = await auth.createUserWithEmailAndPassword(
email,
password
);
await createUserProfileDocument(user, { displayName });
if(this._isMounted) {
this.setState({
displayName: '',
email: '',
password: '',
confirmPassword: ''
});
}
} catch (error) {
console.error(error);
}
};
更多关于如何使用函数式组件和钩子的信息,请查看另一个答案