简体   繁体   English

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

[英]How to edit input value in React Js?

I'm trying to create a component for my app, where when I click on a button input field opens, after I add text I click on that button again and another input opens up, and so on.我正在尝试为我的应用程序创建一个组件,当我单击按钮时,输入字段打开,添加文本后,我再次单击该按钮并打开另一个输入,依此类推。 Then e.target.value of all those inputs should be saved in a different state and displayed in another components.然后所有这些输入的 e.target.value 应保存在不同的 state 中并显示在另一个组件中。 So far I was able to create such input, but I can't figure out how to edit input fields.到目前为止,我能够创建这样的输入,但我不知道如何编辑输入字段。 My code:我的代码:

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 代码沙盒

在此处输入图像描述

At the moment when I click "Add Input fields" new input pops up, I enter any input text, then I click Add Input fields again and another input opens up, when I click "Save" button, all input values are saved to state (as data) and displayed as inputs, and after I can map through "data" and display received inputs.在我单击“添加输入字段”时弹出新输入,我输入任何输入文本,然后再次单击“添加输入字段”并打开另一个输入,当我单击“保存”按钮时,所有输入值都保存到 state (作为数据)并显示为输入,之后我可以通过“数据” map 并显示接收到的输入。 Like on image I added "first", then "second" and they're getting displayed fine, but I don't know how I could edit them, for example change "first" to "third" and on Save button "third" should be displayed instead of "first".就像在图像上我添加了“第一”,然后“第二”,它们显示得很好,但我不知道如何编辑它们,例如将“第一”更改为“第三”并在保存按钮上“第三”应该显示而不是“第一”。 Any help and suggestions are greatly appreciated.非常感谢任何帮助和建议。

Issue问题

  1. Using an index as an id isn't a good idea, they aren't unique.使用索引作为 id 不是一个好主意,它们不是唯一的。
  2. handleChange doesn't persist existing input state. handleChange不会保留现有输入 state。
  3. Other various issues with React keys, and copying state from input to data React 键的其他各种问题,以及将 state 从input复制到data

Solution解决方案

  1. You don't need input objects, you can store the string primitives from the inputs.您不需要输入对象,您可以存储来自输入的字符串原语。 This means you also don't need the id property, it is trivial to update by index.这意味着您也不需要id属性,按索引更新很简单。
  2. Should use functional state updates to update from previous state.应该使用功能 state 更新来从以前的 state 更新。
  3. I suggest using a form and onSubmit handler to handle updating the data state array values.我建议使用表单和onSubmit处理程序来处理更新data state 数组值。

Code:代码:

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>
  );
}

Demo演示

编辑 how-to-edit-input-value-in-react-js

Edit编辑

Edit to generate GUIDs and persist id property through to the data state.编辑以生成 GUID 并将id属性保留到data state。

  1. Generate a new GUID when adding a new input field.添加新输入字段时生成新的 GUID。
  2. Use the id for matching elements for any value updates.使用id匹配元素以进行任何值更新。
  3. Simply copy the input array to data when saving the input fields.保存输入字段时,只需将input数组复制到data即可。
  4. In example I also render the id at every step so it's clear the data elements are still the same objects.在示例中,我还在每一步都渲染了id ,因此很明显数据元素仍然是相同的对象。

Code:代码:

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>
  );
}

Demo 2演示 2

编辑 how-to-edit-input-value-in-react-js(分叉)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM