【问题标题】:Dynamically add and remove form rows with react使用反应动态添加和删除表单行
【发布时间】:2021-01-02 13:50:21
【问题描述】:

我有一个简单的表单(使用 Semantic ui react 库构建),它由一行和几个输入组成,我的目的是让表单在初始渲染时默认为这一行,但允许用户单击按钮添加一个额外的行,效果很好。我需要帮助的地方是能够在用户最终提交之前删除一行。

我将表单字段存储在组件外部的初始变量中(为了便于查看,最重要的是):

const formField = (
    <div style={{ display: "flex", flexDirection: "row" }}>
        <Form.Select
            label="Exercise"
            placeholder="Select an exercise"
            options={exercises}
        />
        <Form.Input label="Sets" placeholder="Enter your sets" type="number" />
        <Form.Input label="Reps" placeholder="Enter your reps" type="number" />
    </div>
);

然后我将其存储为初始状态:

const [formRow, setFormRow] = useState([formField]);

jsx 包含一个按钮,它将一个新的表单字段(行)连接到状态,然后我将所有字段渲染到页面,给我额外的行

<Form>
            {formRow.map((item, i) => (
                <Form.Group inline widths="equal" key={i}>
                    {item}
                    <Icon
                        name="close"
                        onClick={() => setFormRow((cur) => cur.splice(i, 1))}
                    />
                </Form.Group>
            ))}
            <Button
                color="orange"
                content="Add an exercise"
                onClick={() => setFormRow((prev) => prev.concat([formField]))}
            />
        </Form>

当我映射并渲染到页面时,我为每一行添加了一个删除图标,但我无法使用此功能。我尝试只使用 splice 删除相关行,但这不起作用......它还会删除我单击的行之后的所有行(不太清楚为什么)

The form basically looks as such

有谁知道我如何添加一个功能来删除动态创建的表单 jsx 上的每一行?

谢谢。

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    错误原因发生在您的代码中:

    onClick={() => setFormRow((cur) => cur.splice(i, 1))}
    

    SPLICE方法的返回值不是修改后的数组,它返回的是删除后的数组。

    来自 MOZILLA 文档:

    返回值

    包含已删除元素的数组。

    如果只删除一个元素,则返回一个包含一个元素的数组。

    如果没有元素被移除,则返回一个空数组。

    而且,当你想更新 React 状态时,你不应该使用SPLICE,这个方法会改变原始数组。请改用FILTER

    我在您的代码中看到,您为formField 编写了单独的 JSX,但我认为这是不必要的,因为您只编写了一次。

    我为您的问题建议另一种方法,它是简化示例(没有语义),您可以在这个可运行的在线示例中看到它:

    https://codesandbox.io/s/angry-wescoff-lnj71?file=/src/App.js:265-316

    或者在下面这段代码中(和上面的网址一样):

    import React, { useEffect, useState } from "react";
    
    const App = () => {
      const [formRows, setFormRows] = useState([{ id: 1 }]);
    
      useEffect(() => {
        console.log("formRows: ", formRows);
      });
    
      return (
        <div>
          {formRows.map((row) => (
            <div>
              <input></input>
              <input></input>
              <button
                onClick={() =>
                  setFormRows(formRows.filter((fr) => fr.id !== row.id))
                }
              >
                remove
              </button>
            </div>
          ))}
          <button
            onClick={() => setFormRows([...formRows, { id: formRows.length + 1 }])}
          >
            add
          </button>
        </div>
      );
    };
    
    export default App;
    

    【讨论】:

      【解决方案2】:

      以下代码将用于从表单中删除一行

      <Icon
          name="close"
          onClick={() => setFormRow((cur) => [...cur.slice(0, i), ...cur.slice(i+1)])}
      />
      

      另外,我建议只存储您所在州的每一行的数据,而不是存储 jsx。 编辑: 从列表中删除一个元素的示例

      const index = 2
      const list = [0, 1, 2, 3, 4, 5]
      console.log(list)
      const newList = [...list.slice(0, index), ...list.slice(index + 1)]
      console.log(newList)
      enter code here
      

      【讨论】:

      • 不幸的是,我仍然遇到了同样的问题。它继续删除我要删除的单个行之后的所有行。
      • 不会。如果您查看代码,我只会删除索引i 处的代码。我也在答案中附上了一个例子。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-02-12
      • 1970-01-01
      • 1970-01-01
      • 2011-11-09
      • 2021-08-28
      • 2016-10-29
      • 2017-12-11
      相关资源
      最近更新 更多