首页 > 解决方案 > React Router v4:自定义 PrivateRoute 组件不断重新加载

问题描述

这是我的第一个问题,所以请饶我一命。

我试着做所有我能做的研究,但我已经放弃了。

所以基本上我正在使用 react-router v4 处理受保护的路由。在看了 Tyler Mcginnis 的 PrivateRoute 之后,我以为我走在了正确的轨道上,但不是。

我可以正确设置isAuthenticated: truerequireUser功能,但 PrivateRoute 路由组件永远不会呈现。它总是重定向到/login. 经过进一步调查,我意识到页面以某种方式刷新,因此isAuthenticated重新设置为false

另外,我没有使用 Redux。

哦,欢迎对我的代码提出任何批评。

请帮忙

/App.js

class App extends Component {
constructor() {
    super()
    this.state = {
      isAuthenticated: false,
      user: {
        username: ''
      }
    }
  }
  requireUser = (userData) => {
    console.log('userData', userData);
    if(userData) {
      this.setState({
        isAuthenticated: true,
        user: {
          username: userData.username
        }
      })
    }
  }  

  render() {
    return (
      <Router>
        <div>
          <Navbar />

          <Route exact path='/' component={Landing} />
          <Route path='/register' component={Register} />
          <Route path='/login' render={(props) => {
            return <Login {...props} requireUser={this.requireUser} />
          }} />
          <PrivateRoute path='/search' component={SearchBar} auth={this.state.isAuthenticated} />
        </div>
      </Router>
    );
  }
}

export default App;

/PrivateRoute.js

import React from 'react'
import { Route, Redirect } from 'react-router-dom'

const PrivateRoute = ({ component: Component, auth, path, ...rest}) => {
  return <Route {...rest} path='/search'  render={(props) => {
    console.log(auth);
    if(auth) {
      return (
        <Component {...props} />
      )
    } else {
      return (
        <Redirect to='/login' />
      )
    }
  }} />
}

export default PrivateRoute

编辑:在我的登录组件中添加

更新:我最终添加this.props.history.push('/search)到我的handleOnSubmit功能

/登录.js

import React, { Component } from 'react'
import axios from 'axios'
import jwt_decode from 'jwt-decode'

class Login extends Component {
  constructor(props) {
    super(props)
    this.state = {
      email: '',
      password: '',
    }
  }

  handleOnChange = (e) => {
    this.setState({
      [e.target.name]: e.target.value
    })
  }

  handleOnSubmit = (e) => {
    // prevent page refresh
    e.preventDefault()
    // destructure state
    const { email, password } = this.state
    // assign to userData
    const userData = { email, password }
    // axios post /api/users/login
    axios
      .post('/api/users/login', userData)
      .then((response) => {
        // destructure
        const { token } = response.data
        const decoded = jwt_decode(token)
        this.props.requireUser(decoded)
      })
      .catch((error) => {
        console.log(error);
      })
  }

  render() {
    return (
      <section className="section">
        <div className="container">
          <form>
            <div className="field">
              <label className="label">Email</label>
                <div className="control">
                  <input 
                      type="email" 
                      placeholder="email"   
                      className="input" 
                      name='email'
                      onChange={this.handleOnChange}
                  />
                </div>
            </div>
            <div className="field">
              <label className="label">Password</label>
              <input 
                type="password" 
                placeholder="password" 
                className="input" 
                name='password'
                onChange={this.handleOnChange}
              />
            </div>
            <div className="field">
              <div className="control">
                <button 
                  onClick={this.handleOnSubmit}
                  type="submit" 
                  className="button is-primary"
                >Log In</button>
              </div>
            </div>
          </form>
        </div>
      </section>
    )
  }
}

export default Login

标签: javascriptreactjsauthenticationreact-routerreact-router-v4

解决方案


你的代码看起来不错。问题是当您手动将地址栏更改为 时/search,会刷新浏览器。没有办法解决这个问题。

您也可以使用具有prop 值的Link组件,用户可以使用该组件导航到搜索,或者您可以通过编程方式更改对象的路径。to'/search'history

this.props.history.push('/search'); 

推荐阅读