compound component and render props

react 灵活 带来的模式也很多。

本篇主要是描述两种模式

  • compound component
  • render props

从例子了解痛点。

demo1.js simple case

可以看到一个组件内部自行使用子组件。

如果组件Container内部一旦有什么改动,那么整个Container就需要进行重写。

这样一来,组件复用就在恒定模式下复用,而不能灵活使用。


demo2.js

具体实现可以使用React.cloneElement进行对子组件的判断以及props state的注入。

我们如果将Container只是充当我们数据的提供者。

也就是说原有Container中的数据都提取到一层。将内部使用子组件部分提取出来。

  • Container(state, props)
    • Item (props)

====>

-Container (state, props)
– Container.item (props)

使用上的差异

<Contaner {...props} />
<Container ><Container.Item/></Container>

这样一来子组件就可以与上一层Container拆分,不过多耦合。


这样以来又引申到了另一个问题。

拆分后的

<Container ><Container.Item/></Container>

如果使用情况稍微改变一下

<Container>
<Container.Item/>
<div>
 <Item.Header />
  <Container.Item />
</div>
</Container>

demo3.js 例子演示

这样子的话React.children处理子组件的时候,Container.Item不再是直接子组件,这样子的情况会出现props丢失,结果不符合预期等情况。。

这样一来好像就牵扯出了一个问题。

类似于多层组件传值的问题。

react在当中有context api.

在局部范围内 Container,我们可以对Container原有的数据抽象为Container.context

在子组件Container.Item 利用context api 创建消费者进行获取。

这样以来,就可以避免由于原有子组件不是直接子组件所带来的问题。


compound component一般分几步。

  1. 直接使用时的组件状态
  2. 确定需要传递使用的props state
  3. 链接父组件与子组件

render props

上面说了,将父组件抽象为数据提供者用来做分离。

render props则是更抽象的分离。

一般来说,我们可以说render props 与 HOC基本是对等的。HOC能完成的render props也可以。

我们知道,react props可以传递函数 字符串等等。

那么我们也可以利用传递的props 回调函数返回jsx进行render。

这样一来,父组件就彻底沦为了数据的单一提供者,还有渲染的控制者。

渲染的细节完全取决于子组件本身传递的render props

官网也有描述render props的文档。可以进行查阅。

render props

render props hell

如果你常使用render props 很容易会发现一个很恐怖的render props hell

<Text>
  {(word) => {
    return (
      <Test word={word}>
        {(data) => {
          return <h1>data</h1>
        }}
      </Test>
    )
  }}
</Text>

类似以上描述。

我们可以将props callback 转化为函数,以函数调用尽可能的肉眼消除这些问题。

<Text>
  {this.handleRenderWord}
</Text>

all thanks !!

contact me !! hope your feedback

ZWKang@github

blog link


Contact Me

all encode by base64

  • Email: a2FuZzk1NjMwQGdtYWlsLmNvbQ==
  • QQ: OTA3NzQ3ODc0QHFxLmNvbQo=

转载需注明出处与作者

否则将被视为侵权

Reprinting must indicate the source and author

Otherwise it will be regarded as infringement

发表评论

电子邮件地址不会被公开。 必填项已用*标注