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.