反应中的全局屏幕加载器

Max*_*ain 10 frontend loader reactjs react-context use-context

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

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

  • 我想在主要组件中有全局加载器
  • 我想在应用程序中任意位置更新全局加载程序的状态
  • 我不想用 ScreenLoaders 污染我需要使用它的所有组件
  • 我想用钩子来实现它

那么有没有一种方法可以拥有 loader/loaderText 的全局状态,并在需要时使用上下文进行设置和重置?

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

Ben*_*ley 22

创建一个自定义钩子怎么样,它可以在任何提供全局上下文访问权限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;
}
Run Code Online (Sandbox Code Playgroud)
// App.jsx
import { LoadingProvider } from "./LoadingContext";

function App() {
    return (
        <LoadingProvider>
            <RestOfYourApp />
       </LoadingProvider>
    );
}
Run Code Online (Sandbox Code Playgroud)
// RestOfYourApp.js
import { useLoading } from "./LoadingContext";

function RestOfYourApp() {
    const { loading, setLoading } = useLoading();
    return (
      {loading && <LoadingComponent />}
      ...
    );
}
Run Code Online (Sandbox Code Playgroud)

  • 这个的 ts 变体? (2认同)
  • @kakabali,我的回答部分受到这篇文章的启发,其中有一些 TS 代码示例。不完全是这样,但它会为您指明正确的方向:https://kentcdodds.com/blog/how-to-use-react-context-effectly (2认同)

aja*_* 24 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;
Run Code Online (Sandbox Code Playgroud)

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;
Run Code Online (Sandbox Code Playgroud)

使用加载器钩子

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;
Run Code Online (Sandbox Code Playgroud)