typescript 使用react js动态添加和删除select元素

f0brbegy  于 2023-06-24  发布在  TypeScript
关注(0)|答案(2)|浏览(163)

我一直在尝试构建一个选择框,它将通过点击按钮动态添加。我可以添加和删除选择框,但问题是,每当我从数组中删除一个项时,其余元素上的选定选项不会相应更新。如果我从最后一个索引中删除一个元素,它工作得很好,每当项目从开头或中间删除时,问题就会发生。这是我目前所掌握情况

type RailcardsProps = {
  value: string,
  fieldName: string,
  count: string;
}

const railCardsList = [
  {
    text: 'Select Rail card',
    value: ''
  },
  {
    text: 'Child Saver',
    value: 'childSaver'
  },
  {
    text: 'Adult Saver',
    value: 'adultSaver'
  },
  {
    text: 'Senior Railcard',
    value: 'seniorRailcard'
  },
  {
    text: 'Network Railcard',
    value: 'networkRailcard'
  },
]

const PassangerDropdown = () => {
  const [railCards, setRailCards] = useState<RailcardsProps[]>([]);

  const handleRailCardCLick = () => {
    const railCardsArray = railCards;
    const count = railCardCount;
    setRailCards(railCardsArray.concat({
      value: 'Select Rail Card',
      fieldName: `railcard-${railCardCount}`,
      count: '1'
    }));

    setRailCardCount(count + 1);
  }

  useEffect(() => {
    console.log(railCards);
  }, [railCards])

  const handleSelectRailcard = (event: ChangeEvent<HTMLSelectElement>) => {
    const value = (event.target.value);
    const updatedRailCards = railCards;
    const index = event.target.getAttribute('data-index')!;
    updatedRailCards[+index].value = value;
    setRailCards([...updatedRailCards]);
  }

  const handleRailcardCount = (event: ChangeEvent<HTMLSelectElement>) => {
    const count = (event.target.value);
    const updatedRailCards = railCards;
    const index = event.target.getAttribute('data-index')!;
    updatedRailCards[+index].count = count;
    setRailCards([...updatedRailCards]);
  }

  const handleRemoveRailcard = (index: number) => {
    const updatedRailCards = railCards;
    const count = railCardCount;
    updatedRailCards.splice(index, 1);
    setRailCardCount(count - 1);
    console.log(index);
    setRailCards([...updatedRailCards]);
  }

return (
<div className="passanger-dropdown-item--left w-100">
                  <button type="button" className="btn custom-link mb-2" onClick={handleRailCardCLick}>Add Railcards</button>
                  {
                    railCards.map(({ value, fieldName, count }, index) => (
                      <div key={index} className="passanger-dropdown-item--content p-0">
                        <select
                          defaultValue={value}
                          name={fieldName}
                          className="form-control passanger-dropdown-item--select w-70 mr-1"
                          data-index={index}
                          onChange={handleSelectRailcard} >
                          {
                            railCardsList.map(({ value, text }) => (
                              <option key={value} defaultValue={value}>{text}</option>
                            ))
                          }
                        </select>
                        <select
                          defaultValue={count}
                          name={`${fieldName}-count`}
                          className="form-control passanger-dropdown-item--select w-30"
                          data-index={index}
                          disabled={value === 'Select Rail Card'}
                          onChange={handleRailcardCount} >
                          {
                            ['1', '2', '3', '4', '5', '6', '7', '8', '9'].map((item) => (
                              <option key={item} defaultValue={item}>{item}</option>
                            ))
                          }
                        </select>
                        <button
                          type="button"
                          className="btn passanger-dropdown-item--btn"
                          onClick={() => handleRemoveRailcard(index)}>x</button>
                      </div>
                    ))
                  }
                </div>)
}

this site乘客下拉列表中我试图实现的东西,在乘客下拉列表中我们可以添加或删除rail cards,我如何解决这个问题?

lyfkaqu1

lyfkaqu11#

我认为你的问题是你在移除和添加新项时依赖于数组索引,这在React中被认为是反模式,因为在大多数情况下,它可能会导致意想不到的结果。所以我建议创建随机索引来避免这种情况,就像我做let id = Math.floor(Math.random() * 1000000);一样。但是,我强烈建议使用一些模块来生成唯一ID,如uuid
我也能看出你和状态突变有一些斗争。试试我的方法

type RailcardsProps = {
   value: string,
   fieldName: string,
   count: string;
}

const railCardsList = [
  {
    text: "Select Rail card",
    value: ""
  },
  {
    text: "Child Saver",
    value: "childSaver"
  },
  {
    text: "Adult Saver",
    value: "adultSaver"
  },
  {
    text: "Senior Railcard",
    value: "seniorRailcard"
  },
  {
    text: "Network Railcard",
    value: "networkRailcard"
  }
];

const PassangerDropdown = () => {
  const [railCards, setRailCards] = useState<RailcardsProps[]>([]);
  
  const handleRailCardCLick = () => {
    let id = Math.floor(Math.random() * 1000000);
    setRailCards([
      ...railCards,
      {
        value: "Select Rail Card",
        fieldName: `railcard-${railCards.length + 1}`,
        count: 1,
        id
      }
    ]);
  };

  const handleSelectRailcard = (event: ChangeEvent<HTMLSelectElement>) => {
    const index = event.target.getAttribute("data-index");
    const value = event.target.value;
    const updatedRailCards =
      railCards &&
      railCards.map((i) => {
        if (i.id === +index) {
          i.value = value;
        }
        return i;
      });
    setRailCards(updatedRailCards);
  };

  const handleRailcardCount = (event: ChangeEvent<HTMLSelectElement>) => {
    const index = event.target.getAttribute("data-index");
    const count = event.target.value;

    const updatedRailCards =
      railCards &&
      railCards.map((i) => {
        if (i.id === +index) {
          i.count = count;
        }
        return i;
      });
    setRailCards(updatedRailCards);
  };

  const handleRemoveRailcard = (id: number) => {
    const updatedRailCards = railCards && railCards.filter((r) => r.id !== id);
    setRailCards(updatedRailCards);
  };

  return (
    <div className="passanger-dropdown-item--left w-100">
      <button
        type="button"
        className="btn custom-link mb-2"
        onClick={handleRailCardCLick}
      >
        Add Railcards
      </button>
      {railCards &&
        railCards.map(({ value, fieldName, count, id }, index) => (
          <div key={id} className="passanger-dropdown-item--content p-0">
            <select
              defaultValue={value}
              name={fieldName}
              className="form-control passanger-dropdown-item--select w-70 mr-1"
              data-index={id}
              onChange={handleSelectRailcard}
            >
              {railCardsList.map(({ value, text }) => (
                <option key={value} defaultValue={value}>
                  {text}
                </option>
              ))}
            </select>
            <select
              defaultValue={count}
              name={`${fieldName}-count`}
              className="form-control passanger-dropdown-item--select w-30"
              data-index={id}
              disabled={value == "Select Rail Card"}
              onChange={handleRailcardCount}
            >
              {["1", "2", "3", "4", "5", "6", "7", "8", "9"].map((item) => (
                <option key={item} defaultValue={item}>
                  {item}
                </option>
              ))}
            </select>
            <button
              type="button"
              className="btn passanger-dropdown-item--btn"
              onClick={() => handleRemoveRailcard(id)}
            >
              x
            </button>
          </div>
        ))}
    </div>
  );
};

live demo sample

blmhpbnm

blmhpbnm2#

在您的Select元素中添加value={value}

相关问题