nikostav96
nikostav96

Reputation: 211

React dynamic form input

I have a React form with dynamic input fields that a user can add and remove input fields. When i submit the form, i log the values from each input in an array. The problem is that i can't type continuously in a input. When i type in input, i can type only one character and it focus out. How can i fix it?

CodeSandbox

App.js

import React, { useState } from "react";
import ReactDOM from "react-dom";

import "./styles.css";

function App() {
  const [fields, setFields] = useState([""]);

  function handleChange(i, event) {
    const values = [...fields];
    values[i] = event.target.value;
    setFields(values);
  }

  function handleAdd() {
    const values = [...fields];
    values.push("");
    setFields(values);
  }

  function handleRemove(i) {
    const values = [...fields];
    values.splice(i, 1);
    setFields(values);
  }

  function submitHandler(event) {
    event.preventDefault();
    console.log(fields);
  }

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <form onSubmit={submitHandler}>
        <button type="button" onClick={() => handleAdd()}>
          Add Input
        </button>

        {fields.map((field, idx) => {
          return (
            <div key={`${field}-${idx}`}>
              <input
                type="text"
                placeholder="Enter text"
                value={field || ""}
                onChange={(e) => handleChange(idx, e)}
              />
              <button type="button" onClick={() => handleRemove(idx)}>
                X
              </button>
            </div>
          );
        })}
        <button className="margin-top" type="submit">
          Submit
        </button>
      </form>
    </div>
  );
}

export default App;

Upvotes: 3

Views: 7628

Answers (2)

Shoyeb Memon
Shoyeb Memon

Reputation: 1159

i have used a third party debounce , you can choose anything you want

code

import React, { useState } from "react";
import AwesomeDebouncePromise from "awesome-debounce-promise";
import ReactDOM from "react-dom";

import "./styles.css";

function App() {
  const [fields, setFields] = useState([""]);

  function handleChange(i, event) {
    const values = [...fields];
    values[i] = event.target.value;
    setFields(values);
  }

  function handleAdd() {
    const values = [...fields];
    values.push("");
    setFields(values);
  }

 function handleRemove(i) {
   const values = [...fields];
   values.splice(i, 1);
   setFields(values);
 }

 const searchAPIDebounced = AwesomeDebouncePromise((event) => {
   console.log(fields);
 }, 100);

const submitHandler = async (event) => {
  event.preventDefault();
  const result = await searchAPIDebounced(event);
};

return (
  <div className="App">
    <h1>Hello CodeSandbox</h1>
    <form onSubmit={submitHandler}>
      <button type="button" onClick={() => handleAdd()}>
        Add Input
      </button>

      {fields.map((field, idx) => {
        return (
          <div key={`${idx}`}>
            <input
              type="text"
              placeholder="Enter text"
              value={field || ""}
              onChange={(e) => handleChange(idx, e)}
            />
            <button type="button" onClick={() => handleRemove(idx)}>
             X
            </button>
          </div>
         );
       })}
      <button className="margin-top" type="submit">
        Submit
      </button>
    </form>
   </div>
  );
 }

export default App;

Upvotes: 1

Ganesh Budhathoki
Ganesh Budhathoki

Reputation: 61

Replace your code with this

         <div key={`${"asdf"}-${idx}`}>
          <input
            type="text"
            placeholder="Enter text"
            value={field || ""}
            onChange={(e) => handleChange(idx, e)}
          />
          <button type="button" onClick={() => handleRemove(idx)}>
            X
          </button>
        </div>

Upvotes: 1

Related Questions