我想知道是否有一个很好的方法来防止反应中的后备状态闪烁。我使用的是React Router,问题是当组件暂停时,后备加载程序会快速闪烁,这很烦人。我在这里React suspense/lazy delay?看到了如下答案:
const Home = lazy(() => {
return Promise.all([
import('./components/Home'),
new Promise(resolve => setTimeout(resolve, 500))
]).then(([moduleExports]) => moduleExports);
});
但是我的问题是我有一个带有透明背景的叠加加载微调器,并且该组件直到承诺兑现后才真正加载。这会使页面在没有内容的情况下暂停半秒钟,实际上比旋转器的闪烁更令人讨厌。
所以我想问题是有人找到解决此问题的好方法了。我真的很想在页面上添加类似nprogress的内容,但无法弄清楚如何使用React.suspense实现它。我可能只需要回到使用react loadable上来,但是我真的不想在react具有基本相同的功能时使用。
答案 0 :(得分:2)
我最近遇到了同样的问题,我最终实现了一个组件,用于悬念的 fallback
。
想法很简单,就是在一定时间内不显示任何内容,然后显示加载程序。因此,假设在 300 毫秒内不会显示任何内容,延迟后它应该显示(在本例中)ContentLoader
或您喜欢的任何内容。
在打字稿中为 lazy-loader.ts
import { FC, useEffect, useState } from 'react';
import ContentLoader from './content-loader'; // or any spinner component
export interface LazyLoaderProps {
delay?: number;
}
const LazyLoader: FC<LazyLoaderProps> = ({
delay = 250,
...props
}) => {
const [show, setShow] = useState(false);
useEffect(() => {
const timeout = setTimeout(() => {
setShow(true);
}, delay);
return () => {
clearTimeout(timeout);
};
}, [delay]);
return show ? <ContentLoader {...props} /> : null;
};
export { LazyLoader as default };
然后像这样使用
import LazyLoader from "./lazy-loader"
// ...
<Suspense fallback={<LazyLoader delay={300} />}>...</Suspense>
这不会延迟导入。 (我也认为这不是最佳的) 如果这有帮助,请告诉我。
答案 1 :(得分:-1)
import React, { Suspense, lazy } from "react";
const Home = lazy(() => {
return Promise.all([
import("./home"),
new Promise(resolve => setTimeout(resolve, 300))
]).then(([moduleExports]) => moduleExports);
});
function FullSpinner() {
return (
{/** full spinner jsx goes here */}
<div className="full-spinner">
<p>loading....</p>
</div>
)
}
function App() {
return (
<div className="App">
<h1>app component</h1>
<Suspense fallback={<FullSpinner />}>
<Home />
</Suspense>
</div>
);
}
编辑:
import React, { Suspense, lazy, useState, useEffect } from "react";
const Home = lazy(() => {
return Promise.all([
import("./home"),
new Promise(resolve => setTimeout(resolve, 500))
]).then(([moduleExports]) => moduleExports);
});
function FullSpinner() {
return (
<div className="full-spinner">
<p>loading....</p>
</div>
);
}
const LazyLoading = ({ delay, loader: Loader, children }) => {
const [ready, setReady] = useState(false);
useEffect(() => {
setTimeout(() => setReady(true), delay);
}, [delay]);
return ready ? (
<Suspense fallback={<Loader />}>{children}</Suspense>
) : (
<Loader />
);
};
function App() {
return (
<div className="App">
<h1>app component</h1>
<LazyLoading delay={2000} loader={FullSpinner}>
<Home />
</LazyLoading>
</div>
);
}