【发布时间】:2021-04-28 10:17:15
【问题描述】:
我正在尝试在 React 中实现基于 JWT 的身份验证。我关注了this tutorial from digitalocean,但使用了 axios(基于 promise)而不是 fetch API。
如果身份验证失败,将按要求显示错误消息,并且在成功登录时,将显示正确的页面。然而,React 会抛出以下错误:
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.
我想这是因为我调用 loginpage 父级的钩子来从 axios 承诺的 .then() 调用中设置 JWT,但是父级将停止呈现登录页面,并且它是 axios 承诺jwt 已设置。我将如何巧妙地解决这个问题?
function App() {
const [token, setToken] = useState();
if(!token) {
return <EmployeeLogin setToken={setToken} />;
}
return (
<main>
<Switch>
<Route path="/someroute" component={someComponent} exact />
</Switch>
</main>
);
}
export default App;
// EmployeeLogin.jsx
const styles = theme => ({ ... });
class EmployeeLogin extends React.Component {
constructor(props) {
super(props);
const { setToken } = this.props;
this.state = {
email: '',
password: '',
error: null,
isLoading: false,
};
this.handleSubmitevents = this.handleSubmitevents.bind(this);
}
async handleSubmitevents(event) {
event.preventDefault();
const credentials = {
email: this.state.email,
password: this.state.password,
}
this.setState({
isLoading: true,
error: null,
});
axios.post('http://localhost:8080/account/employee/login', credentials, {
headers: {
"Content-Type": 'application/json', 'Accept': 'application/json'
}
})
.then(res => {
this.props.setToken(res.data.token); // Set the token to the parent (App.js)
})
.catch(error => {
this.setState({
error: error.response.data.message, // Show error message on failure
});
})
.then(() => {
this.setState({ isLoading: false }); // Always stop the loading indicator when done
});
}
componentWillUnmount() {
// How to terminate the promise neatly here?
}
render() {
const { classes } = this.props;
return (
<form className={classes.form} onSubmit={this.handleSubmitevents} noValidate>
<TextField
required
value={this.state.email}
onChange={(e) => { this.setState({ email: e.target.value }); }}
/>
<TextField
required
type="password"
value={this.state.password}
onChange={(e) => { this.setState({ password: e.target.value }); }}
/>
<Button type="submit">Sign In</Button>
</form>
);
}
}
EmployeeLogin.propTypes = {
classes: PropTypes.object.isRequired,
setToken: PropTypes.func.isRequired,
};
export default withStyles(styles)(EmployeeLogin);
【问题讨论】:
-
尝试在设置令牌之前将您的 isLoading 设置为 false。设置令牌后,您的应用程序将重新呈现,EmployeeLogin 将不再存在,您无法更新状态未安装的组件。也许那是你的错误
标签: reactjs axios es6-promise