关于组件公共逻辑的抽离
- mixin,已被 React 弃用
- 高阶组件:HOC(high order component)
- Render Props
/* 高阶组件不是一种功能,而是一种模式 */
const HOCFactory = (Component) => {
class HOC extends React.Component {
// 在此定义多个组件的公共逻辑
render () {
return <Component {...this.props} /> // 返回拼装结果
}
}
return HOC;
}
const EnhancedComponent1 = HOCFactory(WrappedComponent1);
const EnhancedComponent2 = HOCFactory(WrappedComponent2);
// 高阶组件 假设处理鼠标位置为公共函数
const withMouse = (Component) => {
class withMouseComponent extends React.Component {
constructor(props) {
super(props)
this.state = {
x: 0,
y: 0
}
}
handleMouseMove = (event) => {
this.setState({
x: event.clientX,
y: event.clientY
})
}
render() {
return (
<div style={{height: 500px}} onMouseMove={this.handleMouseMove}>
{/* 透传所有 props,增加 mouse 属性 */}
<Component {...this.props} mouse={this.state} />
</div>
)
}
}
return withMouseComponent;
}
const App = (props) => {
const {x, y} = props.mouse // 接收 mouse 属性
return (
<div>the mouse position is {x}, {y}</div>
)
}
export default withMouse(App) // 返回高阶组件
高阶组件是一种模式
render props
术语”render prop”是指一种在React组件之间使用一个值为函数的prop共享代码的简单技术
// 通过一个函数将 class 组件的 state 作为 props 传递给纯函数组件
class Factory extends React.Component {
constructor() {
this.state = {
/* state 即多个组件的公共逻辑数据 */
}
}
/* 修改 state */
render() {
return <div>{ this.props.render(this.state) }</div>
}
}
const App = () => {
<Factory render={
/* render 是一个函数组件 */
(props) => <p>{props.a} {props.b}</p>
} />
}
class Mouse extends React.Component {
constructor() {
super(props)
this.state = {x: 0, y: 0}
}
handleMouseMove = (event) => {
this.setState({
x: event.clientX,
y: event.clientY
})
}
render() {
return <div onMouseMove={this.handleMouseMove}>
{/* 将当前 state 作为 props,传递给 render,(render是一个函数组件) */}
{ this.props.render(this.state) }
<div>
}
}
Mouse.propTypes = {
render: PropTypes.func.isRequired // 必须接受一个render属性,且是函数
}
const App = () => (
<div>
<Mouse render={
({x, y}) => <h1>the mouse position is {x}, {y}</h1>
} />
</div>
)
- HOC:模式简单,但会增加组件层级
- Render Props:代码简介,学习成本较高
- 按需使用