如何在 React Js 中编辑输入值?

How to edit input value in React Js?

我正在尝试为我的应用程序创建一个组件,当我点击一个按钮时,输入字段打开,在我添加文本后,我再次点击该按钮,另一个输入打开,等等。然后 e.target.value 所有这些输入应该以不同的状态保存并显示在另一个组件中。到目前为止,我能够创建这样的输入,但我不知道如何编辑输入字段。我的代码:

import "./styles.css";
import React, { useState } from "react";

export default function App() {
  const [input, setInput] = useState([{}]);
  const [data, setData] = useState([]);

  function handleChange(i, e) {
    e.preventDefault();

    setInput([
      {
        id: i,
        value: e.target.value
      }
    ]);
  }

  function handleAddInput() {
    const values = [...input];
    values.push({ value: null });
    setInput(values);
  }

  const handleSave = () => {
    let value = input?.map((item) => {
      return item.value;
    });
    if (!value || /^\s*$/.test(value)) {
      return;
    }

    const newData = [...data, ...input];

    setData(newData);

    setInput([])
  };

  return (
      <div className="App">
        <button type="button" className="btn" onClick={() => handleAddInput()}>
          Add  Input fields
        </button>

        {input?.map((input, idx) => {
          return (
            <div key={input.id}>
              <input
                type="text"
                placeholder="Enter text"
                onChange={(e) => handleChange(idx, e)}
                value={input.value}
              />
            </div>
          );
        })}

       
    
<h2>Display Added Fields and Edit</h2>
      {data?.map((item) => {
        return (
          <>
            <input defaultValue={item.value}
            
            
            
            />
          </>
        );
      })}

<button className="btn" onClick={handleSave}>Save</button>

      {data?.map((item) => {
        return (
          <div style={{ display: "flex", flexDorection: "column", marginTop:"20px" }}>
            {item.value}
          </div>
        );
      })}
        </div>
  );
}

codeSandbox

当我点击“添加输入字段”弹出新输入时,我输入任何输入文本,然后我再次点击添加输入字段并打开另一个输入,当我点击“保存”按钮时,所有输入值被保存到状态(作为数据)并显示为输入,之后我可以映射“数据”并显示接收到的输入。就像在图像上我添加了“第一”,然后是“第二”,它们显示得很好,但我不知道如何编辑它们,例如将“第一”更改为“第三”并在“保存”按钮上更改为“第三”应该显示而不是“第一”。非常感谢任何帮助和建议。

问题

  1. 使用索引作为 id 不是一个好主意,它们不是唯一的。
  2. handleChange 不会保留现有的输入状态。
  3. React 键的其他各种问题,以及将状态从 input 复制到 data

解决方案

  1. 您不需要输入对象,您可以存储来自输入的字符串基元。这意味着您也不需要 id 属性,按索引更新很简单。
  2. 应该使用功能状态更新来更新以前的状态。
  3. 我建议使用表单和 onSubmit 处理程序来处理 data 状态数组值的更新。

代码:

function App() {
  const [input, setInput] = useState([]);
  const [data, setData] = useState([]);

  function handleChange(i, e) {
    e.preventDefault();

    setInput((values) =>
      values.map((value, index) => (index === i ? e.target.value : value))
    );
  }

  function handleAddInput() {
    setInput((input) => input.concat(""));
  }

  const saveHandler = (e) => {
    e.preventDefault();

    // Map all existing form field values
    setData((data) => data.map((_, i) => e.target[i].value));

    // If there are any input values, add these and clear inputs
    if (input.length) {
      setData((data) => data.concat(input));
      setInput([]);
    }
  };

  return (
    <div className="App">
      <button type="button" className="btn" onClick={handleAddInput}>
        Add Input fields
      </button>

      {input.map((input, idx) => {
        return (
          <div key={idx}>
            <input
              type="text"
              placeholder="Enter text"
              onChange={(e) => handleChange(idx, e)}
              value={input.value}
            />
          </div>
        );
      })}

      <h2>Display Added Fields and Edit</h2>
      <form onSubmit={saveHandler}>
        {data.map((item, i) => {
          return (
            <div key={i}>
              <input id={i} defaultValue={item} />
            </div>
          );
        })}

        <button className="btn" type="submit">
          Save
        </button>
      </form>

      {data.map((item, i) => {
        return (
          <div
            key={i}
            style={{
              display: "flex",
              flexDirection: "column",
              marginTop: "20px"
            }}
          >
            {item}
          </div>
        );
      })}
    </div>
  );
}

演示

编辑

编辑以生成 GUID 并将 id 属性 保持到 data 状态。

  1. 添加新的输入字段时生成新的 GUID。
  2. 使用 id 匹配任何值更新的元素。
  3. 保存输入字段时,只需将 input 数组复制到 data
  4. 在示例中,我还在每一步都呈现 id,因此很明显数据元素仍然是相同的对象。

代码:

function App() {
  const [input, setInput] = useState([]);
  const [data, setData] = useState([]);

  const handleChange = (id) => (e) => {
    e.preventDefault();

    setInput((values) =>
      values.map((el) =>
        el.id === id
          ? {
              ...el,
              value: e.target.value
            }
          : el
      )
    );
  };

  function handleAddInput() {
    setInput((input) =>
      input.concat({
        id: uuidV4(),
        value: ""
      })
    );
  }

  const saveHandler = (e) => {
    e.preventDefault();

    setData((data) =>
      data.map((el) => ({
        ...el,
        value: e.target[el.id].value
      }))
    );

    if (input.length) {
      setData((data) => data.concat(input));
      setInput([]);
    }
  };

  return (
    <div className="App">
      <button type="button" className="btn" onClick={handleAddInput}>
        Add Input fields
      </button>

      {input.map((input) => {
        return (
          <label key={input.id}>
            {input.id}
            <input
              type="text"
              placeholder="Enter text"
              onChange={handleChange(input.id)}
              value={input.value}
            />
          </label>
        );
      })}

      <h2>Display Added Fields and Edit</h2>
      <form onSubmit={saveHandler}>
        {data.map((item) => {
          return (
            <div key={item.id}>
              <label>
                {item.id}
                <input id={item.id} defaultValue={item.value} />
              </label>
            </div>
          );
        })}

        <button className="btn" type="submit">
          Save
        </button>
      </form>

      {data.map((item) => {
        return (
          <div
            key={item.id}
            style={{
              display: "flex",
              flexDirection: "column",
              marginTop: "20px"
            }}
          >
            <div>
              {item.id} - {item.value}
            </div>
          </div>
        );
      })}
    </div>
  );
}

演示 2