javascript - 如何使用 NextJS 只使用一次动态导入
问题描述
我正在使用 NextJS 构建一个应用程序,我想在获取数据或加载某些页面时呈现加载图标。目前我必须将 Loading 组件插入到每个组件中,例如,如果您有 HomePage,则必须将 Loading 导入 HomePage,然后如果您有 ProductList,您还必须将 Loading 导入 ProductList,....虽然我认为是如果我可以只导入一次加载并申请整个应用程序,比如 React Lazy + 暂停,那就更好了。NextJS 的文档仅指导您如何处理每个组件。我已经尝试过 React Lazy + Suspend 但这并不奏效。您能否建议我是否应该进行动态导入。
感谢任何建议。
文件页面/_app.js:
function MyApp({ Component, pageProps }) {
return (
<>
<Head>
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossOrigin="anonymous" />
<title>Hello, world!</title>
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossOrigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossOrigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossOrigin="anonymous"></script>
</Head>
<Header />
<main className="pt-3">
<Component {...pageProps} />
</main>
<Footer />
</>
)
}
export default MyApp;
解决方案
如果要在获取数据时添加全局加载,可以尝试loading state
将 实现它的方法可能是这样的。
_app.js
import { useSelector, useDispatch } from 'redux';
function MyApp({ Component, pageProps }) {
const isLoading = useSelector((state) => state.isLoading);
const dispatch = useDispatch();
useEffect(() => {
Router.events.on('routeChangeComplete', () => {
// when route has been changed complete, dispatch an action which would make the loading state to be true
dispatch({ type: 'CHANGE_LOADING_STATE', payload: true });
}, [])
return (
<WithLoadingComponent>
<Component {...pageProps} />
</WithLoadingComponent>
);
}
WithLoadingComponent
import { useSelector } from 'redux';
import Router from 'next/router';
function WithLoadingComponent(props) {
const isLoading = useSelector((state) => state.isLoading);
return (
<>
{isLoading && <GlobalLoadingComponent />}
<div className={isLoading ? 'loading' : ''}>{props.children}</div>
<style jsx>{`
.loading {
visibility: hidden;
}
`}</style>
</>
);
}
页面组件
import { useDispatch } from 'redux';
function PageComponent(props) {
const dispatch = useDispatch();
useEffect(() => {
// Call api to fetch data
(async () => {
try {
const data = await fetch('https://www.xxyyzz.com/api');
console.log(data);
dispatch({ type: 'CHANGE_LOADING_STATE', payload: false });
} catch (error) {
dispatch({ type: 'CHANGE_LOADING_STATE', payload: false });
}
})();
}, []);
return <div>Page component</div>;
}
但是,我认为在每个页面中显示全局加载状态似乎并不合理。因为大多数时候,它只是调用api,然后在屏幕上渲染一部分(而不是整个屏幕)。更好的方法是仅在屏幕的一小部分显示加载图标,稍后将显示来自 api 的响应数据。
推荐阅读
- android - findViewById 不适用于使用 View.generateViewId 创建的 id
- flutter - FAILURE:构建失败并出现异常(共享首选项和 gradle 包装器属性)
- html - 如何阻止两个元素相互影响?
- hive - Hive QL IN 对性能不利吗?
- android - Android Keystore 多用途密钥生成
- xsd - 通过 xsd 约束本地化枚举值
- android - 如何在另一台计算机上签署 Android 应用程序
- python - 将各种长度的 Python 字典解包到 sql 查询中
- python - 使用python将文件复制到另一个文件夹
- c++ - 垫到矢量