如何在 React / Preact(又名 <If> 组件)中传递条件子级

Posted

技术标签:

【中文标题】如何在 React / Preact(又名 <If> 组件)中传递条件子级【英文标题】:How to pass conditional children in React / Preact (aka. <If> component) 【发布时间】:2018-09-14 07:22:23 【问题描述】:

有时我需要创建一个包装器元素,它会根据自己的逻辑显示其子项(或不显示),可以选择将它们包装在自己选择的元素中:

<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,如果我错了,请纠正我)除非 SomeWrapper 真正决定使用其 children 属性,否则不会调用 InnerContent 的构造函数和渲染。

但是如果我不想为 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 元素吗?

【问题讨论】:

&lt;condition here&gt; &amp;&amp; ...map(item =&gt; &lt;li&gt;..&lt;/li&gt; )而不是添加Wrapper有什么问题吗? 我不会担心浪费资源。甚至反应新的上下文 API 使用渲染道具。 哦,有趣!我很好奇 &lt;condition here&gt; &amp;&amp; ...map(item =&gt; &lt;li&gt;..&lt;/li&gt; )是怎么浪费资源的?有条件不是不做图吗? @KennethTruong condition &amp;&amp; ... 不会浪费任何资源,但它会在 SomeWrapper 道具和 curly 表达式中重复条件表达式,我宁愿避免重复。 @TomaszMularczyk 你是说这个吗? &lt;SomeCtx.Consumer&gt;ctx =&gt; ...&lt;/SomeCtx.Consumer&gt; 这看起来很像我的示例 #1。你会说它比示例 #2 更惯用吗? 【参考方案1】:

您可以简单地执行以下操作

<Container> yourCondition === true && <ConditionalChildElement/> </Container>

【讨论】:

【参考方案2】:

看起来 render props 是一个东西,其实有一个 React 页面解释了它们的用法和最佳实践:

https://reactjs.org/docs/render-props.html

【讨论】:

以上是关于如何在 React / Preact(又名 <If> 组件)中传递条件子级的主要内容,如果未能解决你的问题,请参考以下文章

在 Preact 和 typescript 中使用 web 组件

如何将 React 路由器与 Preact 一起使用

Preact:React.js替代品?

如何使用 Preact 和 TypeScript 对子组件进行类型检查?

React 和 Preact diff 算法在深度上有啥区别

SciterSciter 结合 Preact 封装 图片查看器总结