【React】antd <Row> <Col> 动态添加问题
问题描述
对一个数组进行动态JSX拼接,目前是三条数据需要用Row包裹起来。
问题出现的环境背景及自己尝试过哪些方法
实现row和col的动态生成,我试过动态拼接,可是编译不过去.
相关代码
// 请把代码文本粘贴到下方(请勿用图片代替代码)
const formItems = data.map((item) => (
<FormItem label={item.name} key={item.name}><Row>
{item.list.map((value) => <Col span={8}><Checkbox key={value.name}>{value.name}</Checkbox></Col>)}
</Row>
</FormItem>
));
你期待的结果是什么?实际看到的错误信息又是什么?
我希望的是<Row><Col/><Col/><Col/></Row>目前是<Row><Col/>...</Row>这样的结果
回答
遇到同样的问题,而且想想其实也是常见的场景,经过半天周折做出的自己的解决方案,希望群策群力,提出更优的方案。
背景:对一个数组进行动态JSX拼接,目前是三条数据需要用Row包裹起来。
场景:原项目中对于这里的处理是穷举法,对所有的Col做写死三个一个Row,写出形式如下:
<div> <Row>
<Col span="8">
<FormItem {...formItemLayout} label="真实姓名:">
<Input {...getFieldProps('realName', { initialValue: '' }) } disabled={true} style={{border:'none', background:'#FFF', display:'block'}}/>
</FormItem>
</Col>
<Col span="8">
<FormItem {...formItemLayout} label="性别:">
<Input {...getFieldProps('sex', { initialValue: '' }) } disabled={true} style={{border:'none', background:'#FFF', display:'block'}}/>
</FormItem>
</Col>
<Col span="8">
<FormItem {...formItemLayout} label="年龄:">
<Input {...getFieldProps('age', { initialValue: '' }) } disabled={true} style={{border:'none', background:'#FFF', display:'block'}}/>
</FormItem>
</Col>
</Row>
<Row>
<Col span="8">
<FormItem {...formItemLayout} label="身份证号码:">
<Input {...getFieldProps('idNo', { initialValue: '' }) } disabled={true} style={{border:'none', background:'#FFF', display:'block'}}/>
</FormItem>
</Col>
<Col span="8">
<FormItem {...formItemLayout} label="银行卡号:">
<Input {...getFieldProps('cardNo', { initialValue: '' }) } disabled={true} style={{border:'none', background:'#FFF', display:'block'}}/>
</FormItem>
</Col>
<Col span="8">
<FormItem {...formItemLayout} label="所属银行:">
<Input {...getFieldProps('bank', { initialValue: '' }) } disabled={true} style={{border:'none', background:'#FFF', display:'block'}}/>
</FormItem>
</Col>
</Row>
...
</div>
这样写的问题显而易见,变动成本很高,如果要在原有布局上中间插入一个新的Col,需要手动把该项后面的Col依次推后一位,大量的手工劳动(这样写代码真的是在搬砖),好处也有,就是代码直观易懂,新手也能上手改动,代码的格式就能直观映射出在屏幕上的布局。
分析:这里无非就是想对一个可能变动的数组进行三个一组显示一行,超出三个的换行显示
思路:
1、对数据分组
2、遍历分组后的数组生成Dom
3、在JSX中渲染显示
具体步骤:
1、数组如下
const rowList = [ {
label: '真实姓名:',
propKey: 'realName',
},
{
label: '性别:',
propKey: 'sex',
},
{
label: '年龄:',
propKey: 'age',
},
{
label: '身份证号码:',
propKey: 'idNo',
},
{
label: '银行卡号:',
propKey: 'cardNo',
},
{
label: '所属银行:',
propKey: 'bank',
},
...
]
数组中的键仅保留标示性的属性,这样在增加新的数组项时可以保证最少改动,对于公共属性做数组遍历添加
// 为单元对象统一添加属性for (let i = 0; i < rowList.length; i++) {
const eachObj = rowList[i];
if (eachObj.initialValue === undefined) {
eachObj.initialValue = '';
}
if (eachObj.disabled === undefined) {
eachObj.disabled = true;
}
if (eachObj.style === undefined) {
eachObj.style = {border:'none', background:'#FFF', display:'block'}
}
}
对数组进行遍历,把三个放入一组
for (let i = 0; i < rowList.length; i++) { if (i % 3 === 0) {
const rowObjFirst = rowList[i];
const rowObjSecond = rowList[i+1];
const rowObjThird = rowList[i+2];
tableDomList.push({
<Col span="8">
<FormItem {...formItemLayout} label={rowObjFirst.label}>
<Input {...getFieldProps(rowObjFirst.propKey, { initialValue: rowObjFirst.initialValue }) }
disabled={rowObjFirst.disabled}
style={rowObjFirst.style}/>
</FormItem>
</Col>
<Col span="8">
<FormItem {...formItemLayout} label={rowObjSecond.label}>
<Input {...getFieldProps(rowObjSecond.propKey, { initialValue: rowObjSecond.initialValue }) }
disabled={rowObjSecond.disabled}
style={rowObjSecond.style}/>
</FormItem>
</Col>
<Col span="8">
<FormItem {...formItemLayout} label={rowObjThird.label}>
<Input {...getFieldProps(rowObjThird.propKey, { initialValue: rowObjThird.initialValue }) }
disabled={rowObjThird.disabled}
style={rowObjThird.style}/>
</FormItem>
</Col>
})
}
}
遍历分组后的数组生成Dom
tableDom = tableDomList.map((ele) => { return ele
})
渲染显示
return ( <Form horizontal form={this.props.form} style={{ marginTop: '20' }}>
<div className="navLine-wrap-left">
<h2>基本信息</h2>
{
tableDom
}
</div>
</Form>
)
总结:这种方案很明显还不够最优,并没有做到DRY(Don't repeat yourself),代码中还充斥着雷同部分,可以做进一步抽象优化,但是相比较原先穷举的方案,改良后对于数据变更的处理可以少一些手动改动,在变动较小的情况下,可以直接在数组需要插入的位置直接添加数据项即可,该程序会自动遍历数据项做三个一组分组进行显示
Ref:示例中使用到Antd的行列布局,即对空间的横向以Col分割,纵向按Row划分,所以才产生了这个场景,开发者可以针对自己需要的分组布局,对数据进行分组处理,做类似上面的显示布局
你要的是不是这个效果...,imgs参数是图片,自己弄个几个链接就行了...
const imgCols = []; for (let i = 0; i < imgs.length; i+=3) {
const rowArr = imgs.slice(i, i+3);
const ele = (
<>
<Row>
{
rowArr.map((item, j)=>{
return (
<Col md={8} sm={24} key={j+i}>
<img src={item} width="100%" style={{border:'1px solid #ddd', borderRadius:10}}/>
</Col>
)
})
}
</Row>
</>
)
imgCols.push(ele);
}
以上是 【React】antd <Row> <Col> 动态添加问题 的全部内容, 来源链接: utcz.com/a/72528.html