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

如何在React JSX中实现类似ERB的列表分栏渲染?

在JSX中实现列表分栏的方案

背景

我习惯传统后端开发风格,使用ERB这类服务端模板时,可编写如下代码实现列表分栏:

@items = ['South Africa', 'Zimbabwe', 'Zambia', 'Egypt', 'Malawi']
<div class="columns">
  <div class="column">
    <%- @items.each_with_index do |item, index| -%>
      <% if (index >= @items.length / 2) %>
        </div><div class="column">
      <% end %>
      <div class="menu-item">
        <%= item %>
      </div>
    <%- end -%>
  </div>
</div>

这段代码最终能生成合法HTML文档,但编译阶段代码本身并不合法。而React JSX不支持此类写法,比如以下手动编写的尝试存在语法错误:

const items = ['South Africa', 'Zimbabwe', 'Zambia', 'Egypt', 'Malawi']
<div className="columns">
  <div className="column">
    {items.map((item, index) => {
      {(index === items.length / 2) ? </div><div className="column"> : null}
      <div className="menu-item">
        {item}
      </div>
    })}
  </div>
</div>

使用dangerouslySetInnerHTML也无法满足需求,因为需要额外包裹元素,会破坏原有结构。请问如何在JSX中实现该列表分栏功能?


可行实现方案

方案1:先分割数组再渲染

JSX要求结构必须闭合且符合语法,最直接的方式是先把原数组拆分为两个子数组,再分别渲染对应的列:

const items = ['South Africa', 'Zimbabwe', 'Zambia', 'Egypt', 'Malawi'];
// 向上取整,保证前栏元素数量不小于后栏
const splitIndex = Math.ceil(items.length / 2);
const firstColumnItems = items.slice(0, splitIndex);
const secondColumnItems = items.slice(splitIndex);
<div className="columns">
  <div className="column">
    {firstColumnItems.map(item => (
      <div className="menu-item" key={item}>
        {item}
      </div>
    ))}
  </div>
  <div className="column">
    {secondColumnItems.map(item => (
      <div className="menu-item" key={item}>
        {item}
      </div>
    ))}
  </div>
</div>

方案2:动态生成列数组(支持多栏扩展)

如果需要支持更多分栏,可以先把原数组按指定栏数拆分为多维数组,再批量渲染列:

const items = ['South Africa', 'Zimbabwe', 'Zambia', 'Egypt', 'Malawi'];
const columnCount = 2; // 可按需修改为3、4等
const itemsPerColumn = Math.ceil(items.length / columnCount);
const columns = [];

for (let i = 0; i < columnCount; i++) {
  columns.push(items.slice(i * itemsPerColumn, (i + 1) * itemsPerColumn));
}
<div className="columns">
  {columns.map((columnItems, idx) => (
    <div className="column" key={idx}>
      {columnItems.map(item => (
        <div className="menu-item" key={item}>
          {item}
        </div>
      ))}
    </div>
  ))}
</div>

方案3:用React.Fragment处理连续元素(不推荐)

如果想要接近ERB“中途切换容器”的写法,可利用React.Fragment(或简写<>)包裹逻辑,但这种写法可读性差、易出错,仅作兼容场景参考:

<div className="columns">
  {items.map((item, index) => {
    const splitIndex = Math.floor(items.length / 2);
    return (
      <>
        {/* 在分割点处渲染新列的开头 */}
        {index === splitIndex && <div className="column" />}
        <div className="menu-item" key={item}>
          {item}
        </div>
        {/* 在分割点前渲染前列的结尾 */}
        {index === splitIndex - 1 && </div>}
      </>
    );
  })}
</div>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 13:54:23