简体   繁体   English

如何在反应中有条件地延迟加载动态导入?

[英]How to conditionally lazy load dynamic imports in react?

I would like to trigger a dynamic import of a react component only after an image is loaded to prioritise first paint.我想仅在加载图像以优先考虑第一次绘制后触发反应组件的动态导入。 The problem is, it's a context provider component and having some trouble as a result.问题是,它是一个上下文提供程序组件,因此会遇到一些麻烦。

So I have a dynamic import here in the file auth.js :所以我在auth.js文件中有一个动态导入:

   const AuthContextPreloader = hasWindow
   ? lazy(() => import("./AuthContextPreloader"))
   : null;

And I have an image here in a separate component:我在一个单独的组件中有一个图像:

   <img
      ref={() => hasWindow && imageLoaded()}
      className={styles.optionsImageImg}
      alt={"nav"}
      src={didLoad && thumb.jpg}
      type="image/jpeg"
    />

And once loaded I a send state up the component tree to hand down to AuthContextPreloader加载后,我将 state 向上发送到组件树以传递给AuthContextPreloader

    const imageLoaded = () => {
      setheroLoaded(true);
     };

Some pseudo-code to try and achieve this in auth.js :一些伪代码尝试在auth.js中实现这一点:

  useEffect(() => {
    props.heroLoaded && **trigger the lazyload**;
  }, [props.heroLoaded]);

But totally unsure how to implement that.但完全不确定如何实施。 Thank you.谢谢你。

You should not be concerned about when your component will be loaded.您不应该担心何时加载您的组件。 Your concern should be when to render it.你应该关心什么时候渲染它。 Something like that:像这样的东西:

const AuthContextPreloader = hasWindow
  ? lazy(() => import("./AuthContextPreloader"))
  : null;

function ComponentWhereWouldBeRenderedAuthContextPreloader(props) {
  return props.heroLoaded ? <Suspense><AuthContextPreloader /> </Suspense> : null;
}

This way you will not consider yourself with internals, but will render your current application state.这样您就不会认为自己具有内部结构,而是会呈现您当前的应用程序 state。

Edit编辑

From the comments it is clear that your concern not the component itslef, but it's large dependency.从评论中可以清楚地看出,您关心的不是组件本身,而是很大的依赖关系。

In this case you can do something like this:在这种情况下,您可以执行以下操作:


function ComponentWhereWouldBeRenderedAuthContextPreloader(props) {
  return props.heroLoaded ? <AuthContextPreloader /> : null;
}

function AuthContextPreloader(props) {
  let [dependencyState, setDependencyState] = useState("not_loaded");
  useEffect(function () {
    import("large-dependency")
      .then(function (module) {
        // return either default, or named exports that you need, or skip this step
        return module.default;
      })
      .then(function (dep) {
        // do something with dependency and then change state
        setDependencyState("loaded");
      });
  }, []);
  if (depenencyState === "not_loaded") return null;
  return ...;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM