首页 > 解决方案 > 删除 Div Wrapper 或更改嵌套地图中某些分组元素的类名称

问题描述

我有以下从嵌套输出的 html,该嵌套.map是根据从使用 graphQL 查询的 cms 传入的数据从 for 循环构造的。

在此处输入图像描述

  1. 我需要任何 div 包装删除任何 NewBlock 部分,或者我需要它们具有与 BlockGridWrapper 元素的包装 div 不同的类名

  2. 我需要包装任何 BlockGridWrapper 组的 div 要么是唯一具有包装 div 的组,要么具有与 NewBlock 的包装 div 不同的 className

这是构造数据数组的 for 循环

const wrap = data => {
    const res = [[data[0]]];
    let curr = data[0];
    // let curr = 0;
    let idx = 0;
    for (let i = 1; i < data.length; i++) {
      if (data[i].__typename === curr.__typename) {
        res[idx].push(data[i]);
      } else {
        curr = data[i];
        idx += 1;
        res[idx] = [curr];
      }
    }
    return res
  };

  const wrappedData = wrap(data.datoCmsProject.projectBlock);

这是console.log wrappedData的输出,所以我正在检查一个类型名,理想情况下我想要的是div包装器有一个依赖于该类型名的类名,但是嵌套循环发生在div包装器之后,所以我我对如何实现这一点感到困惑

在此处输入图像描述

然后这是我的嵌套.map. 我需要包装 div 有一个基于类型名的条件类,理想情况下仅适用于BlockGridWrapper,但是我不能让它单独包装每个元素,因为我需要它来包装整个块,但NewBlock它是否有一个包装div或者如果它有不同的类名都可以。但是我需要保留这些元素的顺序,因为它是从 cms 填充的。

{
      wrappedData.map(list => {
        return (    
          <div>   //I Need this div to have a conditional class based on the typename                  
            {list.map(l =>         
              l.__typename === "DatoCmsSingleProjectBlockContent" ? (
                <NewBlock >text1</NewBlock>
              ) : (
                <BlockGridWrapper>
                  text2
                </BlockGridWrapper>
              )
            )           
            }
          </div>
        );
      })
    }

标签: javascripthtmlreactjsloopscontent-management-system

解决方案


删除 Div Wrapper 或更改某些 ...

扭转问题......不要渲染 sth 而不是 remove sth

从那时起,我们就面临着常见的条件渲染问题。

在这种情况下(数据结构),我们可以简单地检查循环之前第一个元素的类型

{
  wrappedData.map(list => {
    let isNewBlock = list[0].__typename === "DatoCmsSingleProjectBlockContent"
    return (    
      {isNewBlock ? (<div class="nb">) : (<div>)}
        {list.map(l =>         
          l.__typename === "DatoCmsSingleProjectBlockContent" ? (
            <NewBlock >text1</NewBlock>
          ) : (
            <BlockGridWrapper>
              text2
            </BlockGridWrapper>
          )
        )           
        }
      </div>
    );
  })
}

或“删除 div 包装器”(使用片段):

{
  wrappedData.map(list => {
    let isNewBlock = list[0].__typename === "DatoCmsSingleProjectBlockContent"
    return (    
      {isNewBlock ? (<>) : (<div>)}
        {list.map(l =>         
          l.__typename === "DatoCmsSingleProjectBlockContent" ? (
            <NewBlock >text1</NewBlock>
          ) : (
            <BlockGridWrapper>
              text2
            </BlockGridWrapper>
          )
        )           
        }
      {isNewBlock ? (</>) : (</div>)}
    );
  })
}

甚至更简单/更具可读性,例如:

{
  wrappedData.map(list => {
    let isNewBlock = list[0].__typename === "DatoCmsSingleProjectBlockContent"
    if (isNewBlock) return (    
      <>
        {list.map(l => (
            <NewBlock >{l.titleOfSection}</NewBlock>
          )
        )
        }
      </>
    );
    // the rest - notice different 'fieldset'
    return (    
      <div>
        {list.map(l => (
            <BlockGridWrapper>{l.titleOfGridSection}</BlockGridWrapper>
          )
        )
        }
      </div>
    );

  })
}

推荐阅读