设置后如何直接渲染状态?

时间:2020-04-23 05:55:39

标签: javascript reactjs react-router react-router-dom

简介:我非常是ReactJS的新手(我一周前才刚开始),但我并没有以此为借口,因此,如果我不了解某些内容,请加倍努力。

摘要:我正在尝试实施保护路线。

背景:在安装“受保护的路由”组件后,componentDidMount()调用一个名为isAuthenticated()的函数,该函数会更改名为isAuthenticated的字段的状态。我正在检查该字段,以确定用户是看到受保护的组件还是被路由回“登录”页面。

问题:每次访问CreatePost的受保护路线时,我的日志显示isAuthenticated()componentDidMount()之后被调用,但是我不确定为什么我的UI是反映这些新更改,以向用户显示经过身份验证的路由。

问题:任何人都可以协助或推荐我没有考虑过的更好的策略吗?我真的很感激。

注意:如果我在构造函数中将this.state.isAuthenticated字段声明为true,则会看到我的保护路线,但这不是我的预期目标。希望这有助于诊断问题。

App.js:

import React, {Component} from 'react'
import './App.css'

import Signup from './components/Signup'
import Login from './components/Login'
import Feed from './components/Feed'
import CreatePost from './components/Createpost' 
import ProtectedRoute from './components/Protectedroute'

import {
    BrowserRouter as Router,
    Switch,
    Link,
    Route,
    Redirect
} from 'react-router-dom'


class App extends Component {
    render() {
        return(
            <Router>
                <div>
                    <Link to ='/signup'>Signup</Link>
                    <br />
                    <Link to = '/login'>Login</Link>
                    <br />
                    <Link to ='/create-post'>Create Post</Link>
                    <br />
                    <Link to ='/feed'>Feed</Link>
                </div>
                <Switch>
                    <Route path = '/signup' component = {Signup} />
                    <Route path = '/login' component = {Login} />
                    <Route path = '/feed' component = {Feed} />
                    <ProtectedRoute path = '/create-post' component = {CreatePost} />
                </Switch>
            </Router>
        )
    }
}

export default App

ProtectedRoute.js

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


class ProtectedRoute extends Component {
    constructor(props) {
        super(props)

        this.state = {
            isAuthenticated: false
        }

        this.isAuthenticated = this.isAuthenticated.bind(this)
    }

    componentDidMount() {
        console.log('--componentDidMount--')
        this.isAuthenticated()
    }

    isAuthenticated() {
        console.log('--isAuthenticated--')
        this.setState({isAuthenticated: true})
    }
    render() {
        const Component = this.props.component

        return this.state.isAuthenticated ? (<Component />) : (<Redirect to = '/login' />)
    }
}

export default ProtectedRoute

2 个答案:

答案 0 :(得分:1)

与其在该API调用的组件内部设置状态,不如尝试创建一个函数,然后将api响应返回为true或成功

import React, { Component } from "react";
import { Redirect, Route } from "react-router-dom";

class ProtectedRoute extends Component {
  constructor(props) {
    super(props);

    this.state = {
      isAuthenticated: false
    };

    this.isAuthenticated = this.isAuthenticated.bind(this);
  }

  componentDidMount() {
    console.log("--componentDidMount--");
    this.isAuthenticated();
  }

  isAuthenticated() {
    console.log("--isAuthenticated--");
    // Authentiction logic
    return true;
  }
  render() {
    const Component = this.props.component;

    return (
      <Route
        render={props =>
          this.isAuthenticated() ? (
            <Component {...props} />
          ) : (
            <Redirect to="/login" />
          )
        }
      />
    );
  }
}

export default ProtectedRoute;

答案 1 :(得分:0)

似乎这里的问题是setState异步。发生的情况是,在第一个渲染中this.state.isAuthenticated为false,因此立即进行重定向。您可以引入一个加载状态,这将帮助您仅在加载状态和isAuthenticated状态都解决后才将组件\重定向的呈现推迟到。 通常,永远不要期望setState以同步的方式立即更改状态。

相关问题