【问题标题】:How to get the value of selected option from React hooks?如何从 React 钩子中获取选定选项的值?
【发布时间】:2020-12-04 02:38:17
【问题描述】:

我有这个 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 放入并将每个元素放入&lt;options/&gt; 标记中。

item 的 Json 对象如下所示:

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

如您所见,我将idnamevariationIdprice 的部分作为对象。因此,每个&lt;option/&gt; 标签都将与item.name 一起呈现给用户。到目前为止,这部分没有问题,假设有 5 个变体,并且可以全部呈现。

我想做的是:

我想更新&lt;Typography /&gt; 组件下的价格值。例如,用户在Select 中选择了第三个选项,我想更新&lt;Typography /&gt; 中第三项的price 值。

我尝试了什么:

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

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

但我得到的是:

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

这个错误:

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

问题:

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

我已尽力根据我目前所了解的情况进行解释。因此,我们将不胜感激任何帮助。

更新:

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

【问题讨论】:

    标签: reactjs react-hooks react-material


    【解决方案1】:

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

    来自docs

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

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

    您可能想做什么?不要将当前选中的项目设置为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 属性传递给我们的每个options。

    <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>
      );
    };
    

    【讨论】:

    • 我需要问一件事,对于这2行代码const { variations } = props.product; const { nodes } = variations;开头,这是我们如何在另一个数组中破坏数组吗?假设是props.product.variations.map(the item inside),但我们做到了{variations} = props.product{nodes} = variation,这2个链接让我很困惑
    • 这就是你如何破坏object 以获得value,它被称为destructuring assignment。虽然它也适用于array,但在我们上面的代码中处理的是objects。
    猜你喜欢
    • 2017-01-23
    • 2020-05-26
    • 2015-08-24
    • 2015-05-09
    • 1970-01-01
    • 1970-01-01
    • 2019-10-15
    • 1970-01-01
    • 2020-03-18
    相关资源
    最近更新 更多