Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何基于API中的数据重新路由,而无需组件闪烁-React/Redux_Javascript_Reactjs_Redux_React Redux_React Router - Fatal编程技术网

Javascript 如何基于API中的数据重新路由,而无需组件闪烁-React/Redux

Javascript 如何基于API中的数据重新路由,而无需组件闪烁-React/Redux,javascript,reactjs,redux,react-redux,react-router,Javascript,Reactjs,Redux,React Redux,React Router,我正在编写一个小型待办应用程序,在基于后端数据重新路由用户时遇到问题。该应用程序正在使用: express session创建服务器端用户会话 连接mongodb会话以存储会话数据 react redux用于应用程序状态管理 当用户登录时,名为isLoggedIn的user模型属性设置为true。此值用于将用户重定向到LandingPage组件,用户可以在该组件中创建新的待办事项。这很好,但问题是如果刷新登录页,则在呈现登录页之前,isLoggedIn的值尚未从后端到达。这会导致用户被重新路

我正在编写一个小型待办应用程序,在基于后端数据重新路由用户时遇到问题。该应用程序正在使用:

  • express session
    创建服务器端用户会话
  • 连接mongodb会话
    以存储会话数据
  • react redux
    用于应用程序状态管理
当用户登录时,名为
isLoggedIn
user
模型属性设置为
true
。此值用于将用户重定向到
LandingPage
组件,用户可以在该组件中创建新的待办事项。这很好,但问题是如果刷新登录页,则在呈现登录页之前,
isLoggedIn
的值尚未从后端到达。这会导致用户被重新路由到登录页面,然后数据到达,然后再次被重新路由到登录页面

登录页面“闪烁”起来是非常烦人的,我找不到任何方法来回避它。我尝试在
localStorage
中存储一个布尔值
isLoggedIn
,效果很好,但这肯定会破坏使用服务器端会话的意义

以下是我的代码片段,谢谢

App.js

import { getUser } from "./redux/actions/auth";

const App = withRouter(({ user, data }) => {
    useEffect(() => {
        store.dispatch(getUser()); // user data loaded every time app re-renders
    }, []);

    return (
        <Provider store={store}>
            <Router>
                <div className='my-app'>
                    <Switch>
                        <Route exact path='/login' component={Login} />
                        <Private
                            isLoggedIn={isLoggedIn}
                            path='/landing'
                            component={LandingPage}
                        />
                    </Switch>
                </div>
            </Router>
        </Provider>
    );

const Private = ({ isLoggedIn, component: Component, ...rest }) => {
    return (
        <Route
            {...rest}
            render={props =>
                isLoggedIn ? (
                    <Component {...props} />
                ) : (
                    // I think the problem is here - because isLoggedIn is not available from the backend 
                    // call yet, so login page gets rendered before the data arrives
                    <Redirect to='/login' {...props} /> 
                )
            }
        />
    );
};
getUserReducer.js

const initialState = {
    user: {}
};

export default function(state = initialState, action) {
    const { type, payload } = action;
    switch (type) {
        case LOGIN_SUCCEEDED:
        case LOADED_USER:
            return {
                ...state,
                user: payload
            };
        case LOGIN_FAILED:
        case LOAD_USER_FAILED:
            return {
                ...state,
                user: {}
            };
        default:
            return state;
    }
}

所以有几种方法可以做到这一点。一种方法是创建一个经过身份验证的路由,其唯一目的是验证会话cookie,例如
/me

如果用户以前登录过,浏览器应具有有效的会话作为cookie。这意味着可以使用200请求
/me
。如果会话已过期,则您将获得401。对于401,您只需重定向回登录页面

有很多方法可以向用户传达这种情况。一种方法是像您已经做的那样在本地存储中有一些状态,并假设允许用户导航到登录页。无论如何,您都不会加载任何敏感数据,因为这些数据应该位于经过身份验证的端点之后


对于任何401,您都可以重定向到登录,或向用户显示错误,如“您的会话似乎已过期,请单击此处重新登录。”。

我的建议是,创建一个父组件,在这种情况下,您可以添加逻辑来检查用户是否为loggedIn,还可以触发此后端检查的指示符/加载符号。仅在API返回结果时加载子组件。对于父组件,您可以在这里看到一个示例-感谢您的回复!这是一个好主意,虽然链接已断开,但您在其他地方有此示例吗?干杯
export const getUser = () => async dispatch => {
    try {
        const response = await axios.get("/api/user");
        dispatch({
            type: LOADED_USER,
            payload: response.data
        });
    } catch (error) {
        dispatch({
            type: LOAD_USER_FAILED
        });
    }
};
const initialState = {
    user: {}
};

export default function(state = initialState, action) {
    const { type, payload } = action;
    switch (type) {
        case LOGIN_SUCCEEDED:
        case LOADED_USER:
            return {
                ...state,
                user: payload
            };
        case LOGIN_FAILED:
        case LOAD_USER_FAILED:
            return {
                ...state,
                user: {}
            };
        default:
            return state;
    }
}