reactjs 从不同页面调用时,在React.js中全局显示加载屏幕

wwwo4jvm  于 2023-02-15  发布在  React
关注(0)|答案(1)|浏览(127)

当从API获取数据时,我试图实现一个全局加载屏幕,我读取了this answer并试图实现类似的东西。

    • 正在加载. provider. js**
import { createContext, useContext, useState } from "react";

const LoadingContext = createContext({
  loading: false,
  setLoading: null
});

export function LoadingProvider({ children }) {
  const [loading, setLoading] = useState(false);
  const value = { loading, setLoading };
  return (
    <LoadingContext.Provider value={value}>{children}</LoadingContext.Provider>
  );
};

export function useLoading() {
  const context = useContext(LoadingContext);
  if (!context) {
    throw new Error('useLoading must be used within LoadingProvider');
  }

  return context;
};
    • 应用程序. js**

加载屏幕已添加到此屏幕:

import Layout from '@/components/Layout/Layout';
import { LoadingProvider, useLoading } from '@/Providers/loading.provider';
import LoadingScreen from "./LoadingScreen";

export default function App({ Component, pageProps }) {
  const { loading } = useLoading();

  return (
    <>
      <CssBaseline />
      <LoadingProvider>
        <AppStateProvider>
          { loading && <LoadingScreen loading={true} bgColor='#fff' spinnerColor={'#00A1FF'} textColor='#676767'></LoadingScreen> }
          <Layout>
            <Component {...pageProps} />
          </Layout>
        </AppStateProvider>
      </LoadingProvider>
    </>
  );
};

我有一个布局组件,其中包含SideMenu、顶部AppBarmain组件:

    • 布局. js**
export default function Layout({ children }) {
  return (
    <Fragment>
      <Box sx={{ display: 'flex' }}>
        <AppBar />
        <SideMenu />
        <Box component="main" sx={mainContentWrapper}>
          <div className={styles.container}>
            <main className={styles.main}>
              {children}
            </main>
          </div>
        </Box>
      </Box>
    </Fragment>
  );
}

现在我尝试从一个页面([identifier]. js)显示它:

import { useLoading } from "@/Providers/loading.provider";

export default function MainPage({ response }) {
  const { loading, setLoading } = useLoading();
  const btnClickedAll = async (data) => {
    setLoading(true);
  };

  return (
    <Fragment>
      <Button sx={{ ml: 2 }} key={'btnAll'} onClick={btnClickedAll} variant="contained">All</Button>,
    </Fragment>
  );
}

使用setLoading(true)设置loading后,正在调用loading,但app.js内部的状态没有更改。有人能帮助我并指出正确的方向吗?
编辑:根据@DustInComp建议对代码进行了一些更改。

x759pob2

x759pob21#

原因是您的LoadingProvider位于app. js内部,只有LoadingProvider内部的子级才能访问加载状态。

    • 备选案文1**

您可以做的是将整个app.js移动到父级的LoadingProvider中,可能是index.js
索引. js中

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import store from './store';
import './index.css';
import './bootstrap.min.css';
import App from './App';

ReactDOM.render(
    <LoadingProvider>
        <App />
    </LoadingProvider>,
    document.getElementById('root')
);
    • 或**
    • 备选案文2**

您可以为app.js中的所有内容创建一个子组件。
Child. js中(您可以随意命名)

const Child = ({ Component, pageProps }) => {
    const { loading } = useLoading();
     <AppStateProvider>
          { loading && <LoadingScreen loading={true} bgColor='#fff' spinnerColor={'#00A1FF'} textColor='#676767'></LoadingScreen> }
          <Layout>
            <Component {...pageProps} />
          </Layout>
     </AppStateProvider>
};

export default Child;

app. js

export default function App({ Component, pageProps }) {
  return (
    <>
      <CssBaseline />
      <LoadingProvider>
        <Child Component={Component} pageProps={pageProps}/>
      </LoadingProvider>
    </>
  );
};
    • 或**
    • 备选案文3**

您可以创建加载程序的加载程序组件并将其导入app.js
Loader. js中(您可以随意命名)

const Loader = () => {
    const { loading } = useLoading();
    return loading && <LoadingScreen loading={true} bgColor='#fff' spinnerColor={'#00A1FF'} textColor='#676767'></LoadingScreen>;        
};

export default Loader;

app.js

export default function App({ Component, pageProps }) {
  return (
    <>
      <CssBaseline />
      <LoadingProvider>
        <AppStateProvider>
          <Loader />
          <Layout>
            <Component {...pageProps} />
          </Layout>
        </AppStateProvider>
      </LoadingProvider>
    </>
  );
};

相关问题