react-router4.2.0实用例子
代码分割
官网上面写的代码分割是不支持create-react-app脚手架的,要使用import实现
创建一个bundle.js文件
import { Component } from 'react'
class Bundle extends Component {
constructor(props) {
super(props);
this.state = {
mod: null
};
}
componentWillMount() {
this.load(this.props)
}
componentWillReceiveProps(nextProps) {
if (nextProps.load !== this.props.load) {
this.load(nextProps)
}
}
load(props) {
this.setState({
mod: null
});
props.load().then((mod) => {
this.setState({
mod: mod.default ? mod.default : mod
});
});
}
render() {
return this.state.mod ? this.props.children(this.state.mod) : null;
}
}
export default Bundle
假设有一个自己的子组件需要代码分割
demo.js
import React from 'react'
const MyComponent = () => (
<div>我是子组件</div>
)
export default MyComponent;
在需要代码分割的文件中导入这个Bundle
import Bundle from './test.js'
const MyComponent = (props) => (
<Bundle load={() => import('./demo.js')}>
{(MyComponent) => <MyComponent {...props} />}
</Bundle>
)
只有当MyComponent在文件中使用到了,才会去异步加载需要的组件
** 补充
如果你要和代码分割一起使用建议将Bundle.js文件修改成如下,如果不修改,亲测有bug
import React, { Component } from 'react'
class Bundle extends Component {
constructor() {
super()
this.state = {
mod: null
}
}
async componentDidMount() {
const {default: mod} = await this.props.load()
this.setState({
mod: mod.default || mod
})
}
render() {
return (
this.state.mod ? this.props.children(this.state.mod) : null
)
}
} export default Bundle
ScrollTop实现方式一
默认情况下,react中的组件在路由之间切换时不会默认回到页面的最顶部,这时需要自己动手编写一个组件实现这个功能
创建ScrollTop.js文件
import { Component } from 'react'
import { withRouter } from 'react-router'
class ScrollToTop extends Component {
componentDidUpdate(prevProps) {
if (this.props.location !== prevProps.location) {
window.scrollTo(0, 0)
}
}
render() {
return this.props.children
}
}
export default withRouter(ScrollToTop)
使用
import ScrollTop from './ScrollTop.js'
将router内部的子元素全部使用ScrollTop包裹即可
<Router>
<ScrollTop>
<div>
<div style={{"position":"fixed","top": 0,"left": 0}}>
<Link to="/a">组件一</Link>
<Link to="/b">组件二</Link>
</div>
<Route path="/a" component={Demo} />
<Route path="/b" component={Demo1} />
</div>
</ScrollTop>
</Router>
ScrollTop实现方式二
创建ScrollTop.js文件,添加如下内容
import { Component } from 'react'
import { withRouter } from 'react-router'
class ScrollToTopOnMount extends Component {
componentDidMount(prevProps) {
window.scrollTo(0, 0)
}
render() {
return null
}
}
export default ScrollToTopOnMount
使用
import ScrollToTopOnMount from './scrollTop.js'
将你原本的组件重新封装一个组件来使用即可
class LongContent extends React.Component {
render() {
return (
<div>
<ScrollToTopOnMount/>
<Demo />
</div>
)
}
}
路由之间的动画切换
结合react-transition-group插件使用,官方推荐,详细点击http://www.cnblogs.com/ye-hcj/p/7723104.html
demo如下
import React from 'react'
import ReactDOM from 'react-dom'
import {TransitionGroup,CSSTransition } from 'react-transition-group'
import { withRouter } from 'react-router'
import './index.css'
import {
BrowserRouter as Router,
Route,
Link,
Switch
} from 'react-router-dom'
const MyComponent1 = () => (
<div style={{"height": "200px","width": "200px","background": "red","position": "absolute","top": 0, "left": 0}}>我是组件一</div>
)
const MyComponent2 = () => (
<div style={{"height": "200px","width": "200px","background": "yellow","position": "absolute","top": 0, "left": 0}}>我是组件二</div>
)
const MyComponent3 = () => (
<div style={{"height": "200px","width": "200px","background": "green","position": "absolute","top": 0, "left": 0}}>我是组件三</div>
)
const AnimateComponent = withRouter(( {location} ) => (
<div>
<p><Link to="/a">组件一</Link></p>
<p><Link to="/b">组件二</Link></p>
<p><Link to="/c">组件三</Link></p>
<hr />
<TransitionGroup>
{/*这里使用location.key会在所有的路由之间使用相同的动画效果,如果你不想子路由也应用动画效果请使用location.pathname.split('/')[1]*/}
<CSSTransition key={location.key} timeout={500} classNames="fade" mountOnEnter={true} unmountOnExit={true}>
<div style={{"position": "relative","top": 0,"left": 0}}>
<Switch location={location}>
<Route path="/a" exact component={MyComponent1}/>
<Route path="/b" component={MyComponent2}/>
<Route path="/c" component={MyComponent3}/>
</Switch>
</div>
</CSSTransition>
</TransitionGroup>
</div>
))
class MyComponent extends React.Component {
render () {
return (
<Router>
<AnimateComponent></AnimateComponent>
</Router>
)
}
}
ReactDOM.render(
<MyComponent/>,
document.getElementById('root')
)
注:
你可能使用的动画
.fade-enter {
opacity: 0;
z-index: 1;
}
.fade-enter.fade-enter-active {
opacity: 1;
transition: opacity 250ms ease-in;
}