繁体   English   中英

在React Router V4中将私有路由设为异步路由

[英]make a private route to async route in react router v4

我正在使用React Router v4在我的应用程序中进行路由。 组件,sagas和reducer异步加载。 在这种情况下,我现在如何实现私有路由和公共路由?

这是路由和加载的代码

/**
 * A wrapper component that will lazily render a component after it has been loaded.
 */
class Bundle extends Component {
  static contextTypes = {
    store: React.PropTypes.object
  };

  state = {
    // short for "module" but that's a keyword in js, so "mod"
    mod: null
  };

  componentWillMount() {
    this.load(this.props);
  }

  /* istanbul ignore next */
  componentWillReceiveProps(nextProps) {
    if (nextProps.load !== this.props.load) {
      this.load(nextProps);
    }
  }

  load(props) {
    this.setState({
      mod: null
    });
    props.load(this.context.store, mod => {
      this.setState({
        // handle both es imports and cjs
        mod: mod.default ? mod.default : mod
      });
    });
  }

  render() {
    // eslint-disable-next-line no-unused-vars
    const { load, ...otherProps } = this.props;
    return this.state.mod && <this.state.mod {...otherProps} />;
  }
}

const AsyncRoute = ({ load, ...others }) => (
  <Route {...others} render={props => <Bundle load={load} {...props} />} />
);

AsyncRoute.propTypes = {
  computedMatch: React.PropTypes.object,
  path: React.PropTypes.string,
  load: React.PropTypes.func
};

export default AsyncRoute;


// how can i make private route with different layout not a children of App
function Routes({ location }) {
  return (
    <Switch location={location}>
      <AsyncRoute exact path="/" load={loadHomePage} />
      <AsyncRoute exact path="/signup" load={loadSignupPage} />
      <AsyncRoute path="" load={loadNotFoundPage} />
    </Switch>
  );
}


export default (store, cb) => {
  const { injectReducer, injectSagas } = getAsyncInjectors(store);
  const importModules = Promise.all([
    import("./reducer"),
    import("./sagas"),
    import("./index")
  ]);

  importModules.then(([reducer, sagas, component]) => {
    injectReducer("signup", reducer.default);
    injectSagas(sagas.default);

    cb(component);
  });

  importModules.catch(errorLoading);
};

const render = messages => {
  ReactDOM.render(
    <Provider store={store}>
        <ConnectedRouter history={history}>
          <App />
        </ConnectedRouter>
    </Provider>,
    document.getElementById("app")
  );
};

假设您已使用react-router-redux将历史记录与redux存储区同步,则可以在主块中创建一个传奇,以从react-router-redux获取最新的LOCATION_CHANGE操作类型并刷新身份验证(将其存储在auth reducer中) )调用一些API。

要区分私有组件和公共组件,您可以修改Bundle ,使其阻止异步加载私有块,直到auth状态有效为止。

这是一些代码草图

传奇/ auth.js

import { LOCATION_CHANGE } from 'react-router-redux'

function *checkAuth() {
   yield put(authenticateStart())
   // Assuming using some token authentication
   const token = yield select(state => state.auth.token)
   const result = yield call(Api.refreshAuth, token)
   if (result.isAuthenticated) {
      yield put(authenticateSuccess(result.user)
   } else {
      // Need auth
      yield put(authenticateError())
   }
}
// Put this saga on main bundle
function *authSaga() {
    yield* takeLatest(LOCATION_CHANGE, checkAuth)
}

bundle.js

class Bundle extends Component {
  static contextTypes = {
    store: React.PropTypes.object
  };

  state = {
    // short for "module" but that's a keyword in js, so "mod"
    mod: null
  };

  componentWillMount() {
    if (this.props.isProtected && !this.props.isAuthenticated)
       return
    this.load(this.props);
  }

  /* istanbul ignore next */
  componentWillReceiveProps(nextProps) {
    // Modify similar to above
  }

  load(props) {
    this.setState({
      mod: null
    });
    props.load(this.context.store, mod => {
      this.setState({
        // handle both es imports and cjs
        mod: mod.default ? mod.default : mod
      });
    });
  }

  render() {
    // eslint-disable-next-line no-unused-vars
    const { load, ...otherProps } = this.props;
    return this.state.mod && <this.state.mod {...otherProps} />;
  }
}

export default connect(state => ({ isAuthenticated: state.auth.isAuthenticated }))(Bundle)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM