【问题标题】:How to use dynamic import one time only with NextJS如何仅通过 NextJS 使用一次动态导入
【发布时间】:2021-02-01 08:59:26
【问题描述】:

我正在使用 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;

【问题讨论】:

    标签: javascript reactjs react-redux next.js router


    【解决方案1】:

    如果您想在获取数据时添加全局加载,可以尝试将loading state 放在redux 中。实现它的方法可能是这样的。

    _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 的响应数据。

    【讨论】:

    • 非常感谢 bcjohn,Redux 需要包装应用程序内部 否则会显示错误“找不到 react-redux 上下文值”,我应该把这个放在哪里?
    • 如果要将redux集成到next.js中,最好使用next-redux-wrapper
    • 如果回答对你有帮助,可以采纳或投上一票,谢谢。
    猜你喜欢
    • 2019-05-28
    • 2017-04-12
    • 1970-01-01
    • 2021-12-28
    • 2020-06-12
    • 1970-01-01
    • 1970-01-01
    • 2021-12-26
    • 1970-01-01
    相关资源
    最近更新 更多