React-Router
路由
- 下载插件
cnpm install react-router-dom --save-dev
- 创建几个jsx页面,然后创建一个router文件夹/index.js文件
import React, { Component } from 'react';
import { Route,browserHistory,HashRouter,Switch,Redirect } from 'react-router-dom';
import asyncComponent from '@/utils/asyncComponent';
import home from "@/pages/home/home";
const record = asyncComponent(() => import("@/pages/record/record"));
const recordId = asyncComponent(() => import("@/pages/recordId/recordId "));
const user = asyncComponent(() => import("@/pages/user/user"));
// 关于Route的exact,加上exact代表当前路由path的路径采用精确匹配
// 比如说Home的path如果不加上exact,那么path="/about"将会匹配他自己与path="/" 这两个,所以一般path="/" 一般会加上exact
// 另外需要注意一点的是嵌套路由不要加exact属性,如果父级路由加上,他下面的子路由将不会生效,因为外层强制匹配了
export default class RouteConfig extends Component{
render(){
return(
// 标签可以是 browserHistory 或者 HashRouter
// browserHistory不带#,HashRouter带#
<browserHistory>
<Switch>
<Route path="/" exact component={home} />
<Route path="/record" component={record} />
// 二级参数路由
<Route path="/record/:id" component={recordId} />
<Route path="/user" component={user}/>
<Redirect to="/" />
</Switch>
</browserHistory>
)
}
}
- 上面的异步加载组件的方法
// utils/asynvComponent.js
import React, { Component } from "react";
export default function asyncComponent(importComponent) {
class AsyncComponent extends Component {
state = {
component: null
}
async componentDidMount() {
const { default: component } = await importComponent();
this.setState({ component });
}
render() {
const C = this.state.component;
return C ? <C {...this.props} /> : null;
}
}
return AsyncComponent;
}
- 入口文件的修改
import React from 'react';
import ReactDOM from 'react-dom';
import Route from './router/';
const render = Component => {
ReactDOM.render(<Component />,document.getElementById('root'))
}
render(Route);
- 挂载路由后this的变化
// 增加了两个对象的属性
this.props.match
this.props.location
- 子路由
// user.js
import { Link, Switch, Route, Redirect } from 'react-router-dom';
...
render() {
return (
// 子路由建议写在父组件里,当路由满足子路由的条件,子组件就会显示出来
// 比如访问 /user 是看不到下面的组件的
// 访问/user/123 就可以看到了
<Switch>
<Route path={ this.props.match.path+"/:id" } component={ userDetail } />
</Switch>
);
}
...
- 标签路由和参数
// home.js
import { Link, Switch, Route, Redirect } from 'react-router-dom';
...
state = {
id : "abc123"
}
render() {
return (
<div>
<Link to="/home">home</Link>
<Link to={ this.state.id } >user</Link>
<Link to={ "/xxx/"+this.state.id } >xxx</Link>
<Link to={{ path:'/xxx', state: {k:v}, query: {k:v} }}>参数</Link>
</div>
);
}
...
- 方法路由和参数
this.props.history.push("/xxx")
this.props.history.replace("/xxx")
this.props.history.push({
pathname: "/xxx/" + this.state.id, state: {k:v}, query: {k:v}
});
// 冒号的传参
this.props.match.params.xx
// query的传参,可见
this.props.location.query.xx
// state的传参,不可见
this.props.location.state.xx
监听全局的路由变化,进行权限的判断等
- 没找到对应的方法
路由热更新
- 网上的教程需要改造webpack的配置,但是发现没这个文件,因为
react-scripts
把所有的配置都藏起来了 - 首先把脚手架的
.git
和.gitignore
文件删了 - 执行命令
npm run eject
选 y
- 安装
npm install --save-dev react-hot-loader
- config/webpack.config.js
entry: [
'react-hot-loader/patch', // 添加本行
require.resolve('./polyfills'),
require.resolve('react-dev-utils/webpackHotDevClient'),
paths.appIndexJs
]
- 入口文件index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import Route from './router/';
import { AppContainer } from 'react-hot-loader';
const render = Component => {
ReactDOM.render(
<AppContainer>
<Component />
</AppContainer>,
document.getElementById('root'),
)
}
render(Route);
// Webpack Hot Module Replacement API
if (module.hot) {
module.hot.accept('./router/', () => {
render(Route);
})
}
- 启动之后修改子组件内的数据,就不会刷新页面了