【问题标题】:React - Creating a form with a dynamic number of inputsReact - 创建具有动态输入数量的表单
【发布时间】:2021-03-12 11:36:59
【问题描述】:

我正在尝试为用户创建一个表单以提交食谱。我需要将其设置为用户可以单击“+”按钮以添加更多成分或添加更多说明的位置。每个输入旁边还有一个“-”按钮可以将其删除。

我大部分时间都在工作,我可以添加项目。但是,删除项目似乎没有任何一致性。

我正在使用 Material UI,我不确定这是否相关。

这是我正在处理的相关代码,我将在最后链接一个完整的代码框。

const [ingredients, setIngredients] = React.useState(
  [
    {
      name: "",
      amount: ""
    }
  ]
);

这是我在 react 中渲染数组的方式

        {ingredients.map((ing, idx) => {
          return (
            <div key={idx}>
              <TextField
                id={"ing-name-" + idx}
                name={"ing-name-" + idx}
                variant="outlined"
                label="Ingrediant Name"
                value={ing.name}
                required
                onChange={handleIngredientChange}
              />
              <TextField
                id={"ing-amt-" + idx}
                name={"ing-amt-" + idx}
                variant="outlined"
                label="Ingredient Amount"
                value={ing.amount}
                required
                onChange={handleIngredientChange}
              />
              <Button
                id={"ing-remove-" + idx}
                variant="contained"
                color="secondary"
                type="button"
                onClick={handleIngredientRemove}
              >-</Button>
            </div>
          )
        })}

        <Button
          variant="contained"
          color="primary"
          type="button"
          onClick={handleIngredientAdd}
        >+</Button>

最后是处理项目添加/删除的两个函数


  function handleIngredientRemove(event) {
    /*
    * To remove an element, we just use the array.filter function to genereate a new array without the 
    * element being deleted
    */
    console.log(event.target.id);
    let idx = parseInt(event.target.id.split("-")[2]);
    console.log("Removing ingredient " + idx);
    let newIngredients = ingredients.filter((ingredient, index) => idx !== index);
    setIngredients(newIngredients);
    
  }

  function handleIngredientAdd(event) {
    /*
    * Same concept as the above methods, concat returns a new array. In this case we get a new array with an
    * element containing an empty string in both fields at the end of it
    */
    let newIngredients = ingredients.concat({name: "", amount: ""});
    setIngredients(newIngredients);
  }

完整的代码框演示https://codesandbox.io/s/happy-herschel-k0oqf

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    Material UI 使用多个标签包装您的按钮。所以当你点击一个按钮时,里面可能还有其他东西被点击了。

    将 id 传递给 onClick 函数将解决您的问题,但它可能会在您每次单击按钮时创建一个新函数。

    onClick={() => handleIngredientRemove(idx)}
    

    我建议你使用 currentTarget 而不是 current。

    function handleInstructionRemove(event) {
        // Use event.currentTarget instead of event.current
        let idx = parseInt(event.currentTarget.id.split("-")[2]);
        console.log("Removing instruction " + idx);
        let newinstructions = instructions.filter(
              (instruction, index) => idx !== index
        );
        setInstructions(newinstructions);
     }
    

    【讨论】:

    • 谢谢,我已经尝试了这两种解决方案,它们都有效。我想我会像建议的那样使用 currentTarget。
    【解决方案2】:

    一种简单的方法是将索引传递给删除处理程序并使用该索引进行过滤。(仅针对第一种形式进行更改) here is the updated code

    或者您可以在添加时使用时间戳作为 id 并使用该唯一时间戳 id 删除

    【讨论】:

      【解决方案3】:

      我建议不要解析元素 id 来提取索引。您可以直接传递它:

      onClick={() => handleIngredientRemove(idx)}
      

      然后在handleIngredientRemove点赞

      handleIngredientRemove(idx)
      

      现在可以正常删除了!

      【讨论】:

      • 您的 idx 成为事件。它应该是 () => handleIngredientRemove(idx)
      • 谢谢!固定
      猜你喜欢
      • 1970-01-01
      • 2010-10-28
      • 2021-01-29
      • 2017-05-21
      • 2020-08-05
      • 1970-01-01
      • 1970-01-01
      • 2010-11-12
      • 1970-01-01
      相关资源
      最近更新 更多