[英]React re-render after login — and after an asynchronous call
In my Login
react component here, I call handleLogin
within the handleSubmit
method. 在此处的
Login
react组件中,我在handleSubmit
方法中调用handleLogin
。 And then... (see below)... 然后...(见下文)...
import React from "react"
import { Redirect } from "react-router-dom"
import axios from 'axios'
import Form from "./Form"
import View from "./View"
import { handleLogin, isLoggedIn } from "../utils/auth"
export default class Login extends React.Component {
constructor(props) {
super(props);
this.state = {
email: ``,
password: ``,
};
}
handleUpdate(event) {
this.setState({
[event.target.name]: event.target.value,
})
}
handleSubmit(event) {
event.preventDefault()
handleLogin(this.state)
}
render() {
if (isLoggedIn()) {
return <Redirect to={{ pathname: `/app/profile` }} />
}
return (
<View title="Log In">
<Form
handleUpdate={e => this.handleUpdate(e)}
handleSubmit={e => this.handleSubmit(e)}
/>
</View>
)
}
}
...Within the handleLogin
method (imported from ../utils/auth
below), I make an asynchronous call ( axios.post
): ...在
handleLogin
方法(从下面的../utils/auth
导入)中,我进行了异步调用( axios.post
):
// in /utils/auth.js
import axios from 'axios'
const isBrowser = typeof window !== `undefined`
const getUser = () =>
window.localStorage.gatsbyUser
? JSON.parse(window.localStorage.gatsbyUser)
: {}
const setUser = user => (window.localStorage.gatsbyUser =
JSON.stringify(user))
export const handleLogin = ({ email, password }) => {
if (!isBrowser) return false
axios.post(`${process.env.API_URL}/sessions`, {
email: email,
password: password,
})
.then(response => {
console.log(response);
return setUser({
name: `Jim`,
legalName: `James K. User`,
email: email,
})
})
.catch(error => {
return false
});
}
export const isLoggedIn = () => {
if (!isBrowser) return false
const user = getUser()
return !!user.email
}
The problem I run into is that the render()
method is called before the axios.post / handleLogin(this.state)
is resolved, thus preventing the render()
method from seeing the isLoggedIn()
as returning true
. 我遇到的问题是在解决
axios.post / handleLogin(this.state)
之前调用了render()
方法,从而阻止了render()
方法将isLoggedIn()
视为返回true
。
I'd like to know how I can prevent the render()
method from being called before axios.post
is resolved. 我想知道如何防止
axios.post
解决之前调用render()
方法。
You can solve this problem by triggering a re-render. 您可以通过触发重新渲染来解决此问题。 Based on your code example, I reckon you just need to wait for the
handleLogin
async call to finish, then check if user is logged or not with isUserLogin
, you should add a local state that is mirrored isUserLogin
to trigger the re-render. 根据您的代码示例,我认为您只需要等待
handleLogin
异步调用完成,然后使用isUserLogin
检查用户是否已登录,则应添加镜像isUserLogin
的本地状态以触发重新渲染。
Below is an example using Promise, you can achieve the same thing with async/await: 以下是使用Promise的示例,您可以使用async / await实现相同的功能:
export default class Login extends React.Component {
constructor(props) {
super(props);
this.state = {
email: ``,
password: ``,
isLoggedIn: false
};
}
handleSubmit(event) {
event.preventDefault()
handleLogin(this.state)
.then(response => this.setState({isLoggedIn: isLoggedIn()}))
.catch(err => // Handle the error here, or just swallow it)
}
render() {
if (this.state.isLoggedIn) {
return <Redirect to={{ pathname: `/app/profile` }} />
}
return (
<View title="Log In">
<Form
handleUpdate={e => this.handleUpdate(e)}
handleSubmit={e => this.handleSubmit(e)}
/>
</View>
)
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.