Javascript 如何包装在.map方法中重复的div
如何在一个包含div的.map函数中封装一个返回 我知道我可以将整个.map包装在一个div中,但是在.map中我有两个不同的返回,因为我有一个if语句来检查graphQL类型名是否存在。我的问题是,我想将的输出包装在父div中,该父div包装整个div输出,以便在其上使用显示网格。如果在.map中没有具有两个不同返回的if语句,我可以这样做,因为我不想只包装 这是我的地图Javascript 如何包装在.map方法中重复的div,javascript,html,reactjs,loops,jsx,Javascript,Html,Reactjs,Loops,Jsx,如何在一个包含div的.map函数中封装一个返回 我知道我可以将整个.map包装在一个div中,但是在.map中我有两个不同的返回,因为我有一个if语句来检查graphQL类型名是否存在。我的问题是,我想将的输出包装在父div中,该父div包装整个div输出,以便在其上使用显示网格。如果在.map中没有具有两个不同返回的if语句,我可以这样做,因为我不想只包装 这是我的地图 {data.datoCmsProject.projectBlock.map(projectEntry => {
{data.datoCmsProject.projectBlock.map(projectEntry => {
if (projectEntry.__typename === 'DatoCmsSingleProjectBlockContent') {
return (
<NewBlock key={projectEntry.id}>
Text Here
</NewBlock>
)
}
else{
return ( // I want every div outputted here to be wrapped in one containing div
<>
<BlockGridWrapper>
<BlockGrid key={projectEntry.id}>
<div>{projectEntry.titleOfGridSection}</div>
<Img fluid={projectEntry.imageOfGridBlock.fluid} />
</BlockGrid>
</BlockGridWrapper>
</>
)
}
})}
所以我希望它最终的格式如下所示
<div>
blockgridwrapper,
blockgridwrapper
</div>
newblock,
<div>
blockgridwrapper
</div>
newblock,
newblock,
newblock,
<div>
blockgridwrapper,
blockGridwrapper,
blockGridwrapper
</div>
第二个答案是我的回答
因此,根据相同的答案,这里是包装数据的console.log
0: Array(3)
0: {__typename: "DatoCmsSingleProjectBlockContent", id: "DatoCmsSingleProjectBlockContent-2018663-en", titleOfSection: "About Mussels", descriptionOfImage: "<h1><b>Heading 1</b></h1><p><span style="font-weig…DO: Anders and Riel Style</span></p></blockquote>", descriptionToggle: true, …}
1: {__typename: "DatoCmsSingleProjectBlockContent", id: "DatoCmsSingleProjectBlockContent-2018670-en", titleOfSection: "Test Title on top", descriptionOfImage: "<h1><b>Heading 1</b></h1><p><span style="font-weig…can see a list of things we did below.</span></p>", descriptionToggle: true, …}
2: {__typename: "DatoCmsSingleProjectBlockContent", id: "DatoCmsSingleProjectBlockContent-2018672-en", titleOfSection: "", descriptionOfImage: "", descriptionToggle: true, …}
length: 3
__proto__: Array(0)
1: Array(4)
0: {__typename: "DatoCmsProjectBlockGrid", id: "DatoCmsProjectBlockGrid-2043741-en", titleOfGridSection: "Test", imageOfGridBlock: {…}}
1: {__typename: "DatoCmsProjectBlockGrid", id: "DatoCmsProjectBlockGrid-2043742-en", titleOfGridSection: "Test #2", imageOfGridBlock: {…}}
2: {__typename: "DatoCmsProjectBlockGrid", id: "DatoCmsProjectBlockGrid-2043743-en", titleOfGridSection: "Test #3", imageOfGridBlock: {…}}
3: {__typename: "DatoCmsProjectBlockGrid", id: "DatoCmsProjectBlockGrid-2043744-en", titleOfGridSection: "Test #4", imageOfGridBlock: {…}}
现在如果我用下面的代码做嵌套映射
wrappedData.map(list => {
return (
<div>
{list.map(l =>
l._typeName === "DatoCmsSingleProjectBlockContent" ? (
<NewBlock >text1</NewBlock>
) : (
<BlockGridWrapper>
text2
</BlockGridWrapper>
)
)}
</div>
);
})
我得到了下面的html输出,但是根据三元运算符typeName检查,它应该显示两次。我圈出的地方应该是文本1内容而不是文本2内容的新块。否则我们就很接近我想要的结果了。当我在cms中测试时,只要它能处理它们以不同的顺序出现,而不仅仅是一排
如果在所有BlockGridWrapper组件之上,您对所有新块组件都满意,那么这应该是可行的。如果您不希望新块组件散布,那么应该包装连续的BlockGridWrapper组件组 您可以这样做:
let newBlockArr = [];
let blockgridArr = [];
data.datoCmsProject.projectBlock.forEach(v => {
if (v.__typename === 'DatoCmsSingleProjectBlockContent') {
newBlockArr.push( <NewBlock key={v.id}>Text Here</NewBlock> );
} else {
blockGridArr.push(
<BlockGridWrapper>
<BlockGrid key={v.id}>
<div>{projectEntry.titleOfGridSection}</div>
<Img fluid={v.imageOfGridBlock.fluid} />
</BlockGrid>
</BlockGridWrapper>
);
}
});
或者这个:
let newBlockArr = data.datoCmsProject.projectBlock.filter(v => v.__typename === 'DatoCmsSingleProjectBlockContent').map(v => ( <NewBlock key={v.id}>Text Here</NewBlock> ));
let blockgridArr = data.datoCmsProject.projectBlock.filter(v => v.__typename !== 'DatoCmsSingleProjectBlockContent').map(v => (
<BlockGridWrapper>
<BlockGrid key={v.id}>
<div>{projectEntry.titleOfGridSection}</div>
<Img fluid={v.imageOfGridBlock.fluid} />
</BlockGrid>
</BlockGridWrapper>
));
其次是:
return (
<div>{newBlockArr}</div>
<div>{blockgridArr}</div>
);
您正在执行if-else,因此您的BlockGridWrapper将无法在阵列中持续可用。您的映射数组可能看起来像
[
<BlockGridWrapper ... ,
<BlockGridWrapper ...,
< NewBlock ...,
<BlockGridWrapper...
]
好的,我想您可以创建一个连续元素数组,然后在它们上面运行循环。差不多
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];
}
}
};
const wrappedData = wrap(data.datoCmsProject.projectBlock);
/* wrappedData will look like (maintaining the order)
[
[
{__typename: 'DatoCmsSingleProjectBlockContent',...},
{__typename: 'DatoCmsSingleProjectBlockContent',...},
{__typename: 'DatoCmsSingleProjectBlockContent',...},
],
[
{__typename: 'NotDatoCmsSingleProjectBlockContent'},
{__typename: 'NotDatoCmsSingleProjectBlockContent'},
{__typename: 'NotDatoCmsSingleProjectBlockContent'}
],
[
{__typename: 'DatoCmsSingleProjectBlockContent',...},
{__typename: 'DatoCmsSingleProjectBlockContent',...},
],
// and so on
]
*/
Now in your render you gotta do a nested loop:
wrappedData.map(list => {
return (
<div>
{list.map(l =>
l._typeName === "DatoCmsSingleProjectBlockContent" ? (
<NewBLock />
) : (
<BlockWrapper />
)
)}
</div>
);
});
现在,通过分离映射,它们不一定是按顺序出现的,它们都在graphQL中的一个查询中,所以我需要它们按照在cms中输入的顺序出现。我将在上面添加我的查询。对于您的解决方案,我认为它会让所有的新块排成一行,然后是所有的notnewblock,但是如果它在cms中的顺序是那样的,它应该是交替的,这取决于。我将在上面添加我的查询,如果它有助于您理解我的用例,您是说如果您的所有BlockGridWrapper元素都出现在一行中,那么它们会出现吗?比如NewBlock,NewBlock,NewBlock,BlockGridWrapper,BlockGridWrapper,NewBlock,NewBlock,BlockGridWrapper,BlockGridWrapper,等等?没错,这都是变量,因为它们都是从cmshmm输入的,也许我解释得不对。我希望它能够去blockGridWrapper,newBlock,newBlock,blockGridWrapper。。。无论在cms中输入的顺序是什么,它们都应该出现在页面中。但是blockGridWrapper的开头和结尾应该始终有一个wrapping和closing div,因此如果它看起来像这个blockGridWrapper,blockgridwrappernewblock,blockgridwrappernewblock,newblock,newblock,blockGridWrapper,blockGridWrapper,BlockGridWrapper我希望BlockGridWrapper组件在进入cms时出现,这样就可以[newblock,BlockGridWrapper,BlockGridWrapper,newblock]等等。这有意义吗?对于第一部分,我尝试将wrappedData记录到控制台中,但我没有定义,我将代码放在组件const IndexPage={data}=>{在返回之前,当我控制台记录wrap中的内容时,它包含了我所有的数据console.logdata.datoCmsProject.projectBlock;我添加了控制台日志的输出,以查看这是否有助于调试为什么当我使用wrap函数时,将其放入变量中,而控制台日志中的变量未定义。哦,我认为我需要在函数中返回resn现在我得到了数组中的数据。好的,我现在要尝试第二部分。好的,因为某种原因,它在应该输出的时候输出。我将在上面添加一个输出html的屏幕截图。
const newBlocks = data.datoCmsProject.projectBlock.filter(projectEntry => projectEntry.__typename === 'DatoCmsSingleProjectBlockContent')
const notNewBlocks = data.datoCmsProject.projectBlock.filter(projectEntry => projectEntry.__typename !== 'DatoCmsSingleProjectBlockContent')
return (
<WhateverYourComponentIs>
...
{newBlocks.map(projectEntry =><NewBlock key={projectEntry.id}></NewBlock> )}
<div>{notNewBlocks.map(projectEntry => <BlockGridWrapper>...</BlockGridWrapper> )}</div>
</<WhateverYourComponentIs
)
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];
}
}
};
const wrappedData = wrap(data.datoCmsProject.projectBlock);
/* wrappedData will look like (maintaining the order)
[
[
{__typename: 'DatoCmsSingleProjectBlockContent',...},
{__typename: 'DatoCmsSingleProjectBlockContent',...},
{__typename: 'DatoCmsSingleProjectBlockContent',...},
],
[
{__typename: 'NotDatoCmsSingleProjectBlockContent'},
{__typename: 'NotDatoCmsSingleProjectBlockContent'},
{__typename: 'NotDatoCmsSingleProjectBlockContent'}
],
[
{__typename: 'DatoCmsSingleProjectBlockContent',...},
{__typename: 'DatoCmsSingleProjectBlockContent',...},
],
// and so on
]
*/
Now in your render you gotta do a nested loop:
wrappedData.map(list => {
return (
<div>
{list.map(l =>
l._typeName === "DatoCmsSingleProjectBlockContent" ? (
<NewBLock />
) : (
<BlockWrapper />
)
)}
</div>
);
});