我正在使用react
,我希望render
每隔一列新增一行。
我的代码:
function Product(props) {
const content = props.products.map((product) => (
<div className="row" key={product.id}>
<article key={product.id} className="col-md-3"></article>
</div> )
);
return (
<div>
{content}
</div>
);
}
我通过传递一个看起来像这样的条件尝试了这个方法:
if (product.id % 4 == 1)
,在列周围,但它不起作用......
这就是我想要发生的事情:
<div class="row">
<div class="col-md-3"></div>
<div class="col-md-3"></div>
<div class="col-md-3"></div>
<div class="col-md-3"></div>
</div>
<div class="row">
<div class="col-md-3"></div>
<div class="col-md-3"></div>
<div class="col-md-3"></div>
<div class="col-md-3"></div>
</div>
答案 0 :(得分:8)
将您的产品分组为(最多)4个元素,即
[1,2,3,4,5,6,7,8] => [ [1, 2, 3, 4], [5, 6, 7, 8 ] ]
迭代组以生成行,并在内部循环中迭代项目以显示列
要计算每行4个项目的行数,请使用Math.ceil(props.products.length / 4)
。然后创建一个行数组。给定2行(8个项目):Array(2)
。由于您无法map
未初始化元素数组,因此您可以使用扩展语法:[...Array(2)]
返回[ undefined, undefined ]
。
现在,您可以将这些undefined
条目映射到行中:对于每一行,从产品中获取4个元素:[ undefined, undefined ].map( (row, idx) => props.products.slice(idx * 4, idx * 4 + 4) ) )
(编辑注释更改为slice
,因为{ {1}}改变原始数组)。结果是一个数组数组(项目行)。
您可以迭代行,并在每次迭代内迭代给定行中的项目。
https://jsfiddle.net/dya52m8y/2/
splice
答案 1 :(得分:7)
这样写:
function Product(props) {
let content = [];
props.products.forEach((product, i) =>{
if((i+1) % 4 == 0){
content.push(
<div className="row" key={product.id}>
<article key={product.id} className="col-md-3"></article>
</div>
)
}else{
content.push(<article key={product.id} className="col-md-3"></article>);
}
});
return (
<div>
{content}
</div>
);
}
答案 2 :(得分:1)
你想为每4列包装新行,对吗?
试试这个
render() {
const products = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let rowContents = [];
const contents = products.reduce((acc, p, i) => {
rowContents.push(<div key={i} className="col col-md-3">Col {p}</div>);
if (i % 4 === 3) {
acc.push(<div className="row">{rowContents}</div>);
rowContents = [];
}
return acc;
},[])
contents.push(<div className="row">{rowContents}</div>);
return (
<div>
{contents}
</div>
)
}
答案 3 :(得分:1)
Bootstrap的好处是,您可以将所有col*
保留为单个 row
,然后每4个插入一个全角div
列以强制换行。这些使事情变得更简单,您不必分块数据。
这是React渲染的样子:
render() {
let columns=[];
this.props.items.forEach((item,idx) => {
// push column
columns.push(
<div className="col-sm py-3" key={idx}>
Content
</div>
)
// force wrap to next row every 4 columns
if ((idx+1)%4===0) {columns.push(<div className="w-100"></div>)}
})
return (
<div className="row">
{columns}
</div>
)
}
演示: https://www.codeply.com/go/VMV26jhHFz
注意:在 Bootstrap 4 中,使用<div className="w-100"></div>
,如上所示。在引导程序3 中,使用<div className="clearfix"></div>
强制列包装每个 n 。
答案 4 :(得分:0)
您可以这样做:
render() {
function toChunkArray(myArray: any, chunkSize: any): any {
var results = [];
while (myArray.length) {
results.push(myArray.splice(0, chunkSize));
}
return results;
}
let chunkedArraysOfColSize = toChunkArray(myList, 3);
return (
<div className="row">
{
chunkedArraysOfColSize.map( (colSizeArray, index) =>
<div className="col-sm-4" key={index.toString()}>
{colSizeArray.map((o, i) =>
<NameOfComponent key={o.Id} obj={o} />
)}
</div>
)
}
</div>
);
}
答案 5 :(得分:0)
你可以有一行,所有列(col-md-3)都可以进入。要在每个第4列之后实现多行效果,您可以将样式设置为每个第4列,如下所示 -
<div className="col-md-3" style={{clear: (index != 0 && index % 4 == 0) ? 'both' : 'none'}}></div>
这将获得与具有多行相同的结果。
答案 6 :(得分:0)
当前所有答案似乎并不是Silly, Stupid,因为那里只关注一次打印一组项目,而没有考虑对具有不同项目数量的行的进一步处理。以下答案使用打字稿,但可以在香草JS中简单实现。我也使用lodash chunk
作为一种便利,尽管您自己的分块方法很容易在需要时添加。
import * as _ from 'lodash'
export enum flexChunkOptions {
col1 = 12,
col2 = 6,
col3 = 4,
col4 = 3,
col6 = 2,
col12 = 1
}
export const chunkIntoFlexgrid = (numbOfItemsInRow: flexChunkOptions, arrayOfItems: ArrayLike<any>) => {
return _.chunk(arrayOfItems, numbOfItemsInRow)
}
在上面的代码中,我们创建了一个枚举,该枚举具有所有可被12整除的引导程序列定义。这样做很简单,因此我们可以轻松地在模板中使用相应的col定义。我们期望接收到任何类型的项的数组(ts用户ArrayLike<any>
的类型安全性要比any
更好)。之后,如果我们选择[[1,2,3], [1,2,3]]
,我们将返回一个分块的数组,类似于col-3
。
const myArrOfItems = [1, 2, 3, 4, 5, 6, 7, 8]
{chunkIntoFlexgrid(flexChunkOptions.col3, mySetOfItems).map((el, i) => {
return <div key={ `row-${ i }` } className={ `row` }>
{
el.map(item => item)
}
</div>
})
在我们的模板中,我们可以简单地调用我们的connncence方法,并提供我们希望如何生成行的方法,并且可以简单地使用外部el
变量来处理单个元素。