首页 > 解决方案 > Redux 身份验证不使用更新的道具?

问题描述

私有路由.js

import React, { Component } from "react";

import { BrowserRouter, Route, Switch, Redirect, withRouter} from "react-router-dom";
import { connect } from "react-redux";

function AuthRoute({ component: Component, isAuth, ...rest }) {
  console.log(isAuth);
  let test = false;
  return (
    <Route
      {...rest}
      render={props =>
        isAuth.isAuthenticated === true ? (
          <Component {...props} />
        ) : (
          <Redirect
            to={{
              pathname: "/login",
              state: { from: props.location }
            }}
          />
        )
      }
    />
  );
}

const mapStateToProps = state => {
  {
    console.log(state);
    return { isAuth: state.auth.isAuthenticated };
  }
};

export default withRouter(connect(mapStateToProps, { pure: false })(AuthRoute));

应用程序.js

import React, { Component } from "react";
import { BrowserRouter, Route, Switch, Redirect } from "react-router-dom";
import { library } from "@fortawesome/fontawesome-svg-core";
import PropTypes from "prop-types";
import {
  faHome,
  faClock,
  faTasks,
  faStickyNote,
  faCalendarWeek
} from "@fortawesome/free-solid-svg-icons";

import { connect } from "react-redux";
import { loadUser, checkAuth } from "./actions/authActions";
import store from "./store";

import Home from "./Home";
import SideNav from "./Components/SideNav";
import Recent from "./Components/Recent";
import TopBar from "./Components/TopBar";
import AddNote from "./AddNote";
import LogIn from "./Components/LogIn/LogIn.js";
import Register from "./Components/Register/Register";
import ToDo from "./Components/ToDo/ToDo";
import AuthRoute from "./privateRoute";

library.add(faHome, faClock, faTasks, faStickyNote, faCalendarWeek);

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      isAuthenticated: false
    };
  }

  static propTypes = {
    isAuthenticated: PropTypes.bool
  };

  componentDidMount() {
    store.dispatch(loadUser());
    //  this.props.isAuthenticated();
  }

  LogInContainer = () => {
    return <Route path="/login" component={LogIn} />;
  };

  RegisterContainer = () => {
    return <Route path="/register" component={Register} />;
  };

  DefaultContainer = () => {
    return (
      <div className="app_container">
        <SideNav />
        <TopBar />
        <Route exact path="/" component={Home} />
        <Route path="/recent" component={Recent} />
        <Route path="/AddNote" component={AddNote} />
        <Route path="/ToDo" component={ToDo} />
      </div>
    );
  };

  render() {
    return (
      <div>
        <h1> {this.props.auth.isAuthenticated.toString()}</h1>
        <BrowserRouter>
          <Switch>
            <Route exact path="/login" component={this.LogInContainer} />
            <Route exact path="/register" component={this.RegisterContainer} />
            <AuthRoute component={this.DefaultContainer} />
          </Switch>
        </BrowserRouter>
      </div>
    );
  }
}

const mapStateToProps = state => {
  return { auth: state.auth };
};

export default connect(mapStateToProps)(App);

当用户登录时,将分派一个动作来验证用户。在 redux 开发工具中,我可以看到用户已通过身份验证。

在 privateRoute.js 中,mapStateToProps 总是匹配初始状态而不是更新状态,所以 isAuth 永远不等于 true,我不能显示受保护的路由?

我已经坚持了好几天了,我觉得我正在实施这个错误但是查看其他示例我看不出我做错了什么。

标签: reactjsauthenticationreduxroutes

解决方案


问题是您如何将状态映射到道具。看起来您的商店状态的结构为{ auth: { isAuthenticated: boolean } }. 但是,在道具的私有路由映射状态下,您正在尝试有效访问auth.isAuthenticated.isAuthenticated,这将始终是错误/未定义的。将状态映射到道具时,您需要在状态结构中更上一层楼。尝试将私有路由组件更新为:

import React, { Component } from "react";

import { BrowserRouter, Route, Switch, Redirect, withRouter } from "react-router-dom";
import { connect } from "react-redux";

function AuthRoute({ component: Component, isAuth, ...rest }) {
  console.log(isAuth);
  let test = false;
  return (
    <Route
      {...rest}
      render={props =>
        isAuth.isAuthenticated === true ? (
          <Component {...props} />
        ) : (
          <Redirect
            to={{
              pathname: "/login",
              state: { from: props.location }
            }}
          />
        )
      }
    />
  );
}

const mapStateToProps = state => {
  {
    console.log(state);
    return { isAuth: state.auth }; // change this line
  }
};

export default withRouter(connect(mapStateToProps)(AuthRoute));

推荐阅读