哈喽~我是刘十一,在了解withRouter之前我们先看看高阶组件吧。
什么是HOC
高阶组件(Higher-Ordercomponents)是 React 中用于复用组件逻辑的一种高级技巧。HOC 自身不是 React API 的一部分,它是一种基于 React 的组合特性而形成的设计模式。
具体而言,高阶组件是参数为组件,返回值为新组件的函数。
const EnhancedComponent = higherOrderComponent(WrappedComponent);
HOC的特点
- 是 React 中用于复用组件逻辑的一种高级技巧
- 自身不是 React API 的一部分,它是一种基于 React 的组合特性而形成的设计模式(一种组件的设计模式)
- 接受一个组件和额外的参数(如果需要),返回一个新的组件
- 纯函数,没有副作用
HOC的优缺点
- 优点∶ 逻辑复用、不影响被包裹组件的内部逻辑。
- 缺点∶ HOC传递给被包裹组件的props容易和被包裹后的组件重名,进而被覆盖
HOC的应用场景
- 代码复用,逻辑抽象
- 渲染劫持
- state 抽象和更改
- props 更改
withRouter作用
withRouter是一个高阶组件中(HOC), 其作用是将一个组件包裹进Route里面, 然后react-router的三个对象history, location, match就会被放进这个组件的props属性中,此时这个组件就具备了路由的属性。
应用场景
所以withRouter的应用场景就是, 当我们某个东西不是一个Router, 但是我们要依靠它去跳转一个页面, 比如点击页面的logo, 返回首页, 这时候就可以使用withRouter来完成。即,解决方法是将span使用withRouter作为一个可点击跳转的Link。
使用withRouter
比如app.js这个组件,一般是首页,不是通过路由跳转过来的,而是直接从浏览器中输入地址打开的,如果不使用withRouter此组件的this.props为空,没法执行props中的history、location、match等方法。
如何应用于项目中
import * as React from 'react'
import { withRouter } from 'react-router-dom'
const CustomerMessageSearchForm = (props: any) => {
return (
<div>
......
</div>
)
}
export default withRouter(CustomerMessageSearchForm)
1.避免更新受阻
// before
export default connect(mapStateToProps)(Something)
// after
import { withRouter } from 'react-router-dom'
export default withRouter(connect(mapStateToProps)(Something))
因为react-redux的connect高阶组件会为传入的参数组件实现shouldComponentUpdate 这个钩子函数, 导致只有prop发生变化时才触发更新相关的生命周期函数(含render)而很显然,我们的location对象并没有作为prop传入该参数组件。
2.在组件中意图使用history来控制路由跳转
import React from "react";
import {withRouter} from "react-router-dom";
class MyComponent extends React.Component {
...
myFunction() {
this.props.history.push("/some/Path");
}
...
}
export default withRouter(MyComponent);
如果我们不使用withRouter来处理(MyComponent),那么我们这里的this.props就取不到history,会报hitstory is undefiend之类的错。