【问题标题】:Global screen loader in react反应中的全局屏幕加载器
【发布时间】:2021-06-10 00:57:12
【问题描述】:

我正在寻找在 react 中使用全局屏幕加载器的解决方案。

我对反应上下文不太熟悉,但我想知道这是否可以帮助我。 基本上我正在介绍一个屏幕加载器,我在想也许最好的方法是在主要组件的某个地方有一个全局加载器。所以得出结论:

  • 我想在主组件中有全局加载器
  • 我想在应用中的任何地方更新全局加载器的状态
  • 我不想用 ScreenLoaders 污染我需要使用它的所有组件
  • 我想为它使用钩子

那么有没有办法获得 loader/loaderText 的全局状态,并在需要时使用上下文进行设置和重置?

如果有一种简单的方法可以做到这一点,那么您认为使用这种解决方案可能有什么缺点吗?也许这有点过头了。

【问题讨论】:

    标签: reactjs frontend loader react-context use-context


    【解决方案1】:

    如何创建一个自定义钩子useLoading,它可以用于任何可以从全局上下文访问loadingsetLoading 的组件?

    // LoadingContext.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;
    }
    
    // App.jsx
    import { LoadingProvider } from "./LoadingContext";
    
    function App() {
        return (
            <LoadingProvider>
                <RestOfYourApp />
           </LoadingProvider>
        );
    }
    
    // RestOfYourApp.js
    import { useLoading } from "./LoadingContext";
    
    function RestOfYourApp() {
        const { loading, setLoading } = useLoading();
        // ...
    }
    

    【讨论】:

    【解决方案2】:

    useLoader.js(钩子)

    import React, { useState } from "react";
    import Loader from "./loader";
    const useLoader = () => {
      const [loading, setLoading] = useState(false);
      return [
        loading ? <Loader /> : null,
        () => setLoading(true),
        () => setLoading(false),
      ];
    };
    export default useLoader;
    

    loader.js(加载器组件)

    import React from "react";
    import styled from "styled-components";
    import spinner from "./loader.gif"; // create gif from https://loading.io
    import Color from "../../Constant/Color";
    
    const Loader = () => {
      return (
        <LoaderContainer>
          <LoaderImg src={spinner} />
        </LoaderContainer>
      );
    };
    
    
    const LoaderContainer = styled.div`
      position: absolute;
      top: 0;
      bottom: 0;
      width: 100%;
      height: 100vh;
      display: flex;
      justify-content: center;
      align-items: center;
      position: fixed;
      background: ${Color.greyBg};
      z-index: 100;
    `;
    const LoaderImg = styled.img`
      position: absolute;
    `;
    
    export default Loader;
    

    使用 Loader 钩子

    import useLoader from "../../../hooks/loader/useLoader"; /// import loader hook
    
    const App = (props) => {
    const [loader, showLoader, hideLoader] = useLoader(); //initialize useLoader hook
    
    
    useEffect(() => {
        showLoader(); /// loading starts
       
        Axios.post("url")
          .then((res) => {
            hideLoader(); // loading stops
          })
          .catch((error) => {
            hideLoader();// loading stops
          });
      }, []);
    
    return (
    <>
    {loader} /// important 
    
    //// add your elements /////
    </>
    )
    }
    export default App;
    

    【讨论】:

    • 但在这种情况下,我总是必须将{loader} 应用于我需要的每个组件,对吗?这就是我想要避免的。要在例如 App 组件中只有一个全局加载器 html 元素并依赖于其他组件中的某些获取 - 将加载状态设置为 true/false
    • 为此你必须使用 redux。在你的应用程序的顶层调用这个 useLoader 钩子,例如你设置路由的地方。并渲染 {loder}。创建一个布尔值的redux状态,在你使用路由的地方添加使用效果钩子,只要你想showloader()将redux状态的值更改为true并将hideloader设置为false。如果你不想使用 redux,请使用 ,useContext hook。
    猜你喜欢
    • 2023-02-04
    • 1970-01-01
    • 2021-07-07
    • 1970-01-01
    • 2021-03-18
    • 1970-01-01
    • 1970-01-01
    • 2022-08-13
    • 2018-07-21
    相关资源
    最近更新 更多