繁体   English   中英

通过 NavLink 更改路线后,Ion Popover 不会关闭

[英]Ion Popover will not dismiss after changing route via NavLink

我有一个UserCard组件,其中有一个垂直Elipsis 当我单击Elipsis时,会出现一个带有三个选项的弹出框 - Delete UserKick UserEdit 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM