Home > database >  Fetch the value of props other than "value" from a custom component?
Fetch the value of props other than "value" from a custom component?

Time:12-03

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?

CodePudding user response:

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" />
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

Place a value on the option like this:

{craftItems.map((item) => (
  <option value={item.key} key={item.key}>{item.name}</option>
))}
  • Related