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

问题描述

我有这个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>
    )
}

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

item的Json对象如下所示:

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

如您所见,我将idnamevariationIdprice的一部分作为对象。因此,每个<option/>标签将以item.name的形式呈现给用户。到目前为止,这部分没有问题,可以说有5种变体,并且可以展示所有变体。

我想做的是:

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

我尝试过的事情:

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

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

但是我得到的是:

控制台日志中的价格值为undefined。因此我无法获得option.price的值。

和此错误

TypeError:无法读取未定义的属性“价格”

问题:

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

根据目前的理解,我尽力解释。因此,任何帮助将不胜感激。

更新

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

enter image description here

解决方法

您必须在ProductCell组件上设置默认的选定选项。此外,当您访问onChange上的值时,您的string处理程序将收到object而不是event.target.value

docs

function(event: object) => void event:回调的事件源。您可以通过访问event.target.value(字符串)来提取新值。

即使您在event.target.value组件上将value作为object传递,

NativeSelect仍将是一个字符串。

您可能想做什么?不要将当前选定的项目设置为object,而要使用id并具有使用当前选定的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>
  );
};

还要注意,在我们的每个id上都将value作为option道具传递。

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

现在我们如何显示price,我们称之为getSelectedPrice()

Edit gallant-agnesi-289ei


更新

我认为一个更好的解决方案。我意识到,您可以将selected状态设置为对象,并在onChange处理程序上给定id中的event.target.valuenodes上找到该项并进行设置作为您新的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>
  );
};

Edit quizzical-nash-mg4bc