Simplifies loading state sharing.
npm install shared-loading-indicatorSimplifies loading state sharing in React.
!Demo
You can play with it yourself here filipchalupa.cz/shared-loading-indicator.
``bash`
npm install shared-loading-indicator
Wrap all by one .
`jsx
import { SharedLoadingIndicatorContextProvider } from 'shared-loading-indicator'
export const App => () => {
return (
My app
)
}
`
Place SharedProgressLoadingIndicator inside SharedLoadingIndicatorContextProvider to use prestyled loading indicator. See demo to change color or placement.
`jsx
import { SharedLoadingIndicatorContextProvider, SharedProgressLoadingIndicator } from 'shared-loading-indicator'
export const App => () => {
return (
My app
)
}
`
You can change the color by setting a CSS custom property on its parent named --ProgressLoadingIndicator-color. Or you can build your own indicator using useSharedLoading hook.
#### CSS example
`css`
:root {
--ProgressLoadingIndicator-color: #ff00ff;
}
Hook useSharedLoading returns true if some component is in loading state. Use this information to show your own loading indicator (spinner, progress bar, …).
`jsx
import { useSharedLoading } from 'shared-loading-indicator'
export const LoadingIndicator => () => {
const isLoading = useSharedLoading()
if (!isLoading) {
return null
}
return (
#### Options
You can optionally configure
startDelay and minimalDuration in milliseconds.`js
const isLoading = useSharedLoading({
startDelay: 300, // isLoading won't be true if all local loads get finished under 300 milliseconds
minimalDuration: 1000, // isLoading will be true for at least 1000 milliseconds
})
`$3
Place
inside to signalize something is loading.`jsx
import { SharedLoadingIndicatorContextProvider, Loading } from 'shared-loading-indicator'export const App => () => {
const somethingIsLoading = true // Hook this to a state
return (
{somethingIsLoading && }
My app
)
}
`$3
Hook
useLocalLoading works similarly to useState. It returns array with boolean state indicating that component is loading and set function.`jsx
import { useLocalLoading } from 'shared-loading-indicator'export const MyComponent => () => {
const [isLoading, setIsLoading] = useLocalLoading()
return (
Is loading: {isLoading ? 'yes' : 'no'}
)
}
``jsx
import { useLocalLoading } from 'shared-loading-indicator'
import { useEffect } from 'react'export const LazyComponent => () => {
const [isLoading, setIsLoading] = useLocalLoading()
const [data, setData] = useState(null)
useEffect(() => {
setIsLoading(true)
fetch('https://example.com')
.then(response => response.json())
.then(receivedData => {
setData(receivedData)
})
.finally(() => {
setIsLoading(false)
})
}, [])
return (
Is loading: {isLoading ? 'yes' : 'no'}
{JSON.stringify(data, null, 2)}
)
}
`$3
Mirrors first argument to
useLocalMirror under the hood.`jsx
import { useMirrorLoading } from 'shared-loading-indicator'
import { useQuery } from '@tanstack/react-query'const Mirror = () => {
const query = useQuery([], getData)
useMirrorLoading(query.isLoading)
return
{query.data}
}
`$3
To capture loading state using Suspense wrap your content by
.`jsx
import { LoadingSuspense } from 'shared-loading-indicator'const LazyWithSuspense = () => {
return (
)
}
`React Native
All components and hooks work in React Native as well, except for UI components
and , which are web only. They may be reimplemented for React Native too. See the source code to get inspired how.Tips
- Page navigation in Next.js
- Custom indicator with Material UI
Development
- Install dependencies:
npm ci
- Run: npm run dev`