//最高和最低楼层输入框组件
function FloorInterval({ handleSave }) {
const [priceItems, setPriceItems] = useState([{ base_price: '' }]);
const addMore = () => {
const a = [...priceItems];
a.push({ base_price: '' });
setPriceItems(a);
};
function subtraction(index) {
const a = [...priceItems];
const newPriceItems = a.filter((_, i) => i !== index);
setPriceItems(newPriceItems);
handleSave(newPriceItems);
}
function handleChange(index, type, value) {
const a = [...priceItems];
a[index][type] = value;
setPriceItems(a);
handleSave(priceItems);
}
return (
<div className="append-container">
{priceItems.map(({ base_price, min_floor, max_floor }, index) => (
<div className="append-last" key={index}>
<div style={{ display: 'flex' }}>
<Form.Item label="市场价" style={{ marginBottom: 0 }}>
<Input
style={{ width: '184px' }}
defaultValue={base_price}
name="priceList[index].base_price"
placeholder="市场价"
onChange={(e) =>
handleChange(index, 'base_price', Number(e.target.value))
}
/>
</Form.Item>
<span> </span>
<Form.Item label="楼层区间" style={{ marginBottom: 0 }}>
<Input
defaultValue={min_floor}
placeholder="最小值"
name="min_floor"
style={{ width: '65px' }}
onChange={(e) =>
handleChange(index, 'min_floor', Number(e.target.value))
}
/>
<span>--</span>
<Input
defaultValue={max_floor}
placeholder="最大值"
name="max_floor"
style={{ width: '65px' }}
onChange={(e) =>
handleChange(index, 'max_floor', Number(e.target.value))
}
/>
</Form.Item>
<span> </span>
{index === 0 ? (
<div>
<Button
type="primary"
shape="circle"
size="small"
onClick={addMore}
> + </Button>
</div>
) : (
<div>
<Button
type="danger"
shape="circle"
size="small"
onClick={() => subtraction(index)}
> -</Button>
</div>
)}
</div>
</div>
))}
</div>
);
}
组件对应的内容就是
现在的问题:
点击第二行的减号按钮之后,列表中删掉的是index为1 的数据,但是页面中删除的永远是最后一行?
很好的一个问题!
正好碰到过一个类似的问题,简单说,你的key序列会在删掉一行后由1,2,3,4,变为1,2,3
React复用了原先的1,2,3,即使你的数组内容是原先的1,2,4
其实你的数据是正常更新的,只是input内的内容不对。虽然没有测试,但如果你将数据放到文本标签中应该是能正常显示的,所以这应该属于Antd的一个bug/特性。
解决方案是不要重用key,即不要将数组的index作为key,而是自行维护一个index,相关的在antd的某个类似的示例中也有。
删除一行前是1,2,3,4;删除第二行,1,3,4;增加一行,1,3,4,5;可以避免此类问题
以下是修改的你的部分代码,已经过测试:
```typescript
/* eslint-disable camelcase */
import { Button, Form, Input } from 'antd'
import React, { useState } from 'react'
let index = 1
// 最高和最低楼层输入框组件
function FloorInterval({ handleSave }) {
const [priceItems, setPriceItems] = useState([{ base_price: '', index }])
const addMore = () => {
const a = [...priceItems]
a.push({ base_price: '', index: ++index })
setPriceItems(a)
}
function subtraction(index) {
const a = [...priceItems]
const newPriceItems = a.filter((_, i) => i !== index)
setPriceItems(newPriceItems)
handleSave(newPriceItems)
}
function handleChange(index, type, value) {
const a = [...priceItems]
a[index][type] = value
setPriceItems(a)
handleSave(priceItems)
}
return (
<div className='append-container'>
{priceItems.map(({ base_price, min_floor, max_floor, index: inner_index }, index) => (
```
这一部分主要是增加一些全局会使用的 CSS,包括 a 标签、li 标签的一些排版问题,目前实现的 CSS 如下:
body {
margin: 0;
width: 1980px;
background-color: #f3f5f7;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto',
'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans',
'Helvetica Neue', sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
}
li {
list-style: none;
}
input {
outline: none;
}
a {
text-decoration: none;
color: #050505;
}
a:hover {
color: #00a4ff;
}
dd {
margin: 0;
}
.flex {
display: flex;
}
.relative {
position: relative;
}
.absolute {
position: absolute;
}
.container {
width: 1200px;
margin: auto;
background-color: transparent;
}
.flex-center {
align-items: center;
}
.float-left {
float: left;
}
.float-right {
float: right;
}