Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

231
Views
How to make a variable amount of inputs be controlled - React

I have a variable number that created an array, ex:

const numberVariable = 3;

const arr = Array(numberVariable).fill(0)  //  [0,0,0] //

And I have an Input component controlled by one state:

const [ input, setInput] = useState();

<InputUser value={input} onChange={(e) => {setInput(e.target.value) />

The problem:

When I make a map of the array, to create one Input for each element of the array, they change themselves, ex:

3 inputs, I write in the second and the other 2 get the same value;

How do I make them independent? knowing that creating 3 states manually is not an option, (I used 3 as an example, this is a variable number, changed every time)

code that create inputs based on array:

arr .map((number) => {
          return (
            <div key={number}>
              <InputUser/>
            </div>
          );
        });
about 4 years ago · Juan Pablo Isaza
2 answers
Answer question

0

So, you are trying to render X amount of input fields, and be able to manage all of them right ?

I'm not great at react too but i managed to do that, by getting help from here: https://zacjones.io/handle-multiple-inputs-in-react-with-hooks

 const numberVariable = 3;
  let arr = [];
  for (let i = 0; i < numberVariable; i++) {
    arr.push(i);
  }
  let initialState = {};

  arr.forEach((element) => {
    initialState[element] = "";
  });
  console.log(initialState);
  const [input, setInput] = useState(initialState);
  let inputName = 0;

  const handleUserInputChange = (e) => {
    const name = e.target.name;
    const newValue = e.target.value;
    setInput({ [name]: newValue });
  };

  const a = arr.map((number) => {
    inputName++;
    return (
      <div key={number}>
        <input
          value={input[inputName]}
          name={inputName}
          onChange={handleUserInputChange}
        ></input>
      </div>
    );
  });

One problem: there's "A component is changing a controlled input to be uncontrolled." alert on console, harmless but is there. I couldn't debug that. But this code replicates the behaviour you want and hopefully gives the general idea. You use name attribute to give them a unique name, and access it with e.target.name, then as the initial state, you have X amount of objects called 0: "", 1: "", created by the arr.forEach loop, so that you can change the according input field, onChange, by using setInput({ [name]: newValue });.

https://codesandbox.io/s/beautiful-brattain-5foeu?file=/src/App.js

Hope that was decent, never answered a question before. The article i gave on top explains it further, you could possibly use a reducer like done there too, i used one state.

Step by step: User enters a numberVariable, which will be number of inputs created, let's say they entered 6

We make an array and push 0,1,2,3,4,5 in it.

Then we have the initialState object, for each element in the array, we create an object inside it, and initialState now looks like that; 0: "", 1: "", 2: "", ... and so on.

We pass initialState object as, well, initial state of our state.

When we are creating the input fields, we give them a unique name that will be same as objects inside initialState. So first input's name is 0, second input's name is 1 and so on...

Also every input is created with value={input[inputName]} so it gets the right object from the state.

All input's states are handled by handleUserInputChange.

Now our user started writing on one of the inputs, let's say he's writing on the input that is named 2. We get the name of that input with e.target.name, then we set our new state with setInput({ [e.target.name]: e.target.value }) So the object called 2, get's the input named 2's value. That's it. This happens for each input, and their values never get mixed.

about 4 years ago · Juan Pablo Isaza Report

0

Just simplifying the correct answer a bit. The strategy is to store all the controlled input state as a list, and give each input an update function that only updates its position in the array.

const ManyInputs = ({howMany}) => {
  // Like ["", "", ""]
  const [inputs, setInputs] = useState(Array.from(new Array(howMany)).map(_ => ""));

const handleUserInputChange = position => (e) => {
  // Update the correct input state
  setInputs(...inputs.slice(0, position), e.target.value, ...inputs.slice(position+1));
};

return <>
  {inputs.map((text, i) => <input 
  value={text}
   onChange={handleUserInputChange(i)}>
   </input>}
</>;
};
about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!