如何从 React hooks 中获取所选选项的值?

How to get the value of selected option from React hooks?

我有如下 React 组件:

const ProductCell = (props) => {
    const [option, setOption] = useState();

    return(
     <div>
        <NativeSelect
            value={option}
            onChange={e => setOption(e.target.value)}
        >

            {props.product.variations.nodes.map(  // here I extracted all the item
                (item, i) => (
                    <option value={item} key={i}>{item.name}</option>  // set option value to item object
                ))
            }
                    
        </NativeSelect>

        <Typography variant="h5" className={classes.title}>
            {option.price}  // I want to update the value of price according to the selected option. 
        </Typography>       // according to the selected option above
     </div>
    )
}

我有一个来自 React Material-Ui 的 NativeSelect 组件,所以基本上它是一个 Select html 标签。在上面的代码中,我所做的是,提取 props.product.variations.nodes 中的所有元素并将提取的所有元素放入 item 并将每个元素放入 <options/> 标记中。

项目的 Json 对象将如下所示:

"variations": {
    "nodes": [
        {
            "id": "someId",
            "name": "abc1234",
            "variationId": 24,
            "price": "0.00"
        },
        {
           .. another ID, name,variation and price
        }
    ]
}

如您所见,我将 idnamevariationIdprice 的部分定位为一个对象。因此每个 <option/> 标签将以 item.name 作为呈现给用户。到目前为止这部分没有问题,假设有5个变化,并且可以全部呈现。

我想做的是:

我想更新 <Typography /> 组件下的价格值。例如,用户在 Select 中选择了第 3 个选项,我想更新 <Typography /> 中第 3 个项目的 price 值。

我试过的:

我创建了一个反应钩子 const [option, setOption] = useState(); ,然后当 handleChange 时,我 setOption()NativeSelect 组件中的 event.target.value 。因此<option />标签的value设置为item对象。

最后,我从 Typography 部分的钩子中获得了 price 值。

但是我得到的是:

控制台日志中的价格值为 undefined。所以我无法获取 option.price.

的值

和这个错误:

TypeError: Cannot read property 'price' of undefined

问题:

如何在上面的示例中的 NativeSelect 组件之外获取 option.price 值(我希望它与 item.price 相同)?

我暂时就我所理解的尽量解释了。因此,我们将不胜感激任何帮助。

更新:

这是我在控制台记录 variation.node.map() 部分中的 item 对象和 onHandleChanged 部分中的 data 对象时得到的结果,但也产生相同的结果:

您必须在 ProductCell 组件上设置一个默认的选定选项。此外,当您访问 event.target.value.

上的值时,您的 onChange 处理程序将收到 string 而不是 object

来自docs

function(event: object) => void event: The event source of the callback. You can pull out the new value by accessing event.target.value (string).

event.target.value 将是一个字符串,即使您在 NativeSelect 组件上将 value 作为 object 传递。

你可能想做什么?不要将当前选定的项目设置为 object,而是使用 id 并具有 look-ups 使用当前选定的项目的功能 id.

检查下面的代码。

const ProductCell = (props) => {
  const { variations } = props.product;
  const { nodes } = variations;

  // we're setting the first node's id as selected value
  const [selectedId, setSelectedId] = useState(nodes[0].id);

  const getSelectedPrice = () => {
    // finds the node from the current `selectedId`
    // and returns `price`
    const obj = nodes.find((node) => node.id === selectedId);
    return obj.price;
  };

  function onChange(event) {
    // event.target.value will be the id of the current
    // selected node
    setSelectedId(parseInt(event.target.value));
  }

  return (
    <div>
      <NativeSelect value={selectedId} onChange={onChange}>
        {nodes.map((item, i) => (
          <option value={item.id} key={i}>
            {item.name}
          </option>
        ))}
      </NativeSelect>
      <Typography variant="h5">{getSelectedPrice()}</Typography>
    </div>
  );
};

另请注意,我们在每个 option 上将 id 作为 value 道具传递。

<option value={item.id} key={i}>

以及我们现在如何显示 price,我们称我们的 getSelectedPrice()


更新

我想到了更好的解决方案。我意识到你可以将你的 selected 状态设置为一个对象,并在你的 onChange 处理程序上给定 event.target.value 中的 id 找到 nodes 上的项目并设置它作为你的新 selected 状态。

const ProductCell = (props) => {
  const { variations } = props.product;
  const { nodes } = variations;

  const [selected, setSelected] = useState(nodes[0]);

  function onChange(event) {
    const value = parseInt(event.target.value);
    setSelected(nodes.find((node) => node.id === value));
  }

  return (
    <div>
      <NativeSelect value={selected.id} onChange={onChange}>
        {nodes.map((item, i) => (
          <option value={item.id} key={i}>
            {item.name}
          </option>
        ))}
      </NativeSelect>
      <Typography variant="h5">{selected.price}</Typography>
    </div>
  );
};