I have input number in which I specify a number that stands for the number of rendered components. For this I have two states with a number and an array. In the array I just pass one value with id.
The code in useEffect is not working correctly. When I click on button up in input number, the Item are not added to the array. And when I click on button down, the items are not deleted.
Where did I go wrong here?
It should also be localStorage in the code.
const [Quantity, setQuantity] = useState('0')
const [Arr, setArr] = useState([])
useEffect(() => {
[...Array(parseInt(Quantity))].map((_, i) => {
setArr((prev) => {
const Item = { id: i };
localStorage.setItem("LSKey", JSON.stringify([...prev, Item]))
return [...prev, Item];
});
});
}, [])
<input type="number" value={Quantity || ""} min={0} onChange={(event) => {
setQuantity(event.target.value)
}} />
render components
Arr.map((Item) => (
<Components key={Item.id} id={Item.id} />
))
>Solution :
The main issue is your effect hook only runs once on mount due to its empty dependencies array.
You’ll want to depend on Quantity and only update state / localStorage after you’ve constructed the new array.
const [Quantity, setQuantity] = useState(0); // use an actual number, not a string
const [Arr, setArr] = useState([]);
useEffect(() => {
const arr = Array.from({ length: Quantity }, (_, id) => ({ id }));
localStorage.setItem('LSKey', JSON.stringify(arr));
setArr(arr); // no need to use the previous value
}, [Quantity]); // set Quantity as an effect dependency
You can also use valueAsNumber to avoid parseInt()…
<input
type="number"
value={Quantity}
min="0"
onChange={(e) => setQuantity(e.target.valueAsNumber)}
/>