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:
- If i set the value to an empty string, then i cannot update it
- 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
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)));
};