小编典典

从通过React Router设置的路由访问Redux Store

reactjs

我想利用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>
)

理想情况下,我想我的requireAuth功能是可以访问存储和当前状态的终极版的动作,像这样的作品:store.dispatch(requireAuth())

不幸的是,我无权访问此文件中的商店。我认为connect在这种情况下我不能使用真正的使用来访问我想要的相关动作。我也不能仅从import store创建商店的文件中访问,因为在应用程序首次加载时这是未定义的。


阅读 357

收藏
2020-07-22

共1个答案

小编典典

完成此操作的最简单方法是将商店传递给返回路线的函数(而不是直接返回路线)。这样,您可以访问存储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>
  );
)

然后更新您的主要组件以调用getRoutes函数,并传入商店:

<Provider store={ store }>
  <Router history={ history }>
    { getRoutes(store) }
  </Router>
</Provider>

至于从调度动作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();
    });
};

希望这可以帮助。

2020-07-22