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;
}
}