我正在尝试向我的应用添加IonPopover
。最初,我是通过定义自定义元素并使用popoverController
创建弹出框来实现的。它工作正常,但感觉有点混乱,因此我将组件从类转换为功能组件以使用React钩子。
显示以下示例代码:
import React, { useState } from 'react';
import { IonPopover, IonButton } from '@ionic/react';
export const PopoverExample: React.FC = () => {
const [showPopover, setShowPopover] = useState(false);
return (
<>
<IonPopover
isOpen={showPopover}
cssClass='my-custom-class'
onDidDismiss={e => setShowPopover(false)}
>
<p>This is popover content</p>
</IonPopover>
<IonButton onClick={() => setShowPopover(true)}>Show Popover</IonButton>
</>
);
};
现在,这主要是我正在使用的内容。该文档还说:
为了相对于单击的元素定位弹出框,需要将click事件传递到
present
方法的选项中。如果未传递事件,则弹出框将位于视口的中心。 我不希望这个弹出窗口位于中心,因此我需要通过一个事件。这是我遇到麻烦的地方。 我这样创建了一个钩子:
const [popoverEvent, setPopoverEvent] = useState();
按下打开弹出窗口的按钮时,将运行此代码,该代码将popoverEvent
的值设置为事件。
onClick={(e) => { setShowPopover(true); setPopoverEvent(e); }}
然后我将其传递给弹出窗口:
<IonPopover
isOpen={showPopover}
cssClass='popover-style-class'
event={popoverEvent}
onDidDismiss={_ => { setShowPopover(false); setPopoverEvent(null); }}
>
//.....
但是,这种方式会产生较大的打字错误:
Argument of type 'MouseEvent<HTMLIonIconElement, MouseEvent>' is not assignable to parameter of type '(prevState: undefined) => undefined'.
Type 'MouseEvent<HTMLIonIconElement, MouseEvent>' provides no match for the signature '(prevState: undefined): undefined'.
无论我将useState设置为什么(即undefined
,MouseEvent
,Event
,我最终都会在文件中某处出现错误,该错误是我不喜欢的正在尝试将类型x
分配为类型y
或类似的内容。
如何将该事件传递给弹出窗口,使其显示在按钮上?
这是完整的代码:
const BluetoothDeviceItem = (Props, { }) => {
const [icon, setIcon] = useState(closeOutline);
const [showPopover, setShowPopover] = useState(false);
const [popoverEvent, setPopoverEvent] = useState();
useEffect(() => {
updateIcons();
}, []);
const updateIcons = () => {
const item = $("#" + Props.address);
const connectingIcon = $(item).find(".connecting-icons");
const spinnerIcon = $(item).find(".connecting-spinner");
switch (Props.state()) {
case 'not_connected':
spinnerIcon.css("opacity", "0");
connectingIcon.css("color", "var(--ion-color-danger)");
connectingIcon.css("opacity", "1");
setIcon(closeOutline);
break;
case 'connecting':
spinnerIcon.css("opacity", "1");
connectingIcon.css("opacity", "0");
setIcon("");
break;
case 'connected':
spinnerIcon.css("opacity", "0");
connectingIcon.css("opacity", "1");
connectingIcon.css("color", "var(--ion-color-success)");
setIcon(checkmarkOutline);
break;
}
}
const rerender = () => {
updateIcons();
}
const handleClick = async () => {
const interactable = Props.interactable || true;
if (Props.state() !== "connecting" && Props.onClick && interactable) Props.onClick(Props.address); //If the device is already connecting, don't allow user to click again
rerender();
}
const toggleChanged = () => {
console.log("here")
}
const interactable = Props.interactable || true;
return (
<IonItem class={Props.class || "" + (Props.interactable ? " bluetooth-item-container" : "")} id={Props.address} onClick={handleClick}>
<IonAvatar slot="start" class="bluetooth-icon-container">
<IonIcon icon={bluetoothOutline} class="bluetooth-icon"></IonIcon>
</IonAvatar>
<IonAvatar slot="end" class="connecting-icons-container">
<IonIcon icon={icon} class="connecting-icons"></IonIcon>
<IonSpinner name="dots" class="connecting-spinner"></IonSpinner>
{interactable ? <IonIcon icon={chevronDownOutline} class="popover-icon" onClick={(e) => { setShowPopover(true); setPopoverEvent(e); }}></IonIcon> : <></>}
</IonAvatar>
<IonLabel>
<div className="device-name">{Props.name || "Unknown"}</div>
<div className="device-address">{Props.address}</div>
</IonLabel>
<IonPopover
isOpen={showPopover}
cssClass='popover-style-class'
event={popoverEvent}
onDidDismiss={_ => { setShowPopover(false); setPopoverEvent(null); }}
>
<IonList>
<IonItem lines="none" class="popover-item">
<IonLabel class="popover-autoconnect-label">Autoconnect</IonLabel>
<IonToggle slot="end" color="success" onIonChange={toggleChanged}></IonToggle>
</IonItem>
</IonList>
</IonPopover>
</IonItem>
);
}
export default BluetoothDeviceItem;
答案 0 :(得分:0)
当我这样做时,它将在我的项目中运行。您的代码不同吗?
BluetoothDeviceItem.js
paginationKey
Popover.js
selenium
答案 1 :(得分:0)
这是一个打字稿错误。如果调用export interface BookList {
title: string;
price: number;
cover: string
synopsis: string;
}
,则打字稿会根据初始值推断状态的类型。但是,当您调用没有初始值的useState(someInitialValue)
时,打字稿实际上会确定此状态的值为useState()
,并且永远只能是undefined
。尝试undefined
以外的其他任何操作时,您会得到一个错误,这就是这里发生的情况。
由于打字稿无法推断状态类型,因此您必须通过手动在setState
上设置通用变量来告诉打字稿期待什么。
undefined
现在已知useState
的类型是const [popoverEvent, setPopoverEvent] = useState<MouseEvent<HTMLIonIconElement, MouseEvent>>();
或popoverEvent
,并且在事件中调用MouseEvent<HTMLIonIconElement, MouseEvent>
时不会再有错误。