移除 Div 包装器或更改 Class 嵌套地图中某些分组元素的名称

Remove Div Wrapper or change Class name on some grouped elements in a nested map

我从嵌套的 .map 中输出了以下 html,嵌套 .map 是根据来自使用 graphQL 查询的 cms 的数据从 for 循环构建的。

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

  2. 不同的 class 名称
  3. 我需要包装任何 BlockGridWrapper 组的 div 要么成为唯一一个包装 div 或具有与 NewBlock 的包装 div

  4. 不同的 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 包装器有一个 className依赖于那个类型名,但是嵌套循环发生在 div 包装器之后,所以我不知道如何实现这个

然后这是我的嵌套 .map。我需要包装 div 有一个基于类型名的条件 class 理想情况下只用于 BlockGridWrapper,但是我不能在 dividually 包装每个元素因为我需要它来包装整个块,但是对于 NewBlock 它是否具有包装 div 或是否具有不同的 className 都没有关系。但是我需要保留这些元素的顺序,因为它是从 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>
        );
      })
    }

Remove Div Wrapper or change Class name on some ...

扭转问题...不要呈现某事而不是删除某事

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

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

{
  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>
    );
  })
}

或 'removing div wrapper'(使用片段):

{
  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>)}
    );
  })
}

甚至 simpler/more 可读,比如:

{
  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>
    );

  })
}