You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在React/Preact中传递条件子元素(即<If>组件)

这个问题我太熟了——很多人第一次写条件渲染的Wrapper组件都会踩这个坑!核心痛点在于:不管SomeWrapper内部要不要渲染子元素,JSX里的子元素表达式都会先执行。所以当condition不成立时,this.may.not.exist.unless.condition是undefined,调用.map()直接就会抛错。

下面给你几种实用的解决方案,按推荐程度排序:

1. 让Wrapper接收函数作为子元素(最优雅的方案)

把原本的静态/动态子元素改成一个函数,让Wrapper内部根据条件决定要不要调用这个函数。这样只有当条件成立时,动态计算的代码才会执行,从根源避免报错。

首先改造你的SomeWrapper组件:

function SomeWrapper({ some: condition, children }) {
  if (!condition) {
    return null; // 条件不满足时直接返回null,不渲染任何内容
  }
  
  // 如果需要用自定义元素包裹子元素,就换成:
  // return <YourCustomElement>{children()}</YourCustomElement>
  return children();
}

然后使用的时候,把动态内容放在函数里:

<SomeWrapper some={condition}>
  {() => (
    <ul>
      {this.may.not.exist.unless.condition.map(item => <li>{item}</li>)}
    </ul>
  )}
</SomeWrapper>

这样一来,只有当condition为true时,Wrapper才会调用这个函数,里面的.map()才会执行,完全不会触发undefined.map()的错误。

2. 在子元素内部提前做条件判断

如果不想修改Wrapper的结构,可以在子元素层面先检查condition,只有成立时才渲染动态内容:

<SomeWrapper some={condition}>
  {condition ? (
    <ul>
      {this.may.not.exist.unless.condition.map(item => <li>{item}</li>)}
    </ul>
  ) : null}
</SomeWrapper>

不过这种方式有点重复判断(Wrapper和子元素都检查了一次condition),如果Wrapper的逻辑复杂,后期维护容易出现不一致的问题,所以优先级不如第一种。

3. 使用renderProp替代子元素

和函数子元素逻辑类似,只是把函数放在单独的render属性里,写法上更明确:

改造Wrapper:

function SomeWrapper({ some: condition, render }) {
  if (!condition) return null;
  return render();
}

使用时:

<SomeWrapper 
  some={condition}
  render={() => (
    <ul>
      {this.may.not.exist.unless.condition.map(item => <li>{item}</li>)}
    </ul>
  )}
/>

这种方式和函数子元素效果完全一致,只是写法不同,看你个人习惯选择。

内容的提问来源于stack exchange,提问作者Tobia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 07:46:53