关于组件公共逻辑的抽离

  • mixin,已被 React 弃用
  • 高阶组件:HOC(high order component)
  • Render Props
  1. /* 高阶组件不是一种功能,而是一种模式 */
  2. const HOCFactory = (Component) => {
  3. class HOC extends React.Component {
  4. // 在此定义多个组件的公共逻辑
  5. render () {
  6. return <Component {...this.props} /> // 返回拼装结果
  7. }
  8. }
  9. return HOC;
  10. }
  11. const EnhancedComponent1 = HOCFactory(WrappedComponent1);
  12. const EnhancedComponent2 = HOCFactory(WrappedComponent2);
  1. // 高阶组件 假设处理鼠标位置为公共函数
  2. const withMouse = (Component) => {
  3. class withMouseComponent extends React.Component {
  4. constructor(props) {
  5. super(props)
  6. this.state = {
  7. x: 0,
  8. y: 0
  9. }
  10. }
  11. handleMouseMove = (event) => {
  12. this.setState({
  13. x: event.clientX,
  14. y: event.clientY
  15. })
  16. }
  17. render() {
  18. return (
  19. <div style={{height: 500px}} onMouseMove={this.handleMouseMove}>
  20. {/* 透传所有 props,增加 mouse 属性 */}
  21. <Component {...this.props} mouse={this.state} />
  22. </div>
  23. )
  24. }
  25. }
  26. return withMouseComponent;
  27. }
  28. const App = (props) => {
  29. const {x, y} = props.mouse // 接收 mouse 属性
  30. return (
  31. <div>the mouse position is {x}, {y}</div>
  32. )
  33. }
  34. export default withMouse(App) // 返回高阶组件

高阶组件是一种模式

render props

术语”render prop”是指一种在React组件之间使用一个值为函数的prop共享代码的简单技术

  1. // 通过一个函数将 class 组件的 state 作为 props 传递给纯函数组件
  2. class Factory extends React.Component {
  3. constructor() {
  4. this.state = {
  5. /* state 即多个组件的公共逻辑数据 */
  6. }
  7. }
  8. /* 修改 state */
  9. render() {
  10. return <div>{ this.props.render(this.state) }</div>
  11. }
  12. }
  13. const App = () => {
  14. <Factory render={
  15. /* render 是一个函数组件 */
  16. (props) => <p>{props.a} {props.b}</p>
  17. } />
  18. }
  1. class Mouse extends React.Component {
  2. constructor() {
  3. super(props)
  4. this.state = {x: 0, y: 0}
  5. }
  6. handleMouseMove = (event) => {
  7. this.setState({
  8. x: event.clientX,
  9. y: event.clientY
  10. })
  11. }
  12. render() {
  13. return <div onMouseMove={this.handleMouseMove}>
  14. {/* 将当前 state 作为 props,传递给 render,(render是一个函数组件) */}
  15. { this.props.render(this.state) }
  16. <div>
  17. }
  18. }
  19. Mouse.propTypes = {
  20. render: PropTypes.func.isRequired // 必须接受一个render属性,且是函数
  21. }
  22. const App = () => (
  23. <div>
  24. <Mouse render={
  25. ({x, y}) => <h1>the mouse position is {x}, {y}</h1>
  26. } />
  27. </div>
  28. )
  • HOC:模式简单,但会增加组件层级
  • Render Props:代码简介,学习成本较高
  • 按需使用