Búsqueda de sitios web

javascript - ¿Por qué getPopupContainer no funciona correctamente en mi aplicación de react?


Estoy recibiendo esta advertencia:

Advertencia: [antd: Modal] La función estática no puede consumir el contexto como un tema dinámico. Por favor, utilice el componente 'App' en su lugar.

Entonces, el Modal.confirm() no se muestra correctamente porque se renderiza fuera del árbol de dependencias y no hereda los estilos.

Estoy usando react 18.2.0 y antd 5.4.6.

Aquí dejo el código

main.tsx

ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
  <Suspense fallback={<Loader />}>
     <ThemeWrapper>
         <Outlet />
      </ThemeCoWrapper>
  </Suspense>
);
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;

Ejemplo de función en la que utilizo Modal.confirm() dentro del envoltorio

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) {}
      },
    });
  };

Intenté usar document.getElemetById en lugar de useRef, pero no funcionó.

Respuesta #1

Porque la función estática en el modo concurrente de React 18 no será bien soportada. En la v5, Antd recomienda usar hooks para la sustitución estática (lea aquí). Por lo tanto, necesitará configurar su proyecto como lo indicaron aquí: https://ant.design/components/app#basic-usage

En tu caso, prueba:

  • Para el componente ThemeWrapper
  • import { App } from 'antd';
  • Y luego, envuelve el elemento <div> en <App></App> así:

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

Aquí, proporciono el ejemplo de codesandbox: https://codesandbox.io/s/text-and-link-component-antd-5-0-2-forked-9svf8v?file=/demo.tsx Recomiendan encapsular App en el nivel superior de la aplicación

Después de eso, necesitarás usar modal.confirm({}) de App.useApp(); en lugar del antiguo Modal.confirm() en tu función onLogout.

Artículos relacionados