Some more easy way
Create Provider with context and hook within single file
import React, {useRef} from 'react';
import {Loader} from '@components';
const LoaderContext = React.createContext();
export function LoaderProvider({children}) {
const ref = useRef();
const startLoader = () => ref.current.start();
const stopLoader = () => ref.current.stop();
const value = React.useMemo(
() => ({ref, startLoader, stopLoader}),
[ref, startLoader, stopLoader]
);
return (
<LoaderContext.Provider value={value}>
{children}
<Loader ref={ref} />
</LoaderContext.Provider>
);
}
export const useLoader = () => React.useContext(LoaderContext);
in App.js add provider
import {StoreProvider} from 'easy-peasy';
import React from 'react';
import {StatusBar, View} from 'react-native';
import colors from './src/assets/colors';
import Navigation from './src/navigation/routes';
import {LoaderProvider} from './src/providers/LoaderProvider';
import {ToastProvider} from './src/providers/ToastProvider';
import store from './src/redux/store';
import globalStyles from './src/styles/index';
import('./src/helpers/ReactotronConfig');
function App() {
return (
<StoreProvider store={store}>
<StatusBar
barStyle="light-content"
backgroundColor={colors.backgroundDark}
translucent={false}
/>
<ToastProvider>
<LoaderProvider>
<View style={globalStyles.flex}>
<Navigation />
</View>
</LoaderProvider>
</ToastProvider>
</StoreProvider>
);
}
export default App;
And in any screen use like this way
import {useLoader} from '../../providers/LoaderProvider';
const {startLoader, stopLoader} = useLoader();
Loader.js
import React, {forwardRef, useImperativeHandle, useState} from 'react';
import {ActivityIndicator, StyleSheet, View} from 'react-native';
import {wp} from '../../styles/responsive';
function Loader(props, ref) {
const [loading, setLoading] = useState(0);
useImperativeHandle(
ref,
() => ({
start: () => {
const loadingCount = loading + 1;
setLoading(loadingCount);
},
stop: () => {
const loadingCount = loading > 0 ? loading - 1 : 0;
setLoading(loadingCount);
},
isLoading: () => loading >= 1,
}),
[],
);
if (!loading) {
return null;
}
return (
<View style={styles.container}>
<ActivityIndicator size={'small'} color={'#f0f'} />
</View>
);
}
const styles = StyleSheet.create({
container: {
...StyleSheet.absoluteFill,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: '#11111150',
zIndex: 999,
elevation: 999,
},
});
export default forwardRef(Loader);