react 全局loading
时间: 2023-06-23 12:49:41 浏览: 46
要在 React 应用程序中实现全局加载指示器(loading),可以使用 React Context 和 React Portal。
首先,创建一个 React Context,用于在应用程序中共享加载状态。例如:
```
import React, { createContext, useState, useContext } from 'react';
const LoadingContext = createContext();
export const LoadingProvider = ({ children }) => {
const [loading, setLoading] = useState(false);
return (
<LoadingContext.Provider value={[loading, setLoading]}>
{children}
</LoadingContext.Provider>
);
};
export const useLoading = () => useContext(LoadingContext);
```
然后,在应用程序的根组件中使用 `LoadingProvider`,并在需要显示加载指示器的组件中使用 `useLoading` Hook。
```
import React from 'react';
import { LoadingProvider, useLoading } from './LoadingContext';
import LoadingIndicator from './LoadingIndicator';
const App = () => {
return (
<LoadingProvider>
<div className="App">
<Component1 />
<Component2 />
</div>
<LoadingIndicator />
</LoadingProvider>
);
};
const Component1 = () => {
const [loading, setLoading] = useLoading();
const handleClick = async () => {
setLoading(true);
// Some async operation
await new Promise(resolve => setTimeout(resolve, 2000));
setLoading(false);
};
return (
<div>
<button onClick={handleClick}>Load Component 1</button>
{loading && <div>Loading Component 1...</div>}
</div>
);
};
const Component2 = () => {
const [loading, setLoading] = useLoading();
const handleClick = async () => {
setLoading(true);
// Some async operation
await new Promise(resolve => setTimeout(resolve, 2000));
setLoading(false);
};
return (
<div>
<button onClick={handleClick}>Load Component 2</button>
{loading && <div>Loading Component 2...</div>}
</div>
);
};
```
在上面的示例中,`LoadingIndicator` 组件是一个 React Portal,用于在应用程序的顶层渲染加载指示器。例如:
```
import React, { useEffect } from 'react';
import ReactDOM from 'react-dom';
import { useLoading } from './LoadingContext';
const LoadingIndicator = () => {
const [loading] = useLoading();
useEffect(() => {
const root = document.createElement('div');
document.body.appendChild(root);
return () => {
document.body.removeChild(root);
};
}, []);
return loading
? ReactDOM.createPortal(
<div className="loading-indicator">Loading...</div>,
document.body
)
: null;
};
export default LoadingIndicator;
```
这是一个简单的实现,你可以根据自己的需求进行扩展和优化。