Reputation: 91
I have the following array :
const [stock, setStock] = useState([])
I also have two input fields to enter stock (this is for different products but all stocks must be added to the stock array state).
How can I add the stock inputs values to the stock array? I only want to add stock when user is done typing. There's only one submit button and two stock inputs.
If I had only one stock field I would've just saved it in the stock state with onChange event but there I have two stock fields so I wanted to use an array.
Edit: using map based on color and size values to render the stock input for each variant of the product.
Upvotes: 0
Views: 52
Reputation: 43894
I'd use an Object, on which you can use something like the input's name as the key, then set the state to the value of the input field.
This way you can dynamically add values for each product
const { useState } = React;
const Example = () => {
const [stock, setStock] = useState({ })
function addStock(){
setStock({
...stock,
[event.target.name]: event.target.value
});
}
console.log(stock);
return (
<div>
<label for={'product_1'}>{'Product 1'}</label>
<input onChange={addStock} name={'product_1'} />
<br />
<label for={'product_2'}>{'Product 2'}</label>
<input onChange={addStock} name={'product_2'} />
</div>
)
}
ReactDOM.render(<Example />, document.getElementById("react"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="react"></div>
If the inputs are generated by a map()
, you just need to find an unique key to use as the name
and therefore the Object key.
Consider the following snippet, same idea as above, but with map()
which reders <input>
and <label>
for each object in the data
array
const { useState } = React;
const data = [
{ color: 'red', size: 15 },
{ color: 'blue', size: 30 }
];
const Example = () => {
const [stock, setStock] = useState({ })
function addStock(){
setStock({
...stock,
[event.target.name]: event.target.value
});
}
console.log(stock);
return (
<div id='demo'>
{
data.map(d => {
const customKey = Object.values(d).join('_');
return (
<React.Fragment>
<label for={customKey}>{customKey}</label>
<input onChange={addStock} name={customKey} />
</React.Fragment>
);
})
}
</div>
)
}
ReactDOM.render(<Example />, document.getElementById("react"));
#demo { width: 150px; display: flex; flex-direction: column; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="react"></div>
Upvotes: 3
Reputation: 53
you could create a temporary second state to store the stock in.
// temporary stock state
const [tmpStock1, setTmpStock1] = useState(0);
const [tmpStock2, setTmpStock2] = useState(0);
const [stock, setStock] = useState([])
Then update the states on each input's onChange event. When clicking the button, those two states can be saved into the array and possibly reset.
Upvotes: -1
Reputation: 1021
You will use an object
with two keys (one for each input) in the following way
const [stock, setStock] = useState({})
function handleChange(event) {
setStock({..stock, [event.target.name]: event.target.value});
}
return (
<input name="item1" onChange={handleChange} />
<input name="item2" onChange={handleChange} />
)
Upvotes: 1