How to make a global Component ( Loader, Alert, Toast, etc ) in React Native

Here I'm going to show you how you can make a global component such as Custom Loader, Custom Alert dialog, Custom Toast, etc.

In React Native for a custom alert and custom loader, we generally make a component. Sometimes implementing component like Loader require importing and managing state for it on every screen where we want to use it.

So isn't cool to show and hide loader just like

global.props.showLoader()

global.props.hideLoader()

I'm just showing you how to make a global loader component only in a few steps.

Let's follow the steps

As a programmer our count starts from zero right?? 😊

Steps 0 - Make a custom Loader component

I'm using lottie-react-native for animation in my custom loader component.


import React, { Component } from "react"
import {
  View,Dimensions,
  Modal,
  StyleSheet,
  TouchableOpacity
  } from "react-native"
import Lottie from 'lottie-react-native';
const { width, height } = Dimensions.get("window")
export default class extends Component {
  render() {
    return (
      <Modal
          transparent={true}
          animationType='fade'
          visible={this.props.loading}
        >
      <TouchableOpacity 
      activeOpacity={1} 
      style={styles.container}>
       {/* Your own Custom component view*/}
        <View style={styles.content}>
          <Lottie
           autoPlay
           loop
           source={require('../../assets/anim/loader.json')}
          />
        </View>
      </TouchableOpacity>
      </Modal>
    )
  }
}
const styles = StyleSheet.create({
  container: {
    height,width,
    position: "absolute",
    justifyContent: "center",
    backgroundColor: "rgba(0,0,0,0.5)",
    top: 0,left: 0,bottom: 0,right: 0
  },
  content: {
    width:60,height: 60,
    borderRadius: 6,
    justifyContent: "space-around" ,
    alignItems: "center",
    alignSelf: "center",
  }
})

Step 1 - Use AppContext API to wrap Loader component Read more about AppContext

import React, { Component } from "react"
// custom loader component
import AppLoader from './AppLoader'
const AppContext = React.createContext({})
export const AppConsumer = AppContext.Consumer
export class AppProvider extends Component {
  constructor(props) {
    super(props)
    this.state = {
      loading:false,
    }
  }
  showProgress = () =>this.setState({loading:true})
  hideProgress = () =>this.setState({loading:false})
  render() {
    const {loading}=this.state
    const funcs = { 
      showLoader:this.showProgress,
      hideLoader:this.hideProgress 
    }
    return (
      <AppContext.Provider
        value={{...funcs}}>
        {this.props.children}
        {/* other global component  */}
       <AppLoader loading={loading} />
      </AppContext.Provider>
    )
  }
}

Step 2 - Wrapping App root component & assigning functions to global.props

import { AppRegistry } from "react-native"
import React, { Component } from "react"
import { name as appName } from "./app.json"
import Route from "./src/navigation"
class AppRoot extends Component {
  constructor(props){
    super(props)
  }
  render() {
    return (
       <AppProvider {...this.props}>
        <AppConsumer>{funcs => { 
            global.props = {...funcs}
            return <Route {...funcs} />
           }}  
        </AppConsumer>
        </AppProvider>

    )
  }
}
AppRegistry.registerComponent(appName, () => AppRoot)

Exposing props to a global variable is not a standard way. This is just for ease, you can follow the AppContext API standard way to pass these props to children components.

Step 3 - Use case of global component

wallpaper.png

** This is my first post ever. I hope this is useful

Comments (3)

Add a comment
Mohd Shad Mirza's photo

Useful stuff, thanks.

Serdar Sanri's photo

I am not confident enough to think it is a good idea to expose it globally. If you are already using context, that smells fishy to me.

Satish Rajbhar's photo

React Native Developer

Yes, you are right. Now added the note in step 2. Thanks