Rul*_*ure 14 javascript ecmascript-6 reactjs redux react-redux
我创建了一个登录组件,其中包含所有逻辑内容。
登录减速器是:
const openState = {
loggedIn: null,
user: null
}
export default (state = openState, action) => {
switch (action.type) {
case LOGIN:
return { ...state, loggedIn: true, user: action.payload }
case LOGOUT:
return { ...state, loggedIn: false, user: null }
default:
return openState
}
}
Run Code Online (Sandbox Code Playgroud)
那个行动 :
export const logIn = (user) => {
return {
type: LOGIN,
payload: user
}
}
export const logOut = () => {
return {
type: LOGOUT
}
}
Run Code Online (Sandbox Code Playgroud)
一切正常,但我不确定如何将actionloggedIn和userprops 从 action传递到路由组件以保护所有路由:
const MainRoutes = props => {
const { loggedIn } = props;
console.log(props.loggedIn)
return (
<Router history={history}>
<Baseline />
<Menu/>
<Container maxWidth="md">
<Switch>
<Route exact path="/Login" component={Login} />
<Route exact path="/Carousel" component={Carousel} />
<Route exact path="/Stepper" component={Stepper} />
<Route component={NotFound} />
</Switch>
</Container>
</Router>
);
}
const mapStateToProps = (state) => {
return { loggedIn: state.loggedIn };
};
export default connect(mapStateToProps)(MainRoutes);
Run Code Online (Sandbox Code Playgroud)
如果我将控制台.logloggedIn道具我得到未定义:| 基于loggedIn我可以在路由组件中创建一个逻辑。
您可以简单地定义一个ProtectedRoute将连接到 redux 状态的自定义组件。在您的情况下,它应该映射state.auth.loggedIn和state.auth.user道具并执行 aRedirect如果这些值是假的:
import React from "react";
import { Route, Redirect } from "react-router-dom";
import PropTypes from "prop-types";
const ProtectedRoute = (props) => {
const { redirectPath, component, user, loggedIn, ...routeProps} = props;
const Component = component;
const isAccessible = Boolean(user) && loggedIn;
return (
<Route
{...routeProps}
render={props => {
if (isAccessible) return <Component {...props} />;
return <Redirect to={{ pathname: redirectPath || "/Login" }} />;
}}
/>
);
};
ProtectedRoute.propTypes = {
path: PropTypes.string.isRequired,
redirectPath: PropTypes.string,
component: PropTypes.oneOfType([
PropTypes.shape({ render: PropTypes.func.isRequired }),
PropTypes.func
]),
};
const mapStateToProps = (state) => {
return {
loggedIn: state.auth.loggedIn,
user: state.auth.user
};
};
export default connect(mapStateToProps)(ProtectedRoute);
Run Code Online (Sandbox Code Playgroud)
有了这个,你MainRoutes就不再需要connect了:
const MainRoutes = props => {
return (
<Router history={history}>
...
<Container maxWidth="md">
<Switch>
<Route exact path="/Login" component={Login} />
<ProtectedRoute exact path="/Carousel" component={Carousel} />
<ProtectedRoute exact path="/Stepper" component={Stepper} />
<Route component={NotFound} />
</Switch>
</Container>
</Router>
);
}
export default MainRoutes;
Run Code Online (Sandbox Code Playgroud)
更新:
如果你想auth在页面刷新后保持状态,你需要对你的 redux store 进行一些额外的设置。主要思想是订阅每个操作并将状态的新副本放入localStorageorcookies并initialState在您的应用程序启动之前从选定的存储中持久化。下面是一个例子:
function getFromStorage(key) {
try {
return JSON.parse(window.localStorage.getItem(key)) || {};
} catch (err) {
return {};
}
}
const initialState = getFromStorage("APP_STATE");
const store = createStore(
rootReducer,
initialState, // should go after root reducer
...
);
store.subscribe(() => {
window.localStorage.setItem("APP_STATE", JSON.stringify(store.getState()));
});
Run Code Online (Sandbox Code Playgroud)
这是工作沙箱(由SuleymanSah引导)
正如其他人已经描述的那样,您最好创建一条受保护的路由来完成您想要的任务。如果用户尚未登录,您只需将用户重定向到登录路由即可。
这是我的实现:(codesandbox)
import React from "react";
import { Route, Redirect } from "react-router-dom";
import { connect } from "react-redux";
const ProtectedRoute = ({
path,
component: Component,
render,
loggedIn,
...rest
}) => {
return (
<Route
path={path}
{...rest}
render={(props) => {
if (loggedIn) {
return Component ? <Component {...props} /> : render(props);
}
return (
<Redirect
to={{
pathname: "/login",
state: { from: props.location }
}}
/>
);
}}
/>
);
};
const mapStateToProps = (state) => {
const { loggedIn } = state.auth;
return {
loggedIn
};
};
export default connect(mapStateToProps)(ProtectedRoute);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1556 次 |
| 最近记录: |