Render Props

  • 概要: 属性中传入函数, 函数返回组件
  • 目的: 封装行为

demo

在如下例子中, 组件 PassState 即为承载公用逻辑的载体。组件 AppUseState 为使用方。

class PassState extends Component {
  constructor() {
    super()
    this.state = { name: 'muyy' }
  }

  render() {
    return (
      <>{this.props.render(this.state)}</>
    )
  }
}

class UseState extends Component {
  render() {
    const { state } = this.props
    return <>{state.name}</>
  }
}

class App extends Component {
  render() {
    return (
      <PassState
        render={(state) => (
          <UseState state={state} />
        )}
      />
    )
  }
}

这是官方摘取的 render Props 例子, 只要将 render 进行替换成 children, 可以发现日常使用它的情形就很寻常了。

class PassState extends Component {
  constructor() {
    super()
    this.state = { name: 'muyy' }
  }

  render() {
    return (
      <>{this.props.children(this.state)}</>
    )
  }
}

class UseState extends Component {
  render() {
    const { state } = this.props
    return <>{state.name}</>
  }
}

class App extends Component {
  render() {
    return (
      <PassState>
        {(state) => (
          <UseState state={state} />
        )}
      </PassState>
    )
  }
}

比如 beast-mobile 中 Matrix 组件就是这种形式。

render props 是否都适合转化为 Hooks

<Matrix dataSources={dataSources}>
  {({ src, index }) => {
    return (
      <div
        style={{
          padding: 10,
          background: '#ebebeb',
          borderRadius: 4,
          fontSize: '12px',
          color: '#666'
        }}
      >
        <div style={{ fontSize: '12px' }}> name: {src.name}</div>
        <div style={{ fontSize: '12px' }}> age: {src.age}</div>
        <div style={{ fontSize: '12px' }}> address: {src.address}</div>
        <div style={{ fontSize: '12px' }}> index: {index}</div>
      </div>
    )
  }}
</Matrix>

Matrix 组件用于在项目中自动调整行内布局, 该组件中 render props 的参数是和当前排列数有关, 与排列数相关的 render props 没有很好的办法转化为 Hooks, 因此 Render Props 还是有用武之地的。