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 还是有用武之地的。