rob*_*nnn 38 javascript reactjs react-router redux
我想利用react-router的onEnter
处理程序来提示用户在进入受限路由时进行身份验证.
到目前为止,我的routes.js
文件看起来像这样:
import React from 'react';
import { Route, IndexRoute } from 'react-router';
export default (
<Route path="/" component={App}>
<IndexRoute component={Landing} />
<Route path="learn" component={Learn} />
<Route path="about" component={About} />
<Route path="downloads" component={Downloads} onEnter={requireAuth} />
</Route>
)
Run Code Online (Sandbox Code Playgroud)
理想情况下,我希望我的requireAuth
函数是一个可以访问商店和当前状态的redux动作,就像这样:store.dispatch(requireAuth())
.
不幸的是,我无法访问此文件中的商店.connect
在这种情况下,我认为我不能真正使用它来访问我想要的相关操作.我也不能只import store
从创建商店的文件中获取,因为在应用程序首次加载时这是未定义的.
Ash*_*son 56
实现此目的的最简单方法是将商店传递给返回路线的功能(而不是直接返回路线).这样您就可以访问商店onEnter
和其他反应路由器方法.
所以对于你的路线:
import React from 'react';
import { Route, IndexRoute } from 'react-router';
export const getRoutes = (store) => (
const authRequired = (nextState, replaceState) => {
// Now you can access the store object here.
const state = store.getState();
if (!state.user.isAuthenticated) {
// Not authenticated, redirect to login.
replaceState({ nextPathname: nextState.location.pathname }, '/login');
}
};
return (
<Route path="/" component={App}>
<IndexRoute component={Landing} />
<Route path="learn" component={Learn} />
<Route path="about" component={About} />
<Route path="downloads" component={Downloads} onEnter={authRequired} />
</Route>
);
)
Run Code Online (Sandbox Code Playgroud)
然后更新你的主要组件来调用该getRoutes
函数,传入商店:
<Provider store={ store }>
<Router history={ history }>
{ getRoutes(store) }
</Router>
</Provider>
Run Code Online (Sandbox Code Playgroud)
至于调度动作requireAuth
,您可以像这样编写函数:
const authRequired = (nextState, replaceState, callback) => {
store.dispatch(requireAuth()) // Assume this action returns a promise
.then(() => {
const state = store.getState();
if (!state.user.isAuthenticated) {
// Not authenticated, redirect to login.
replaceState({ nextPathname: nextState.location.pathname }, '/login');
}
// All ok
callback();
});
};
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助.
小智 12
如果你想要,你可以像这样写route.js:
var requireAuth = (store, nextState, replace) => {
console.log("store: ", store);
//now you have access to the store in the onEnter hook!
}
export default (store) => {
return (
<Route path="/" component={App}>
<IndexRoute component={Landing} />
<Route path="learn" component={Learn} />
<Route path="about" component={About} />
<Route path="downloads" component={Downloads} onEnter={requireAuth.bind(this, store)} />
</Route>
);
);
Run Code Online (Sandbox Code Playgroud)
我已经设置了一个你可以在这个codepen中玩的例子.
不确定是否触发动作以处理身份验证是一个好主意.我个人更喜欢以不同的方式处理auth :
而不是使用的onEnter
钩,我用一个包装功能部件.我希望我的博客的管理部分受到保护,因此我AdminContainer
使用函数将组件包装在路由中requireAuthentication
,如下所示.
export default (store, history) => {
return (
<Router history={history}>
<Route path="/" component={App}>
{ /* Home (main) route */ }
<IndexRoute component={HomeContainer}/>
<Route path="post/:slug" component={PostPage}/>
{ /* <Route path="*" component={NotFound} status={404} /> */ }
</Route>
<Route path="/admin" component={requireAuthentication(AdminContainer)}>
<IndexRoute component={PostList}/>
<Route path=":slug/edit" component={PostEditor}/>
<Route path="add" component={PostEditor}/>
</Route>
<Route path="/login" component={Login}/>
</Router>
);
};
Run Code Online (Sandbox Code Playgroud)
requireAuthentication
是一个功能
Login
你可以在下面看到它:
export default function requireAuthentication(Component) {
class AuthenticatedComponent extends React.Component {
componentWillMount () {
this.checkAuth();
}
componentWillReceiveProps (nextProps) {
this.checkAuth();
}
checkAuth () {
if (!this.props.isAuthenticated) {
let redirectAfterLogin = this.props.location.pathname;
this.context.router.replace({pathname: '/login', state: {redirectAfterLogin: redirectAfterLogin}});
}
}
render () {
return (
<div>
{this.props.isAuthenticated === true
? <Component {...this.props}/>
: null
}
</div>
)
}
}
const mapStateToProps = (state) => ({
isAuthenticated: state.blog.get('isAuthenticated')
});
AuthenticatedComponent.contextTypes = {
router: React.PropTypes.object.isRequired
};
return connect(mapStateToProps)(AuthenticatedComponent);
}
Run Code Online (Sandbox Code Playgroud)
此外,requireAuthentication
将保护所有路线/admin
.您可以随时随地重复使用它.