0

我正在使用打字稿和可加载组件(用于 SSR 实现)开发 React 应用程序,并尝试为可加载组件实现占位符,以减少初始加载时页面的移动(页面首先加载,几秒钟后加载可加载组件出现,将事情向下移动)。我曾尝试使用可加载组件的后备属性,但这会导致更多的变化(后备需要一点时间出现,消失并折叠它所在的空间,然后出现可加载组件)。

我当时正在考虑使用钩子来加载这个组件,但是我一个接一个地出错。我想知道是否可以在 useEffect 中使用可加载组件?另外,如何使用从 loadable(() => import('/someModule')) 返回的模块?只是正常使用它是行不通的。

我通常可以像这样加载可加载组件:


const Module = loadable(() => import('./SomeModule'));

<Module /> // ---> usage

并尝试使用以下功能在加载时在其位置放置一个占位符:

const useLazyContainer = (): any => {
  const Fallback = () => <div style={{ minHeight: '200px' }}>Loading</div>;
  const [component, setComponent] = useState<any>(Fallback);

  useEffect(() => {
    (function loadComponent() {
      const Module = loadable(() => {
        import('./Module');
      });

      setComponent(Module);
    })();
  }, []);

  return component;
};

然后使用它:

const SomeComponent = useLazyContainer();

return (
     <div>
       {SomeComponent}
    </div>. 
)

但是,我得到错误:

Uncaught Error: Objects are not valid as a React child (found: object with keys {$$typeof, render, preload, load}). If you meant to render a collection of children, use an array instead.

似乎模块的类型是 {$$typeof: Symbol(react.forward_ref), render: ƒ, preload: ƒ, load: ƒ} 但 React 拒绝渲染它。

我也尝试调用 SomeComponent 作为

有没有人对如何使它工作或什至可能有任何想法?

4

1 回答 1

0

最后我发现如果我想重新创建回退逻辑,我可以这样做:

const MyComponent = loadable(() => import('stuff'));

const MyApp = () => {
 const [loaded, setLoaded] = useState(false);
 useEffect(() => MyComponent.preload().then(() => setLoaded(true)), []);

 return loaded ? <MyComponent /> : <div>loading...</div>
}

但这对页面移位没有帮助。实际上只是将可加载组件包装在具有最小高度的包装器 div 中。

<div style={{minHeight: '200px'}}>
    <MyLoadableComponent>
</div>
于 2021-03-02T11:25:48.023 回答