[英]Ion Popover will not dismiss after changing route via NavLink
我有一个UserCard
组件,其中有一个垂直Elipsis
。 当我单击Elipsis
时,会出现一个带有三个选项的弹出框 - Delete User
、 Kick User
和Edit User
。
前两个按钮调度一个将用户从商店中删除的操作,因此导致我的组件重新渲染,并且有关该用户的UserCard
组件从 UI 中卸载。
问题在于第三个选项 - Edit User
,它只是一个NavLink
,它导致管理员可以编辑用户信息的页面。 当我单击该链接时,我被重定向到EditUser
组件,但IonPopover
仍然存在,尽管该组件本身已从 UI 中卸载。
我尝试了以下方法:
在设置popover
框 state 的NavLink
上添加onClick
事件:
<NavLink onClick={e => togglePopover({ open: false, event: undefined })} to={"/users/edit/" + user.id}>Edit User</NavLink>
由于 state 的设置是asynchronous
的,因此组件将在togglePopover
完成之前从UI
中卸载,并且IonPopover
仍然可见。
我尝试的第二件事是类似的:
useEffect(() => () => togglePopover({ open: false, event: undefined }), [])
这将在组件从 UI 卸载之前运行togglePopover
function 但这也不起作用(我猜是出于同样的原因)。
下面是UserCard
组件的完整代码:
const UserCard: React.FC<{ user: User, userReducer: UserState }> = ({ user, userReducer }) => {
const dispatch = useDispatch<AppDispatch>()
const [popover, togglePopover] = useState<{ open: boolean, event: Event | undefined }>({ open: false, event: undefined })
const [submitted, setSubmitted] = useState<boolean>(false)
const [infoAlert] = useIonAlert()
useEffect(() => {
// code which calls infoAlert based on updateUserStatus change - caused by handleKick and handleDelete calls
}, [userReducer.updateUserStatus])
useEffect(() => () => togglePopover({ open: false, event: undefined }), [])
const handleKick = () => {
// Dispatches action which kicks the user
}
const handleDelete = () => {
// Dispatches action which kicks the user
}
return (
<div className="grid grid-cols-12 border-solid border-b-2 border-slate-100 py-2 mb-2">
<IonLoading isOpen={userReducer.updateUserStatus === "pending"} message="Updating user... Please wait." />
<BiUserCircle className="col-span-1 w-8 h-10 text-slate-800" />
<span className="col-span-10 ml-3">
<p className="text-base font-bold text-slate-600"> {(user.firstName + " " + user.lastName)}</p>
<p className="text-sm text-slate-600 -mt-1"> {user.email} </p>
</span>
<span className="col-span-1 flex items-center justify-end text-slate-800 cursor-pointer">
<FaEllipsisV onClick={e => togglePopover({ open: true, event: e.nativeEvent })} />
</span>
{userReducer.current.type_id >= user.type_id ? <IonPopover
onDidDismiss={e => togglePopover({ open: false, event: undefined })}
isOpen={popover.open} event={popover.event}
size="auto" side="bottom" alignment="center">
{userReducer.current.type_id === 4 ? <IonItem className="text-red-500 cursor-pointer hover:text-red-600" detail={false} onClick={handleDelete}>
<BsTrashFill className="mr-3" />
<p>Delete</p>
</IonItem> : null}
<IonItem className="text-blue-500 cursor-pointer hover:text-blue-600" detail={false} onClick={handleKick}>
<MdPersonRemoveAlt1 className="mr-3" />
<p>Leave Organization</p>
</IonItem>
<IonItem onClick={e => togglePopover({ open: false, event: undefined })} className="text-cythero-primary cursor-pointer hover:text-cythero-primary-dark" detail={false}>
<BsFillPencilFill className="mr-3" />
<NavLink onClick={e => togglePopover({ open: false, event: undefined })} to={"/users/edit/" + user.id}>Edit User</NavLink> /* Here is the issue. When this NavLink redirects to /users/edit/X, the popover is still being displayed. */
</IonItem>
</IonPopover> : null}
</div>
)
}
我有一个解决方案 - 删除NavLink
并将其替换为具有handleRedirect
function 调用的按钮:
const [redirect, setRedirect] = useState<string>("")
const handleRedirect = id => {
togglePopover({ open: false, event: undefined })
setTimeout(() => setRedirect("/users/edit/" + id), 100)
}
....
if (redirect !== "") return <Redirect to={redirect} />
理论上应该可以工作 - 肯定togglePopover
将花费不到 100 毫秒的时间来完成,之后, setRedirect 将导致<Redirect to={redirect} />
呈现并将用户发送到正确的页面,但这似乎很糟糕解决方案 - 必须有更好的方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.