【问题标题】:Detect if dynamically imported component has loaded in Nextjs检测 Nextjs 中是否加载了动态导入的组件
【发布时间】:2020-06-03 16:27:09
【问题描述】:

这是对我的场景的简化

import React, { useState } from 'react';
import dynamic from 'next/dynamic';

const DynamicImportedComponent = dynamic(() => import('Foo/baz'), {
  ssr: false,
  loading: () => <p>loading..</p>
});


const MyComponent: React.FC = () => {
  const [show, setShow] = useState(false)

  const variableComponent = <SomeStyledComponent styled={show}>value of show is {show.toString()}</SomeStyledComponent>
  return (
    <>
    {variableComponent}
    { show && <DynamicImportedComponent />}
    <button onClick={() => setShow(!show)}>toggle</button>
    </>
  )
}

有一个切换状态允许我显示或不显示动态加载的组件

我有一个始终呈现的组件,但根据切换可能会显示不同的样式。
当用户单击按钮时,状态设置为 true 并且组件被动态加载。同时,nextjs 渲染加载消息。到目前为止,一切顺利

但是,我希望 variableComponent 在加载 DynamicImportedComponent 时不可见。这是因为它有一些样式在加载器中看起来不太好。有没有办法检测组件是否已完成加载?加载组件后,我会像往常一样渲染variableComponent

我在想一些类似的东西

{(DynamicImportedComponent.loaded || !DynamicImportedComponent.isLoading) && variableComponent}

但这似乎并不存在。

我正在使用最新版本的 React 和 nextjs,以及 typescript

【问题讨论】:

标签: reactjs typescript next.js


【解决方案1】:

我也遇到了这个问题。目前还没有标准的方法来做这件事,但是 Nextjs 的维护者之一 suggested the following 在 Nextjs repo 的讨论中:

我们尽可能地镜像 React.lazy(同时还提供缺失的加载状态,因为 suspense 在服务器端不起作用)。 Suspense 可能会解决您的问题,因为它允许在一个项目(例如动态组件)暂停时为树的一部分显示微调器。但是,正如所述,Suspense 目前在服务器端不可用。

您可能会做的一件事是在上下文值中传递状态并在加载组件中传递 setState

我发现使用 React Context 的建议效果很好。

我的项目中的示例代码

const ToolbarTray: FunctionComponent<{}> = () => {
  const { isDialogOpen, closeDialog, openDialog } = useDialogState();

  const [ isDialogLoading, setDialogLoadingStatus ] = useState(false);

  return (
    <DynamicLoadingContext.Provider value={setDialogLoadingStatus}>
      <Button onClick={openDialog}>
        {isDialogLoading ? <CircularProgress /> : <EditIcon />}
      </Fab>

      {isDialogOpen && <EditPersonDialog onClose={closeDialog} />}
    </DynamicLoadingContext.Provider>
  );
};

const EditPersonDialog = dynamic(() => import('~/dialogs/edit-person-dialog'), {
  ssr: false,
  loading: () => {
    const setLoading = useContext(DynamicLoadingContext);

    useEffect(() => {
      setLoading(true);
      return () => setLoading(false);
    }, [setLoading]);

    return null;
  },
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-11-06
    • 2014-03-13
    • 1970-01-01
    • 1970-01-01
    • 2010-11-20
    • 2019-05-28
    • 2017-08-20
    • 2020-12-09
    相关资源
    最近更新 更多