简体   繁体   中英

React input loses focus on change

React input loses focus on each change. I know that if I move my Input function inside map directly it gonna work correctly. But I want to make it a reusable component. Here is the link: https://codesandbox.io/s/weathered-violet-j6gv14?file=/src/inputs.js

import React, { useState } from "react";

export default function Inputs({ inputs, setInputs }) {
  function handleAdd() {
    setInputs([...inputs, { input1: "", input2: "" }]);
  }
  function handleChange({ value, index, name }) {
    const tempInputs = [...inputs];
    tempInputs[index][name] = value;
    setInputs(tempInputs);
  }
  function Input({ index, input, ...props }) {
    return (
      <div {...props}>
        <input
          type="text"
          value={input["input1"]}
          onChange={(e) =>
            handleChange({
              value: e.target.value,
              index: index,
              name: "input1",
            })
          }
        />
        <input
          value={input["input2"]}
          onChange={(e) =>
            handleChange({
              value: e.target.value,
              index: index,
              name: "input2",
            })
          }
        />
      </div>
    );
  }
  return (
    <div>
      <button onClick={handleAdd}>Add</button>
      <ul>
        {inputs.map((input, index) => {
          return <Input key={index} index={index} input={input} />;
        })}
      </ul>
    </div>
  );
}

You need to move your Input function outside Inputs , make it as a separate component and just pass handleChange callback there.

It happens, because when you change inputs, React re-renders the component and as your function is inside the component is being re-rendered too, but you don't need it actually.

import React from "react";

function Input({ index, input, handleChange, ...props }) {
  return (
    <div {...props}>
      <input
        type="text"
        value={input["input1"]}
        onChange={(e) =>
          handleChange({
            value: e.target.value,
            index: index,
            name: "input1"
          })
        }
      />
      <input
        type="text"
        value={input["input2"]}
        onChange={(e) =>
          handleChange({
            value: e.target.value,
            index: index,
            name: "input2"
          })
        }
      />
    </div>
  );
}

export default function Inputs({ inputs, setInputs }) {
  function handleAdd() {
    const tempInputs = [...inputs];
    tempInputs.push({ input1: "", input2: "" });
    setInputs(tempInputs);
  }
  function handleChange({ value, index, name }) {
    const tempInputs = [...inputs];
    tempInputs[index][name] = value;
    setInputs(tempInputs);
  }

  return (
    <div>
      <button onClick={handleAdd}>Add</button>
      <ul>
        {inputs.map((input, index) => {
          return (
            <Input
              key={index}
              handleChange={handleChange}
              index={index}
              input={input}
            />
          );
        })}
      </ul>
    </div>
  );
}

https://codesandbox.io/s/little-brook-7iiiqw?file=/src/inputs.js

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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