Home > database >  React - How to change input values inside loop when state change
React - How to change input values inside loop when state change

Time:11-07

I'm new to react and i stumbled upon an issue to which i need help with. I'm placing multiple input elements and i'm trying to change their values based on a state change which, in this case is manual (true or false);

The code is a simple form where you have 12 inputs inside through a loop. My issue is that based on wether manual is true or false I want to change the inputs value.

If manual returns true, i want it to act normally (input normally) but when manual returns false i want all my input values to display the number 12 and vice versa. The manual state is triggered by a button as seen below.

I have two problems here:

  1. If i set the value to an empty string, then i cannot update it
  2. If i condition what to show like if i have two inputs - one with the value and one without based on the returned state of manual i get the controlled and uncontrolled error for doing this.

Can anyone help me implement this? I have tried using multiple solutions with no success:

import React, {useState, useEffect, useRef} from 'react';

function App() {

    const [budget, setBudget] = useState([])
    const [manual, setManual] = useState(false);

    const handleInput = inputEv =>{
        const budgetState = budget;
        const input = {index: inputEv.target.getAttribute('index'), value: inputEv.target.value};
        
        // if data input already exists - update it
        if(budgetState.some(data=>data.index === input.index)){
            var current = budgetState.find(data=>data.index === input.index);
            current.value = input.value;
        } else {
            budgetState.push(input)
            setBudget(budgetState);
        }
    }

    return (
        <div>
            <form className="inputs">
            {Array(12).fill().map((e, index)=>(
                <div  key={index} className="month">
                    <input type="text" onChange={handleInput} index={index} disabled={manual ? false : true}/>
                </div>
            ))}
            </form>
            <button onClick={()=>setManual(!manual)}>Click</button>
        </div>
    );
}

export default App;

CodePudding user response:

Before starting logic part, you first have to declare state as:

const length = 12;
const [budget, setBudget] = useState(Array.from({ length }, () => 12));
const [manual, setManual] = useState(false);

Live Demo

Codesandbox Demo

You have to consider two scenarios:

1) When you click on the button which will toggle to manual value

It will call a function changeManual whose definition is:

function changeManual() {
  if (manual) setBudget((state) => state.map((o) => 12));
  else setBudget(budget);

  setManual(!manual);
}

2) When you input on one of the input HTML element then you have to update the respective value in an array.

You need event and index, so you can call a function which internally pass both the value as

<input
  type="text"
  value={budget[index]}
  onChange={(e) => handleInput(e, index)}
  disabled={manual ? false : true}
/>

which will trigger handleInput function whose definition is

const handleInput = (inputEv, index) => {
  const value = inputEv.target.value;
  setBudget((state) => state.map((val, i) => (i !== index ? val : value)));
};
  • Related