react数据和页面不一致


//最高和最低楼层输入框组件
  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>&nbsp;&nbsp;&nbsp;&nbsp;</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>&nbsp;&nbsp;</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>
    );
  }

组件对应的内容就是

img

现在的问题:
点击第二行的减号按钮之后,列表中删掉的是index为1 的数据,但是页面中删除的永远是最后一行?

img

img

很好的一个问题!
正好碰到过一个类似的问题,简单说,你的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) => (


```

  • 你可以看下这个问题的回答https://ask.csdn.net/questions/7488757
  • 这篇博客你也可以参考下:关于React中受控组件和不受控组件的选择问题分析
  • 除此之外, 这篇博客: [万字长文]使用 React 重写学成在线前端项目 I 代码完整可运行,步骤有详解中的 修改 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;
    }