有时我需要创建一个包装元素,该元素将根据自己的逻辑显示其子元素(或不显示),可以选择将它们包装在自己选择的元素中:
<SomeWrapper some={condition}>
Hello
</SomeWrapper>
这是有效的,因为孩子(“你好”)是静态的。但是,如果要动态计算子级并且仅在条件成立时才可以明确定义,该怎么办?
<SomeWrapper some={condition}>
<ul>
{this.may.not.exist.unless.condition.map(item =>
<li key={item.id}>{item.text}</li>
)}
</ul>
</SomeWrapper>
在这里,如果条件为假并且包装元素不使用其子元素,它们仍将被创建并向下传递,浪费资源并可能在过程中引发错误。
一种解决方案(可能是最好的?)是将内容包装在自己的组件中:
<SomeWrapper some={condition}>
<InnerContent/>
</SomeWrapper>
这是因为(AFAIK,如果我错了,请纠正我)InnerContent 的构造函数和渲染将不会被调用,除非 SomeWrapper 实际决定使用它的属性children
。
但是如果我不想为 3 行代码创建一个组件怎么办?
我在野外看到了两种选择,没有一种特别吸引人:
传递一个 thunk 作为唯一的孩子:
<SomeWrapper some={condition}>{() => <ul> {this.may.not.exist.unless.condition.map(item => <li key={item.id}>{item.text}</li> )} </ul> }</SomeWrapper>
传递一个 thunk 作为道具:
<SomeWrapper some={condition} render={() => <ul> {this.may.not.exist.unless.condition.map(item => <li key={item.id}>{item.text}</li> )} </ul> }/>
我不喜欢它们,因为 lambda 给代码添加了视觉噪音,更不用说浪费资源了,在每次render()
执行时都会重新创建(AFAIK。)
还有其他我没有看到的解决方案吗?我应该总是使用 InnerContent 元素吗?