反应悬念防止后备旋转器的闪烁



我想知道是否有一种好方法可以防止反应中回退的闪烁。 我正在使用反应路由器,问题是当组件挂起时,回退加载程序闪烁得非常快,这很烦人。 我在这里看到了答案 反应悬念/懒惰延迟?如下所示:

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

但我的问题是我有一个具有透明背景的覆盖加载微调器,并且在解决承诺之前,该组件实际上不会加载。 这会使页面在没有内容的半秒内挂起,实际上比微调器的闪烁更烦人。

所以我想问题是有没有人找到解决这个问题的好方法。 我真的很想在页面上添加类似 nprogress 的东西,但无法弄清楚我将如何使用 React.suspense 实现这一点。 我可能只需要回到使用 react loadable,但我真的不想当 react 具有开箱即用的基本相同功能时。

我最近遇到了同样的问题,我最终实现了用于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>

这不会延迟进口。(我也认为这不是最佳的( 让我知道这是否有帮助。

几周前我就遇到过这种情况,我希望悬念回退不渲染,我们都知道,如果惰性组件处于下载状态,则回退将显示

好吧,这是Suspense的正常行为,与此无关,相反,我们可以通过复制网页的部分背景设计来欺骗最终用户的观点

/* style.css */
.main-pane {
width: '100%',
height: '100%',
backgroundColor: #deb887
}
.header-pane {
width: '100%',
height: '100%',
position: 'absolute',
top: 0,
backgroundColor: #424242
}
//EmptyPage.js
import styles from './style.css';
const EmptyPage = () => {
return (
<div style={styles['main-pane']}>
<div style={styles['header-pane']}><div/>
</div>
)
}
//MainPage.js
import styles from './style.css';
const MainPage = () => {
return (
<div style={styles['main-pane']}>
<div style={styles['header-pane']}>HEADER CONTENT<div/>
BODY CONTENT
</div>
)
}
//App.js
const MainPage = lazy(() => import('./pages/MainPage'))
import EmptyPage from './pages/EmptyPage';
import styles from './style.css';
const App = () => {
return (
<Suspense fallback={<EmptyPage/>}>
<Router>
...
<MainPage/>
</Router>
</Suspense>
)
}

因此,目标只是复制部分背景设计,而不是闪烁或对我们最终用户的视角不友好的体验

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>
);
}

最新更新