我制作了一个登录表单,以便当某人成功登录时,服务器发送用户信息(名称,电子邮件,ID),并且某些页面状态也会相应更改(例如路由,用户对象),但是每当我登录时一切正常好吧,但是我在控制台中看到一条错误消息:
index.js:1 Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method.
in Login (at App.js:226)
这真的使我感到困惑,因为该应用程序仍然可以正常运行,并且idk为什么我遇到此错误。
app.js的render():
render() {
if (this.state.route === 'login') {
return <Login loadUser={this.loadUser} routeChange={this.routeChange} /> //this is line 226 at app.js
} else if (this.state.route === 'register') {
return <Register loadUser={this.loadUser} routeChange={this.routeChange} />
} else {
return (
<div>
{/* The rest of the app's home components */}
</div>
)
}
login.js:
class Login extends Component {
constructor(props) {
super(props);
this.state = {
email: "",
password: "",
loading: false
}
}
handleChange = (e) => {
this.setState({ [e.target.name]: e.target.value })
}
handleClick = () => {
this.setState({ loading: true })
fetch('myApi/login', {
method: 'post',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
email: this.state.email,
password: this.state.password
})
})
.then(response => response.json())
.then(user => {
if (user.id) {
this.props.routeChange('home');
this.props.loadUser(user);
//localStorage.setItem('user', JSON.stringify(user));
this.setState({ loading: false })
}
})
}
render() {
return (
<div className="container">
<div className="row">
<div className="col-sm-9 col-md-7 col-lg-5 mx-auto">
<div className="card card-signin my-5">
<div className="card-body">
<h5 className="card-title text-center">Sign In</h5>
<form onSubmit={(e) => e.preventDefault()} className="form-signin">
<div className="form-label-group">
<input onChange={this.handleChange} name="email" type="email" id="inputEmail" className="form-control" placeholder="Email address" autoFocus />
<label htmlFor="inputEmail">Email address</label>
</div>
<div className="form-label-group">
<input onChange={this.handleChange} name="password" type="password" id="inputPassword" className="form-control" placeholder="Password" />
<label htmlFor="inputPassword">Password</label>
</div>
<div className="custom-control custom-checkbox mb-3">
<input type="checkbox" className="custom-control-input" id="customCheck1" />
<label className="custom-control-label" htmlFor="customCheck1">Remember password</label>
</div>
<button onClick={this.handleClick} className="btn btn-lg btn-primary btn-block text-uppercase">Sign in</button>
<hr className="my-4" />
<h6 onClick={() => this.props.routeChange('register')} style={{ textAlign: 'center', cursor: 'pointer' }}>Register instead</h6>
</form>
</div>
</div>
</div>
</div>
</div>
);
}
}
答案 0 :(得分:2)
问题是这种thenable
条件,在更改路由后设置状态时。 记住 状态更新是异步的,并且在每个新的渲染周期之前发生。
if (user.id) {
this.props.routeChange('home');
this.props.loadUser(user);
//localStorage.setItem('user', JSON.stringify(user));
this.setState({ loading: false }) // <-- error since component unmounted!!
}
将加载状态恢复为false应该解决警告:
if (user.id) {
this.props.routeChange('home');
this.props.loadUser(user);
}
编辑要真正正确地解决此问题,请将路由更改移至生命周期功能,这样,如果登录无效或用户对象没有{{ 1}}属性。
id
答案 1 :(得分:1)
我认为问题实际上出在您的loadUser函数中。你能分享吗?您是否要在loadUser函数中更改页面?
componentDidMount() {
this.isMounted = true;
}
componentWillUnmount() {
this.isMounted = false;
}
handleClick = () => {
fetch('myApi/login', {
method: 'post',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
email: this.state.email,
password: this.state.password
})
})
.then(response => response.json())
.then(user => {
if (user.id) {
if (this.isMounted) this.setState({ this.state..., loading: false });
if (this.isMounted) this.props.loadUser(user);
if (this.isMounted) this.props.routeChange('home');
}
})
}