关于组件公共逻辑的抽离

  • mixin,已被React弃用
  • 高阶组件HOC
  • Render Props

什么是高阶组件

高阶组件就是一个函数,传给它一个组件,它返回一个新的组件。新的组件使用传入的组件作为子组件。
高阶组件的作用是用于代码复用,可以把组件之间可复用的代码、逻辑抽离到高阶组件当中。新的组件和传入的组件通过 props 传递信息。

HOC

  1. import React from 'react'
  2. // 高阶组件
  3. const withMouse = (Component) => {
  4. class withMouseComponent extends React.Component {
  5. constructor(props) {
  6. super(props)
  7. this.state = { x: 0, y: 0 }
  8. }
  9. handleMouseMove = (event) => {
  10. this.setState({
  11. x: event.clientX,
  12. y: event.clientY
  13. })
  14. }
  15. render() {
  16. return (
  17. <div style={{ height: '500px' }} onMouseMove={this.handleMouseMove}>
  18. {/* 1. 透传所有 props 2. 增加 mouse 属性 */}
  19. <Component {...this.props} mouse={this.state}/>
  20. </div>
  21. )
  22. }
  23. }
  24. return withMouseComponent
  25. }
  26. const App = (props) => {
  27. const { x, y } = props.mouse // 接收 mouse 属性
  28. return (
  29. <div style={{ height: '500px' }}>
  30. <h1>The mouse position is ({x}, {y})</h1>
  31. </div>
  32. )
  33. }
  34. export default withMouse(App) // 返回高阶函数

Render Props

render props的核心思想通过一个函数将class组件的state作为props传递给纯函数组件

  1. import React from 'react'
  2. import PropTypes from 'prop-types'
  3. class Mouse extends React.Component {
  4. constructor(props) {
  5. super(props)
  6. this.state = { x: 0, y: 0 }
  7. }
  8. handleMouseMove = (event) => {
  9. this.setState({
  10. x: event.clientX,
  11. y: event.clientY
  12. })
  13. }
  14. render() {
  15. return (
  16. <div style={{ height: '500px' }} onMouseMove={this.handleMouseMove}>
  17. {/* 将当前 state 作为 props ,传递给 render (render 是一个函数组件) */}
  18. {this.props.render(this.state)}
  19. {/* 或者 */}
  20. {/* {this.props.children(this.state)} */}
  21. </div>
  22. )
  23. }
  24. }
  25. Mouse.propTypes = {
  26. render: PropTypes.func.isRequired // 必须接收一个 render 属性,而且是函数
  27. }
  28. const App = (props) => (
  29. <div style={{ height: '500px' }}>
  30. <Mouse render={
  31. /* render 是一个函数组件 */
  32. ({ x, y }) => <h1>The mouse position is ({x}, {y})</h1>
  33. }/>
  34. {/*或者*/}
  35. {/*<Mouse>
  36. {(x,y)=><h1>The mouse position is ({x}, {y})</h1>}
  37. </Mouse>*/}
  38. </div>
  39. )
  40. /**
  41. * 即,定义了 Mouse 组件,只有获取 x y 的能力。
  42. * 至于 Mouse 组件如何渲染,App 说了算,通过 render prop 的方式告诉 Mouse 。
  43. */
  44. export default App

HOC vs Render Props

  • HOC:模式简单,但会增加组件层级
  • Render Props:代码简洁,学习成本较高
  • 按需使用