Reputation: 17
I'm trying to save multiple values in one select and saving it in useState to use it again somewhere else. but it's not working I only get undefined values in my console.log .
here is the code:
import * as React from "react";
function App() {
const [option, setOption] = React.useState({ width: 0, height: 0 });
const options = [
{
label: "first",
value: { width: 10, height: 10 },
},
{
label: "second",
value: { width: 20, height: 20 },
},
{
label: "third",
value: { width: 30, height: 30 },
},
];
const selectHandler = (e) => {
setOption(e.target.value);
};
console.log(option.width);
console.log(option.height);
return (
<div className="App">
<h1>Test!</h1>
<select value={options.value} onChange={selectHandler}>
{options.map((option) => (
<option key={option.label}>{option.label}</option>
))}
</select>
<p></p>
</div>
);
}
export default App;
I don't know if it's even possible... thanks in advance!
Upvotes: 0
Views: 3168
Reputation: 36
You're setting your values in the state in a wrong manner. I've made some changes to your select handler function which hopefully solves your problem:
import * as React from 'react';
function App() {
const [option, setOption] = React.useState({ width: 0, height: 0 });
const options = [
{
label: 'first',
value: { width: 10, height: 10 },
},
{
label: 'second',
value: { width: 20, height: 20 },
},
{
label: 'third',
value: { width: 30, height: 30 },
},
];
const selectHandler = (e) => {
console.log(e.target.value);
switch (e.target.value) {
case 'first':
setOption(options[0].value);
break;
case 'second':
setOption(options[1].value);
break;
case 'third':
setOption(options[2].value);
break;
}
};
console.log(option.width);
console.log(option.height);
return (
<div className="App">
<h1>Test!</h1>
<select value={options.value} onChange={(e) => selectHandler(e)}>
{options.map((option) => (
<option key={option.label}>{option.label}</option>
))}
</select>
<p></p>
</div>
);
}
export default App;
Upvotes: 2
Reputation: 63514
Add a value
attribute to each option. Assign it the option label.
In selectHandler
use find
to locate the object in the options array with a label that matches the option value, and then add its value property to state.
To log changes to state use useEffect
to watch for those changes and then log the result (state updates are async so you wouldn't be able to log the change immediately).
const { useEffect, useState } = React;
function Example({ options }) {
const [option, setOption] = React.useState({
width: 0,
height: 0
});
const selectHandler = (e) => {
const { value } = e.target;
const found = options.find(obj => obj.label === value);
if (found) setOption(found.value);
};
useEffect(() => console.log(option), [option]);
return (
<div className="App">
<h1>Test!</h1>
<select onChange={selectHandler}>
{options.map(option => (
<option
key={option.label}
value={option.label}
>{option.label}
</option>
))}
</select>
<p></p>
</div>
);
}
const options=[{label:"first",value:{width:10,height:10}},{label:"second",value:{width:20,height:20}},{label:"third",value:{width:30,height:30}}];
ReactDOM.render(
<Example options={options } />,
document.getElementById('react')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="react"></div>
Upvotes: 0