我有一个应用程序可以执行通常的 CRUD 功能,其中有一个列表页面,该页面将链接到创建和编辑资源。这是一个视觉效果:
List
|__Create
|__Edit
创建和编辑表单共享一个非常相似的表单,所以我只是重用它。
我的问题来自于当我创建/编辑某些内容时(这是有效的),我想显示ant design的消息,并使用react-router中的
useNavigate
导航回我的列表页面。问题是,当我的创建/编辑成功时,在我的成功回调中,导航时,我根本看不到弹出的消息。然而,当我没有离开时,该消息就会弹出。
我的假设是因为我的消息的
contextHolder
可能位于创建/编辑页面上,离开会让我失去它,从而无法看到它。
我的异步请求使用的是apollo graphql,所以它看起来像这样
// CreateEditForm.tsx
const navigate = useNavigate();
const [messageApi, contextHolder] = message.useMessage();
// ....
onComplete: (data) => {
if (!data.error) {
return messageApi.error('Error');
}
messageApi.success('Success');
return navigate('/list')
re
}
//.... in my CreateEditForm.tsx's render
return (
<>
{contextHolder}
<Form>
{/* the rest of my code */}
);
由于我的假设是离开页面不会显示消息,因此我尝试将 contextHolder 提取到列表中的更高级别,但这似乎不起作用。
编辑:我意识到,如果我将异步/等待添加到
messageApi.success
,消息will会出现,无论默认超时有多长,然后它将导航。然而,我希望有一个更同步的解决方案。
https://codesandbox.io/s/sharp-tree-mysc4n?file=/src/AnotherPage.tsx
有人遇到过类似的问题吗?先谢谢你了
这个
Message
API 在我看来有点有趣/奇怪,但我能够通过将 message
用法移动到主路线上方存在的布局路线中来使事情正常工作,并通过反应上下文。示例:
索引.tsx
messageApi
创建一个
import React from "react";
import ReactDOM from "react-dom/client";
import { createBrowserRouter, RouterProvider, Outlet } from "react-router-dom";
import { message } from "antd";
import App from "./App";
import { AnotherPage } from "./AnotherPage";
const rootElement = document.getElementById("root")!;
const root = ReactDOM.createRoot(rootElement);
组件以使用
AppLayout
挂钩,并将 useMessage
提供给 UI,并将 contextHolder
提供给 messageApi
上下文。Outlet
渲染
const AppLayout = () => {
const [messageApi, contextHolder] = message.useMessage();
return (
<>
{contextHolder}
<Outlet context={{ messageApi }} />
</>
);
};
作为布局路线。
AppLayout
另一页
访问通过
const router = createBrowserRouter([
{
element: <AppLayout />,
children: [
{
path: "/",
element: <App />
},
{
path: "/create",
element: <AnotherPage />
}
]
}
]);
root.render(
<React.StrictMode>
<RouterProvider router={router} />
</React.StrictMode>
);
的上下文提供程序提供的
messageApi
。Outlet