Javascript 无法实现身份验证路由

Javascript 无法实现身份验证路由,javascript,reactjs,react-router,Javascript,Reactjs,React Router,我正在尝试学习react,并在我的应用程序中设置需要您登录的路由。我正在尝试修改给出的例子 我编写的代码应该重定向用户或显示受保护的路由。但当我登录时,我仍然被重定向 我相信问题出在我下面的PrivateRoute课程中。我将在父类中设置的authenticated属性传递给它,但它似乎没有更新 在app.js中,我们声明了验证器,在这里我们使用后端执行异步登录 我将checkLoggedIn函数传递给login组件,在那里我们将父级的authenticatedstate属性设置为true。我正

我正在尝试学习react,并在我的应用程序中设置需要您登录的路由。我正在尝试修改给出的例子

我编写的代码应该重定向用户或显示受保护的路由。但当我登录时,我仍然被重定向

我相信问题出在我下面的PrivateRoute课程中。我将在父类中设置的
authenticated
属性传递给它,但它似乎没有更新

在app.js中,我们声明了验证器,在这里我们使用后端执行异步登录

我将checkLoggedIn函数传递给login组件,在那里我们将父级的
authenticated
state属性设置为true。我正在
console.log()
ing状态,只是为了检查它是否正在发生

当我点击
链接
/protected
路线时,我仍然被重定向

app.js

// imports ... 

let authenticator = new Authenticator();

class ProtectedComponent extends Component {
    render() {
        return (
            <h1>Protected!</h1>
        );
    }
}

class App extends Component {
    constructor(props){
        super(props);
        this.state = {
            authenticator: authenticator,
            authenticated: authenticator.isLoggedIn(),
        }
    }

    checkLoggedIn() {
        this.setState({authenticated: true});
        console.log(this.state);
    }

    render() {
        let routes, links = null;
        links = <div className="links">
            <Link to="/login">Login</Link>
            <Link to="/protected">Protected</Link>
        </div>;

        routes = <div className="routes">
            <Route
                path="/login"
                render={() =>
                    <Login
                        authenticator={this.state.authenticator}
                        loginCallback={this.checkLoggedIn} />
                }
            />
            <PrivateRoute
                path="/protected"
                component={ProtectedComponent}
                authenticated={this.state.authenticated}
            />
        </div>;

        return (
            <Router className="App">
                {links}
                {routes}
            </Router>
        );
    }
}

export default App;
//导入。。。
让验证器=新验证器();
类ProtectedComponent扩展了组件{
render(){
返回(
受保护的!
);
}
}
类应用程序扩展组件{
建造师(道具){
超级(道具);
此.state={
验证者:验证者,
已验证:authenticator.isLoggedIn(),
}
}
checkLoggedIn(){
this.setState({authenticated:true});
console.log(this.state);
}
render(){
让路由、链接=空;
链接=
登录
受保护的
;
路线=
}
/>
;
返回(
{links}
{routes}
);
}
}
导出默认应用程序;
privaterout.js

// imports .... 

const PrivateRoute = ({ component: Component, authenticated, ...rest }) => (
    <Route {...rest} render={props =>
            authenticated === true
                ? (<Component {...props} />)
                : (<Redirect to={{
                        pathname: "/login",
                        state: { from: props.location }
                    }} />
                )
    }/>
);

export default PrivateRoute;

//导入。。。。
const privaterout=({component:component,authenticated,…rest})=>(
已验证===true
? ()
: (
)
}/>
);
导出默认私有路由;
Login.js

// imports ...

class Login extends Component {
    constructor(props) {
        super(props);
        this.authenticator = props.authenticator;
        this.loginCallback = props.loginCallback;
        this.state = {
            identifier: "",
            password: "",
        }
    }

    updateState = (e, keyName = null) => {
        this.setState({[keyName]: e.target.value})
    }

    attemptLogin = (e) => {
        this.authenticator.loginPromise(this.state.identifier, this.state.password)
            .then(resp => {
                if(resp.data.success === true) {
                    this.authenticator.setToken(resp.data.api_token);
                    this.loginCallback();
                } else {
                    this.authenticator.removeToken()
                }
            })
            .catch(err => {
                console.error(err);
            });
    }

    render(){
        <button onClick={this.attemptLogin}> Log In </button>
    }
}

export default Login;
//导入。。。
类登录扩展组件{
建造师(道具){
超级(道具);
this.authenticator=props.authenticator;
this.loginCallback=props.loginCallback;
此.state={
标识符:“”,
密码:“”,
}
}
updateState=(e,keyName=null)=>{
this.setState({[keyName]:e.target.value})
}
尝试登录=(e)=>{
this.authenticator.loginPromise(this.state.identifier,this.state.password)
。然后(resp=>{
if(resp.data.success==true){
this.authenticator.setToken(resp.data.api_token);
this.loginCallback();
}否则{
this.authenticator.removeToken()
}
})
.catch(错误=>{
控制台错误(err);
});
}
render(){
登录
}
}
导出默认登录;
我在回调方法中将authenticated状态设置为true,但是当我转到受保护路由(并运行它的render方法)时,它的计算结果似乎为false


如果我误解了react道具系统,请告诉我。如果您想查看更多的代码,请告诉我,我将修改问题。

您必须首先创建PrivateRoute HOC组件:

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

export const PrivateRoute = ({ component: Component, ...rest }) => (
    <Route {...rest} render={props => (
        localStorage.getItem('bpm-user')
            ? <Component {...props} />
            : <Redirect to={{ pathname: '/login', state: { from: props.location } }} />
    )} />
)

就像我从自己的项目复制的示例代码一样

您可以直接在login组件中使用loginCallback(),如this.props。loginCallback祝您成功…感谢peyman,我决定遵循您的方法和布尔表达式,而不是传递状态。欢迎光临,我添加了我的登录缩减器供您参考;)
        <Switch>
            <Route path="/login" component={Login} />
            <PrivateRoute path="/new/index" component={NewIndex} />
            <PrivateRoute path="/jobs/index" component={JobsIndex} />
            <PrivateRoute path="/unions/index" component={UnionsIndex} />
            <PrivateRoute exact path="/" component={ListIndex} />
            <PrivateRoute exact path="/charges" component={MunicipalCharges} />
        </Switch>
<Link to="/jobs/index">Jobs</Link>
import axios from 'axios';
import * as actionTypes from './AuthActionTypes';

export const login = (user) => {
    return dispatch => {
        // for example => dispatch({type:actionTypes.REQUEST_LOGIN_USER});
        axios({
            method: 'post',
            url: '/api/auth/login',
            data: { 'username': user.username, 'password': user.password },
            headers: { 'Content-Type': 'application/json;charset=utf-8' }
        })
            .then(res => {
                localStorage.setItem('bpm-user', JSON.stringify(res.data));
                dispatch({
                    type: actionTypes.LOGIN_USER,
                    payload: res.data
                })
            })
            .catch(error => {
                 // TODO... for example => dispatch({type:actionTypes.FAILD_LOGIN_USER, payload:error});
            })
    }
}

export const logout = () => {
    localStorage.removeItem('bpm-user');
}