Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

233
Vistas
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 Respuestas
Responde la pregunta

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 Denunciar

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda