MaterialUI HtmlTooltip 嵌套 Material UI Select MenuItem / select onChange 处理程序中的合成事件(?)问题

Nesting MaterialUI HtmlTooltip inside of Material UI Select MenuItem / Synthetic event(?) problem in select onChange handler

---目标---

我正在尝试 Material UI select 包含包含在 HtmlTooltips 中的 MenuItems,它显示有关每个列表选项的悬停信息。

我现在有意将它作为 PoC 保持简单,稍后将动态映射它。

---当前代码---

我正在使用 controller/view 模式并且在视图中有以下 material UI Select 组件:

<FormControl
  variant="outlined"
>
  <InputLabel id="owner">Owner</InputLabel>

  <Select
    labelId="owner"
    id="owner"
    defaultValue="0"
    value={props.owner}
    onChange={props.handleOwnerChange}
  >
    <MenuItem id="none" value="none" disabled>
      (Select a Value)
    </MenuItem>

    <MenuItem id="231-abc" value="231-abc" disabled>
      Charlie Person
    </MenuItem>

    <HtmlTooltip
      title={
        <>
          <Typography color="inherit">
            Steve Human
          </Typography>
          <b>{"Next PTO:"}</b>{" "}
          <i style={{ color: "red" }}>
            {" 12/25/20-01/01/20"}
          </i>
        </>
      }
    >
      <MenuItem id="123-abc" value="123-abc">
        Steve Human
      </MenuItem>
    </HtmlTooltip>
    
  </Select>
</FormControl>

...在控制器中,我的状态getter/setter...

   const [owner, setOwner] = useState("null");

...以及在控制器中,select 用于在 selected 列表项时更改状态值的函数:

 const handleOwnerChange = (event) => {
      setOwner(event.target.value); //
 };
由于某种原因,

event.target.value 在这种情况下未定义。

因为使用setOwner(event.target.value)时是async的,所以需要将事件目标值保存到一个变量中,而不是直接在setOwner中使用。 详情请参考here.

Event pooling

The SyntheticEvent is pooled. This means that the SyntheticEvent object will be reused and all properties will be nullified after the event callback has been invoked. This is for performance reasons. As such, you cannot access the event in an asynchronous way.

function onClick(event) {
  console.log(event); // => nullified object.
  console.log(event.type); // => "click"
  var eventType = event.type; // => "click"

  setTimeout(function() {
    console.log(event.type); // => null
    console.log(eventType); // => "click"
  }, 0);

  this.setState({clickEvent: event}); // Won't work. this.state.clickEvent will only contain null values.
  this.setState({eventType: event.type}); // You can still export event properties.
}

在尝试了 Eric 的建议后,我弄清楚了问题所在。这是我最终需要做的:

基本上,我只需要:

  • 反转组件包装的顺序 - 用 MenuItem 包装 HtmlTooltip,而不是用 HtmlTooltip 包装 MenuItem。
  • 将列表项文本括在 div

---工作代码---

我正在使用 controller/view 模式并且在视图中有以下 material UI Select 组件:

 <FormControl
   variant="outlined"
 >
  <InputLabel id="owner">Owner</InputLabel>

   <Select
     labelId="owner"
     id="owner"
     defaultValue="none"
     value={props.owner}
     onChange={props.handleOwnerChange}
   >
     <MenuItem id="none" value="none" disabled>
       (Select a Value)
     </MenuItem>

     <MenuItem id="231-abc" value="231-abc" disabled>
       Charlie Person
     </MenuItem>

     <MenuItem id="123-abc" value="123-abc">
       <HtmlTooltip
         title={
           <>
             <Typography color="inherit">
               Steve Human
             </Typography>
             <b>{"Next PTO:"}</b>{" "}
             <i style={{ color: "red" }}>
             {" 12/25/20-01/01/20"}
             </i>
           </>
         }
      >
        <div>Steve Human</div>
      </HtmlTooltip>
   </MenuItem>

   </Select>
</FormControl>

...在控制器中,我的状态getter/setter...

  const [owner, setOwner] = useState("none");

...以及在控制器中,select 用于在 selected 列表项时更改状态值的函数:

  const handleOwnerChange = (event) => {
       setOwner(event.currentTarget.id);
  };