通过路由配置来实现全局业务管控。如只有登陆之后才能访问各个路由
react & react-router-dom $ mobx $ mobx-react
router.jsx 文件
关键的router文件,写主要场景逻辑
import React from 'react';
import {
Route, Redirect ,withRouter } from 'react-router-dom';
import {
inject, observer } from 'mobx-react';
import TopicList from '../components/topic-list/index';
import TopicDetail from '../components/topic-detail/index';
import TestApi from '../components/test/api-test';
import Homew from '../components/home/index';
import ListItems from '../components/topic-list/list-item';
import WrappedUserLogin from '../components/user-login/user-login';
/**
*
* @param isLogin 是否登陆,通常如果项目是react+mobx的项目,
* isLogin基本都是通过store传入,那么需要把store注入到这个方法中。
* 由于PrivateRoute 是一个 funcion 组件, 不是一个class 不能直使用注解注入,需要用函数的写法
* 有特殊的注入方式,下面一个方法会讲述到
* @param Component 使用大写是因为jsx文件的组件都是大写命名
* @param rest 其他属性全部放在此处
* @constructor
*/
const PrivateRoute = ({
isLogin, component: Component, ...rest }) => {
<Route
{
...rest} // 把传入的组件属性全部解构出来
render={
props => (
isLogin ?
<Component {
...props} /> :
<Redirect
to={
{
pathname: '/user/login', // 没有登陆跳回这个路由
search: `?from=${
rest.path}`, // 记录登陆之后需要跳回的路由路径
}}
/>
)
}
/>
}
/**
* 使用函数注入,和使用注解一样
*
* 因为使用mobx和react-router-dom 都是使用context去传入内容的
* 会存在一个问题,因为mobx会去修改组件
* observer(PrivateRoute) 执行时,会去修改组件的 shouldComponentUpdate
* 此时会和react-router-dom产生一定的冲突:当路由发生变化时,组件不会重新渲染.这个在react-rouer的官方文档中有提到
* 这个时候应该使用 withRouter 。当组件内容有更新时,强制更新组件.
* 该方法需要注意:在配合 shouldComponentUpdate 被修改的组件是哟弄个时,必须放在最外面
* @type {(React.FunctionComponent<P> & IWrappedComponent<IReactComponent>) | (React.ComponentClass<P> & IWrappedComponent<IReactComponent>) | (React.ClassicComponentClass<P> & IWrappedComponent<IReactComponent>)}
*/
const InjectedPriveRoute = withRouter(inject(((stores) => {
return {
login: stores.appState.user.login,
}
}))(observer(PrivateRoute)))
PrivateRoute.prototype = {
isLogin: PropTypes.bool,
component:PropTypes.element.isRequired,//专门来形容组件的
}
/**
* 如果没有传入isLogin 默认为false
* @type {
{isLogin: *}}
*/
PrivateRoute.defaultProps = {
isLogin: false