sash
sash

Reputation: 91

How to add to array when user has done typing?

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

Answers (3)

0stone0
0stone0

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>


Edit based on OP's comment;

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

sphrases
sphrases

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

Haim Abeles
Haim Abeles

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

Related Questions