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

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

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

  1. type RailcardsProps = {
  2. value: string,
  3. fieldName: string,
  4. count: string;
  5. }
  6. const railCardsList = [
  7. {
  8. text: 'Select Rail card',
  9. value: ''
  10. },
  11. {
  12. text: 'Child Saver',
  13. value: 'childSaver'
  14. },
  15. {
  16. text: 'Adult Saver',
  17. value: 'adultSaver'
  18. },
  19. {
  20. text: 'Senior Railcard',
  21. value: 'seniorRailcard'
  22. },
  23. {
  24. text: 'Network Railcard',
  25. value: 'networkRailcard'
  26. },
  27. ]
  28. const PassangerDropdown = () => {
  29. const [railCards, setRailCards] = useState<RailcardsProps[]>([]);
  30. const handleRailCardCLick = () => {
  31. const railCardsArray = railCards;
  32. const count = railCardCount;
  33. setRailCards(railCardsArray.concat({
  34. value: 'Select Rail Card',
  35. fieldName: `railcard-${railCardCount}`,
  36. count: '1'
  37. }));
  38. setRailCardCount(count + 1);
  39. }
  40. useEffect(() => {
  41. console.log(railCards);
  42. }, [railCards])
  43. const handleSelectRailcard = (event: ChangeEvent<HTMLSelectElement>) => {
  44. const value = (event.target.value);
  45. const updatedRailCards = railCards;
  46. const index = event.target.getAttribute('data-index')!;
  47. updatedRailCards[+index].value = value;
  48. setRailCards([...updatedRailCards]);
  49. }
  50. const handleRailcardCount = (event: ChangeEvent<HTMLSelectElement>) => {
  51. const count = (event.target.value);
  52. const updatedRailCards = railCards;
  53. const index = event.target.getAttribute('data-index')!;
  54. updatedRailCards[+index].count = count;
  55. setRailCards([...updatedRailCards]);
  56. }
  57. const handleRemoveRailcard = (index: number) => {
  58. const updatedRailCards = railCards;
  59. const count = railCardCount;
  60. updatedRailCards.splice(index, 1);
  61. setRailCardCount(count - 1);
  62. console.log(index);
  63. setRailCards([...updatedRailCards]);
  64. }
  65. return (
  66. <div className="passanger-dropdown-item--left w-100">
  67. <button type="button" className="btn custom-link mb-2" onClick={handleRailCardCLick}>Add Railcards</button>
  68. {
  69. railCards.map(({ value, fieldName, count }, index) => (
  70. <div key={index} className="passanger-dropdown-item--content p-0">
  71. <select
  72. defaultValue={value}
  73. name={fieldName}
  74. className="form-control passanger-dropdown-item--select w-70 mr-1"
  75. data-index={index}
  76. onChange={handleSelectRailcard} >
  77. {
  78. railCardsList.map(({ value, text }) => (
  79. <option key={value} defaultValue={value}>{text}</option>
  80. ))
  81. }
  82. </select>
  83. <select
  84. defaultValue={count}
  85. name={`${fieldName}-count`}
  86. className="form-control passanger-dropdown-item--select w-30"
  87. data-index={index}
  88. disabled={value === 'Select Rail Card'}
  89. onChange={handleRailcardCount} >
  90. {
  91. ['1', '2', '3', '4', '5', '6', '7', '8', '9'].map((item) => (
  92. <option key={item} defaultValue={item}>{item}</option>
  93. ))
  94. }
  95. </select>
  96. <button
  97. type="button"
  98. className="btn passanger-dropdown-item--btn"
  99. onClick={() => handleRemoveRailcard(index)}>x</button>
  100. </div>
  101. ))
  102. }
  103. </div>)
  104. }

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

lyfkaqu1

lyfkaqu11#

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

  1. type RailcardsProps = {
  2. value: string,
  3. fieldName: string,
  4. count: string;
  5. }
  6. const railCardsList = [
  7. {
  8. text: "Select Rail card",
  9. value: ""
  10. },
  11. {
  12. text: "Child Saver",
  13. value: "childSaver"
  14. },
  15. {
  16. text: "Adult Saver",
  17. value: "adultSaver"
  18. },
  19. {
  20. text: "Senior Railcard",
  21. value: "seniorRailcard"
  22. },
  23. {
  24. text: "Network Railcard",
  25. value: "networkRailcard"
  26. }
  27. ];
  28. const PassangerDropdown = () => {
  29. const [railCards, setRailCards] = useState<RailcardsProps[]>([]);
  30. const handleRailCardCLick = () => {
  31. let id = Math.floor(Math.random() * 1000000);
  32. setRailCards([
  33. ...railCards,
  34. {
  35. value: "Select Rail Card",
  36. fieldName: `railcard-${railCards.length + 1}`,
  37. count: 1,
  38. id
  39. }
  40. ]);
  41. };
  42. const handleSelectRailcard = (event: ChangeEvent<HTMLSelectElement>) => {
  43. const index = event.target.getAttribute("data-index");
  44. const value = event.target.value;
  45. const updatedRailCards =
  46. railCards &&
  47. railCards.map((i) => {
  48. if (i.id === +index) {
  49. i.value = value;
  50. }
  51. return i;
  52. });
  53. setRailCards(updatedRailCards);
  54. };
  55. const handleRailcardCount = (event: ChangeEvent<HTMLSelectElement>) => {
  56. const index = event.target.getAttribute("data-index");
  57. const count = event.target.value;
  58. const updatedRailCards =
  59. railCards &&
  60. railCards.map((i) => {
  61. if (i.id === +index) {
  62. i.count = count;
  63. }
  64. return i;
  65. });
  66. setRailCards(updatedRailCards);
  67. };
  68. const handleRemoveRailcard = (id: number) => {
  69. const updatedRailCards = railCards && railCards.filter((r) => r.id !== id);
  70. setRailCards(updatedRailCards);
  71. };
  72. return (
  73. <div className="passanger-dropdown-item--left w-100">
  74. <button
  75. type="button"
  76. className="btn custom-link mb-2"
  77. onClick={handleRailCardCLick}
  78. >
  79. Add Railcards
  80. </button>
  81. {railCards &&
  82. railCards.map(({ value, fieldName, count, id }, index) => (
  83. <div key={id} className="passanger-dropdown-item--content p-0">
  84. <select
  85. defaultValue={value}
  86. name={fieldName}
  87. className="form-control passanger-dropdown-item--select w-70 mr-1"
  88. data-index={id}
  89. onChange={handleSelectRailcard}
  90. >
  91. {railCardsList.map(({ value, text }) => (
  92. <option key={value} defaultValue={value}>
  93. {text}
  94. </option>
  95. ))}
  96. </select>
  97. <select
  98. defaultValue={count}
  99. name={`${fieldName}-count`}
  100. className="form-control passanger-dropdown-item--select w-30"
  101. data-index={id}
  102. disabled={value == "Select Rail Card"}
  103. onChange={handleRailcardCount}
  104. >
  105. {["1", "2", "3", "4", "5", "6", "7", "8", "9"].map((item) => (
  106. <option key={item} defaultValue={item}>
  107. {item}
  108. </option>
  109. ))}
  110. </select>
  111. <button
  112. type="button"
  113. className="btn passanger-dropdown-item--btn"
  114. onClick={() => handleRemoveRailcard(id)}
  115. >
  116. x
  117. </button>
  118. </div>
  119. ))}
  120. </div>
  121. );
  122. };

live demo sample

展开查看全部
blmhpbnm

blmhpbnm2#

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

相关问题