如何使用redux商店并让用户访问管理面板 - React

时间:2018-02-24 19:24:49

标签: reactjs redux react-redux

我的应用程序中有这个流程。用户注册/登录,JWT保存在浏览器的存储器中。每当用户刷新页面时,如果存在JWT并且商店没有用户,则它向api发出请求并返回包含用户的json。

index.js

if (localStorage.websiteJWT) {
    setAuthorizationHeader(localStorage.websiteJWT);
    if(!store.getState().user.email)
        store.dispatch(fetchCurrentUser());
}

现在我让用户出现在商店里。用户对象如下所示:

{user: {username: "Bob", admin: true}}

现在我有以下用户路线:

AdminRoute:

-

和将用于其他人的正常路线。

这是管理路线的样子:

<AdminRoute exact location={location} path='/admin/locations' component={LocationsPage}/>

现在我遇到以下情况:

1)管理员用户已经在网站上,商店已经拥有所需的状态state.user.admin,并且他没有任何问题地转到localhost:3000/admin/locations页面。

2)管理员用户直接从浏览器转到该页面,此时商店没有存在用户信息并开始获取它,但是当它返回时,重定向已经发生。在这种情况下,管理员用户永远不能访问管理面板。

我知道这是因为我可以在控制台中看到商店打印几次 Is user admin? undefinedIs user admin? true几次。 我该如何解决情况2?

我想到的唯一解决方案是将一个用户对象存储在localStorage中,就像令牌一样。它并不理想,因为它很容易绕过。即使它不能访问真实数据,因为令牌不是有效的,我也不喜欢这个选项。

编辑:我尝试实施评论中建议的解决方案。我确实有一个loaded: false初始还原状态。

export default function user(state = { loaded: false }, action = {}) {
    switch (action.type) {
        case USER_LOGGED_IN:
            return {...action.user, loaded: true};
        case USER_FETCHED:
            return {...state, ...action.user, loaded: true};
        case USER_LOGGED_OUT:
            return {};
        case USER_CONFIRMED:
            return {...state, confirmed: true};
        default:
            return state;
    }
} 

我相应地更改了我的AdminRoute:

const AdminRoute = ({ loaded, isAuthenticated, component: Component, ...rest }) => {
    console.log(`Is user admin? ${isAuthenticated}`);
    console.log(`Loaded? ${loaded}`);
    return (

        <Route
            {...rest}
            render={props =>
                <div>
                     loaded && isAuthenticated &&
                    <div>
                            <AdminNavigation />
                            <Component {...props} />
                    </div>

                      loaded && !isAuthenticated && <Redirect to="/" />
                </div>
            }
        />
    )
};

AdminRoute.propTypes = {
  component: PropTypes.func.isRequired,
  isAuthenticated: PropTypes.bool,
    loaded: PropTypes.bool.isRequired
};

function mapStateToProps(state) {
  return {
        loaded: state.user.loaded,
        isAuthenticated: state.user.admin
  };
}

export default connect(mapStateToProps)(AdminRoute);

但是这行loaded && !isAuthenticated && <Redirect to="/" />仍然在上面的行之前触发,我仍然被重定向。

我也得到了

Warning: Can only update a mounted or mounting component. This usually means you called setState, replaceState, or forceUpdate on an unmounted component. This is a no-op.

我认为发生这种情况是因为它试图在LocationsPage之后呈现Redirect组件。

0 个答案:

没有答案