童话里做英雄529 2023-04-27 10:47 采纳率: 66.7%
浏览 19
已结题

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

  • 写回答

2条回答 默认 最新

  • RivaJ 2023-04-27 11:56
    关注

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

    ```

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 5月5日
  • 已采纳回答 4月27日
  • 创建了问题 4月27日