我的网站有一些受登录保护的网页。我目前的解决方案是:
app.js中的:
<div className="app">
<Provider store={store}>
<Router history={appHistory} onUpdate={fireTracking}>
<Route name="main" component={AppHandler}>
<Route name="home" path="/" component={HomePageHandler}/>
</Route>
</Router>
</Provider>
</div>
然后我的HomePageHandler是:
export default class HomePageHandler extends BaseAuthorizedComponent {
render() {
return (
<div>hello</div>
)
}
}
由于HomePageHandler扩展了BaseAuthorizedComponent,它被定义为:
class BaseAuthorizedComponent extends Component {
componentWillMount() {
if (!this.props.user.signed_in) {
this.context.router.push('/signin')
}
}
}
HomePageHandler.contextTypes = {
router: React.PropTypes.object.isRequired,
}
function select(state) {
return {
user: state.user,
}
}
export default connect(select)(BaseAuthorizedComponent)
redux的用户对象有一个标志,指示用户是否已登录。我们的想法是,在主页上,在安装组件之前,如果用户未登录,BaseAuthorizedComponent将检查并重定向到登录页面。我的想法是让每个需要授权的页面扩展BaseAuthorizedComponent。
但是,尝试加载主页时会发生以下错误:
Error: Could not find "store" in either the context or props of "Connect(BaseAuthorizedComponent)". Either wrap the root component in a <Provider>, or explicitly pass "store" as a prop to "Connect(BaseAuthorizedComponent)".
不知道如何在保持单个地方检查授权的优势的同时解决问题。有什么想法吗?谢谢!
答案 0 :(得分:1)
首先,您最好使用合成而不是继承https://reactjs.org/docs/composition-vs-inheritance.html
接下来,您可以将react-action-redux(https://github.com/reactjs/react-router-redux)中的“推送”动作创建者添加到mapDispatchToProps函数中:
function composeAuth = (ComposedComponent) => {
class BaseAuthorizedComponent extends React.Component {
// We use componentDidMount instead of componentWillMount, cause componentWillMount is deprecated https://medium.com/@baphemot/whats-new-in-react-16-3-d2c9b7b6193b
componentDidMount() {
if (!this.props.user.signed_in) {
this.props.push('/signin');
}
}
render() {
if (!this.props.user.signed_in) {
return null;
}
return <ComposedComponent {...this.props} />
}
}
return connect(state => ({user: state.user}), {push})(BaseAuthorizedComponent);
}
class HomePageHandler extends React.Component {
render() {
return (
<div>hello</div>
)
}
}
export default composeAuth(HomePageHandler);
答案 1 :(得分:0)
这个怎么样:
class CheckAuth extends React.Component{
state = {
auth: false
}
render(){
return(
{this.state.auth ? <div>Authorized user</div> : <div>Unauthorized user</div>}
)
}
}
function mapStateToProps(state){
return{
auth: state.auth
}
}
export default connect(mapStateToProps)(CheckAuth);
然后将其包含在您的其他组件中:
import CheckAuth from './CheckAuth';
...
class Home extends React.Component{
render(){
return(
<div>
<CheckAuth />
Hello world!!
</div>
)
}
}
export default Home;
答案 2 :(得分:0)
经过更多研究,满足我要求的最简单方法是:
在util文件中:
export function requireAuth(nextState, replace) {
// use your own method to check if user is logged in or not
if (!isLoggedIn()) {
replace({pathname: '/signin'});
}
}
然后在app.js文件中导入此方法并使用它:
<div className="app">
<Provider store={store}>
<Router history={appHistory} onUpdate={fireTracking}>
<Route name="main" component={AppHandler}>
<Route name="home" path="/" component={HomePageHandler} onEnter={requireAuth}/>
</Route>
</Router>
</Provider>
</div>
这样,如果用户需要auth(isLoggedIn()为false),那么它会将页面重定向到/ signin。
答案 3 :(得分:0)
<Route name="name"
path="/path"
component={THeWorkHandler}
onEnter={requireAuth}/>
并且requireAuth被放在一个帮助文件中:
export function requireAuth(nextState, replace) {
if (!(//logic to see if user is logged in )) {
replace({pathname: '/user/signin'});
}
}
这样,如果onEnter requireAuth确定用户未经过身份验证,则会重定向到/ user / signin页面。