【问题标题】:ReactJS - Redirect to private route after state changeReactJS - 状态更改后重定向到私有路由
【发布时间】:2019-11-13 01:42:18
【问题描述】:

我在 Express 中设置了一个登录路由,当使用它时,它将设置我的应用程序的全局状态(使用 Context API),包括用户 ID 和一个由 JSONWebToken 生成的令牌。

为了能够为用户加载待办事项,您需要有一个有效的令牌,当我在执行 API 请求时在标头中发送它时,该令牌有效。使用 Axios 执行此操作时,状态也在更新,但问题是我不知道如何(或最佳方式)转发到受保护的路由。

这是我的 App.js,其中包括我的 WelcomeTodo 组件的路由。在Welcome 内部,有一个Login 组件,它更新AppContext 以包含用户ID 和jsonwebtoken。

import React, { useContext } from 'react'
import { BrowserRouter as Router, Route, Redirect } from 'react-router-dom'
import { Switch } from 'react-router'
import TodoApp from './components/TodoApp/TodoApp'
import Welcome from './components/Welcome/Welcome'
import TodoProvider from './components/TodoApp/TodoContext'
import { AppContext } from './AppContext'

export default function App () {
  const context = useContext(AppContext)

  const PrivateRoute = ({ component: Component, ...rest }) => (
    <Route
      {...rest}
      render={props =>
        context.loggedIn ? <Component {...props} /> : <Redirect to="/" />
      }
    />
  )

  return (
    <Router>
      <Switch>
        <Route exact path="/" component={Welcome} />
        <TodoProvider>
          <PrivateRoute exact path="/todo" component={TodoApp} />
        </TodoProvider>
      </Switch>
    </Router>
  )
}

注意它检查的 context.loggedIn 属性,您可以在本文的最后一个代码块中看到它是如何变化的。

这是我的Login 组件,它位于一个简单的Welcome 组件内

import React, { useState, useContext } from 'react'
import { AppContext } from '../../../AppContext'

export default function Login (props) {
  const [email, setEmail] = useState('')
  const [password, setPassword] = useState('')

  const context = useContext(AppContext)

  const handleSubmit = async e => {
    e.preventDefault()
    try {
      // Method which logs in using the /api/login route, and returns users ID and token to the global state (context)
      await context.handleLogin(email, password)
    } catch {
      throw Error('Login error')
    }
  }
  return (
    <form handleSubmit={handleSubmit}>
      <div className="input-wrapper">
        <label htmlFor="email" />
        <input
          type="text"
          id="login_email"
          placeholder="email"
          value={email}
          onChange={e => setEmail(e.target.value)}
        />
      </div>
      <div className="input-wrapper">
        <label htmlFor="password" />
        <input
          type="password"
          id="login_password"
          placeholder="password"
          value={password}
          onChange={e => setPassword(e.target.value)}
        />
      </div>
      <div className="input-wrapper">
        <button
          type="submit"
          onClick={handleSubmit}
        >
          Log in
        </button>
      </div>
    </form>
  )
}

最后,context.handleLogin 方法更新状态以包含用户 ID 和令牌。取自AppContext.js

handleLogin = (email, password) => {
  axios
    .post('http://localhost:4000/api/login/', {
      email,
      password
    })
    .then(response => {
      this.setState({
        loggedIn: response.httpStatus === 200,
        userID: response.data.data.user._id,
        token: response.data.data.token
      })
    })
    .catch(err => {
      this.setState({
        httpStatus: err.response.status,
        loginError: 'Incorrect email/password'
      })
    })
}

我是 React 的新手,因此我们将不胜感激。提前致谢!

【问题讨论】:

    标签: reactjs express authentication react-router axios


    【解决方案1】:

    我通过使用react-router 中的withRouter() 解决了这个问题,然后将历史推送到私有路由。

    在此处了解更多信息: https://github.com/ReactTraining/react-router/blob/master/packages/react-router/docs/api/withRouter.md

    【讨论】:

      猜你喜欢
      • 2016-12-20
      • 2021-09-09
      • 1970-01-01
      • 2022-01-21
      • 2020-10-22
      • 2020-02-03
      • 2020-04-26
      • 2020-11-12
      • 1970-01-01
      相关资源
      最近更新 更多