So I have the below code:
function Crafting(props) {
const craftItems = [
{
key: 1,
name: "Bronze sword",
},
{
key: 2,
name: "Iron sword",
},
{
key: 3,
name: "Steel sword",
},
];
const [item, setItem] = useState();
const [itemKey, setItemKey] = useState();
function onChangeHandler(event) {
setItem(event.target.value);
setItemKey(event.target.itemID);
console.log(event);
}
function onSubmitHandler(event) {
event.preventDefault();
console.log(item);
console.log(itemKey);
}
return (
<Card className={classes.renderwin}>
<form onSubmit={onSubmitHandler}>
<label htmlFor="items">Select an item</label>
<select name="items" onChange={onChangeHandler}>
{craftItems.map((item) => (
<option key={item.key} itemID={item.key}> {item.name} </option>
))}
</select>
<Button type="submit">Craft item</Button>
</form>
</Card>
);
}
I want to be able to retrieve the original key value against the item. I tried using "key", then added in a custom prop called "itemID" but they both just return as undefined. How do I fetch the ID back based on the value selection?
The issue is that you can basically store only an option value and retrieve that in the handler to save into state.
I would place the item.key on the option element's value attribute.
<select name="items" onChange={onChangeHandler}>
{craftItems.map((item) => (
<option key={item.key} value={item.key}>
{item.name}
</option>
))}
</select>
Access the onChange event object's value property in the handler and convert it back to a Number type before storing in state.
function onChangeHandler(event) {
const { value } = event.target;
setItemKey(Number(value));
}
When accessing in the submit handler use the stored itemKey to search the craftItems array for the matching object.
function onSubmitHandler(event) {
event.preventDefault();
const item = craftItems.find(({ key }) => key === itemKey);
console.log(item?.name);
console.log(item?.key);
}
function Crafting(props) {
const craftItems = [
{
key: 1,
name: "Bronze sword"
},
{
key: 2,
name: "Iron sword"
},
{
key: 3,
name: "Steel sword"
}
];
const [itemKey, setItemKey] = React.useState();
function onChangeHandler(event) {
const { value } = event.target;
setItemKey(Number(value));
console.log({ value });
}
function onSubmitHandler(event) {
event.preventDefault();
const item = craftItems.find(({ key }) => key === itemKey);
console.log(item && item.name);
console.log(item && item.key);
}
return (
// <Card className={classes.renderwin}>
<form onSubmit={onSubmitHandler}>
<label htmlFor="items">Select an item</label>
<select name="items" onChange={onChangeHandler}>
{craftItems.map((item) => (
<option key={item.key} value={item.key}>
{item.name}
</option>
))}
</select>
<button type="submit">Craft item</button>
</form>
// </Card>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(
<Crafting />,
rootElement
);
<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="root" />
Place a value on the option like this:
{craftItems.map((item) => (
<option value={item.key} key={item.key}>{item.name}</option>
))}