Реакция повторного рендеринга после входа в систему и после асинхронного вызова - PullRequest
0 голосов
/ 30 мая 2018

В моем Login реагирующем компоненте я вызываю handleLogin в методе handleSubmit.А затем ... (см. Ниже) ...

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.

Я хотел бы знать, как можно предотвратить вызов метода render() до разрешения axios.post.

1 Ответ

0 голосов
/ 30 мая 2018

Вы можете решить эту проблему, запустив повторную визуализацию.Исходя из вашего примера кода, я считаю, что вам просто нужно дождаться завершения асинхронного вызова 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>
    )
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...