为什么 getPopupContainer 在我的 React 应用程序中无法正常工作?

jes*_*rlm 2 javascript typescript reactjs antd

我收到此警告:

警告:[antd: Modal] 静态函数不能像动态主题一样消耗上下文。请改用“应用程序”组件。

然后,Modal.confirm()无法正确显示,因为它在依赖关系树之外呈现并且不继承样式。

我正在使用 React 18.2.0 和 antd 5.4.6。

这里我留下代码

主.tsx

ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
  <Suspense fallback={<Loader />}>
     <ThemeWrapper>
         <Outlet />
      </ThemeCoWrapper>
  </Suspense>
);
Run Code Online (Sandbox Code Playgroud)
const ThemeWrapper: React.FC<ThemeProps> = ({ children }) => {
  const [theme, setTheme] = useState<any>(defaultTheme);

  const modalContainerRef = useRef<HTMLDivElement>(null);

  return (
    <ConfigProvider
      theme={theme}
      getPopupContainer={() => modalContainerRef.current as HTMLElement}
    >
      <div ref={modalContainerRef}>{children}</div>
    </ConfigProvider>
  );
};

export default ThemeWrapper;
Run Code Online (Sandbox Code Playgroud)

我在包装器内使用 Modal.confirm() 的函数示例

const onLogout = () => {
    Modal.confirm({
      title: (
        <b>
          {intl.formatMessage({
            id: 'labelCloseSession',
          })}
        </b>
      ),
      content: intl.formatMessage({
        id: 'labelLogoutConfirm',
      }),
      centered: true,
      onOk: async () => {
        try {
          await loginService.logout();
          removeUserSession();
          globalContext.dispatch({
            type: GlobalStateActionType.LOGOUT,
          });
          navigate('/login');
        } catch (error) {}
      },
    });
  };
Run Code Online (Sandbox Code Playgroud)

我尝试使用document.getElemetById代替,useRef但没有成功。

Kha*_*i F 5

因为React 18并发模式下的静态函数不会很好支持。在 v5 中,Antd 建议使用钩子进行静态替换(请阅读此处)。因此,您需要像他们在这里所说的那样设置您的项目: https: //ant.design/components/app#basic-usage

对于您的情况,请尝试:

  • 对于ThemeWrapper组件
  • import { App } from 'antd';
  • 然后,将<div>元素包装起来,<App></App>如下所示:
    <ConfigProvider
         theme={theme}
         getPopupContainer={() => modalContainerRef.current as HTMLElement}
    >
         <App>
             <div ref={modalContainerRef}>{children}</div>
         </App>
    </ConfigProvider>
    
    Run Code Online (Sandbox Code Playgroud)

在这里,我提供了codesandbox示例:https://codesandbox.io/s/text-and-link-component-antd-5-0-2-forked-9svf8v ?file=/demo.tsx 他们建议将App封装在应用程序的顶层

之后,您将需要在函数中使用modal.confirm({})fromApp.useApp();而不是 old 。Modal.confirm()onLogout