React suspense/lazy delay? React suspense/lazy delay? reactjs reactjs

React suspense/lazy delay?


lazy function is supposed to return a promise of { default: ... } object which is returned by import() of a module with default export. setTimeout doesn't return a promise and cannot be used like that. While arbitrary promise can:

const Home = lazy(() => {  return new Promise(resolve => {    setTimeout(() => resolve(import("./home")), 300);  });});

If an objective is to provide minimum delay, this isn't a good choice because this will result in additional delay.

A minimum delay would be:

const Home = lazy(() => {  return Promise.all([    import("./home"),    new Promise(resolve => setTimeout(resolve, 300))  ])  .then(([moduleExports]) => moduleExports);});


As mentioned by loopmode, component fallback should have a timeout.

import React, { useState, useEffect } from 'react'const DelayedFallback = () => {  const [show, setShow] = useState(false)  useEffect(() => {    let timeout = setTimeout(() => setShow(true), 300)    return () => {      clearTimeout(timeout)    }  }, [])  return (    <>      {show && <h3>Loading ...</h3>}    </>  )}export default DelayedFallback

Then just import that component and use it as fallback.

<Suspense fallback={<DelayedFallback />}>       <LazyComponent  /></Suspense>


Fallback component animations with Suspense and lazy

@Akrom Sprinter has a good solution in case of fast load times, as it hides the fallback spinner and avoids overall delay. Here is an extension for more complex animations requested by OP:

1. Simple variant: fade-in + delayed display