javascript - 登录后 React 重新渲染——以及异步调用后

标签 javascript reactjs asynchronous axios

在我的 Login react 组件中,我在 handleSubmit 方法中调用了 handleLogin。然后……(见下文)……

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>
    )
  }
}

...在 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
}

我遇到的问题是 render() 方法在 axios.post/handleLogin(this.state) 被解析之前被调用,从而阻止了 render() 方法将 isLoggedIn() 视为返回 true

我想知道如何防止在 axios.post 解析之前调用 render() 方法。

最佳答案

您可以通过触发重新渲染来解决此问题。根据您的代码示例,我认为您只需要等待 handleLogin 异步调用完成,然后使用 isUserLogin 检查用户是否登录,您应该添加一个镜像 isUserLogin 以触发重新渲染的本地状态。

下面是一个使用 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>
    )
  }
}

关于javascript - 登录后 React 重新渲染——以及异步调用后,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50594609/

相关文章:

reactjs - React hooks useEffect 调用 API 第二次和第一次调用 API 响应也返回

jquery - 同时执行同步和异步 AJAX

c# - 异步线程体循环,它只是工作,但如何?

windows - 如何从 Perl 中的管道进行非阻塞读取?

javascript - 使用 Angular Js Promises 发出多个异步请求

javascript - 如何更新 Mongo 文档数组内的对象(在特定索引处)

javascript - 无法读取链接 href 未定义的属性 'top'

javascript - 保存的网页显示 Javascript 错误

reactjs - 如何在 ReactJS 中验证数字输入

javascript - 使用多个 iframe vids 的 ReactJS 只有 1 个有效,其他是 Promise pending