I need to add an "Add input" button which adds a <div> with some inputs. That works fine but if I remove some element (for example the first one) it will deletes the last one no matter what.
I was reading this question but I can't figure out how to bring it to my scenario.
I have created this Codesandbox to see "the bigger picture".
The main idea is whenever you click over "Add input" it adds that div to addedInputs state array:
function addInputElement(inputId) {
const input = inputs[inputId];
input.id = inputId;
setAddedInputs([...addedInputs, input]);
setSelectedValue("default");
setAddInput(false);
}
When you write in any input of it, it adds it also to an object inputValue with the same index number as addedInputs array.
function changeInputValue(element, index, value) {
const iv = inputValue;
if (iv[index]) {
Object.assign(iv[index], { [element]: value });
} else {
Object.assign(iv, { [index]: { [element]: value } });
}
setInputValue(iv);
}
But when I remove the input from addedInputs and it attempts to delete the content from inputValue it deletes the right addedInputs element but does not deletes the right inputValue element:
function removeInputElement(index) {
const filteredInputs = addedInputs.filter((input, i) => i !== index);
setAddedInputs(filteredInputs);
if (inputValue[index] !== undefined) {
const ivs = inputValue;
delete ivs[index];
setInputValue(ivs);
}
}
Well, I am not sure if that is right approach for creating dynamic inputs states but, anyway my "error" here is that I am doing something wrong when removing an input value from inputValues. So, what am I doing wrong?
In case you want the entire code here:
import React from "react";
const inputs = {
"123": { name: "Simple text input", type: "text" },
"456": { name: "Simple number input", type: "number" }
};
export default function App() {
const [addedInputs, setAddedInputs] = React.useState([]);
const [inputValue, setInputValue] = React.useState({});
const [selectedValue, setSelectedValue] = React.useState("default");
const [addInput, setAddInput] = React.useState(false);
function addInputElement(inputId) {
const input = inputs[inputId];
input.id = inputId;
setAddedInputs([...addedInputs, input]);
setSelectedValue("default");
setAddInput(false);
}
function removeInputElement(index) {
const filteredInputs = addedInputs.filter((input, i) => i !== index);
setAddedInputs(filteredInputs);
if (inputValue[index] !== undefined) {
const ivs = inputValue;
delete ivs[index];
setInputValue(ivs);
}
}
function changeInputValue(element, index, value) {
const iv = inputValue;
if (iv[index]) {
Object.assign(iv[index], { [element]: value });
} else {
Object.assign(iv, { [index]: { [element]: value } });
}
setInputValue(iv);
}
return (
<div className="App">
{addedInputs.map((input, index) => (
<div key={index}>
<h5>{input.name}</h5>
<input
placeholder="Title"
type="text"
value={
inputValue[index] &&
inputValue[index][input.id] &&
inputValue[index][input.id].title
}
onChange={(e) => {
changeInputValue("title", index, e.target.value);
}}
/>
<input
placeholder="Description"
type="text"
value={
inputValue[index] &&
inputValue[index][input.id] &&
inputValue[index][input.id].title
}
onChange={(e) => {
changeInputValue("description", index, e.target.value);
}}
/>
<button
onClick={() => {
removeInputElement(index);
}}
>
X
</button>
</div>
))}
{addInput && (
<select
defaultValue={selectedValue}
onChange={(e) => {
addInputElement(e.target.value);
}}
>
<option disabled value="default">
Select an option
</option>
{Object.keys(inputs).map((key, index) => {
const input = inputs[key];
return (
<option key={index} value={key}>
{input.name}
</option>
);
})}
</select>
)}
<button
onClick={() => {
setAddInput(true);
}}
>
Add input
</button>
</div>
);
}