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

Evgeniy Gorbovoy's photo

No need to call "HideSplash" twice in then and catch . It's enough to call "Hide" in finally

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.

Show +1 replies
Kailash Uniyal's photo

What is the drawback of exposing props globally, it seems it doesn't affect performance or security?

Serdar Sanri's photo

Kailash Uniyal In a nutshell, Global variables cause (and more) the following issues.

1) Variable naming collisions - If you're working on a team and both yourself and your co-worker use the same variable name on the global scope, the variable defined last will overwrite the initial variable. This obvious can have devastating consequences.

2) Security - Specifically on the web, every user has access to the Window (or global) object. By putting variables on the global scope, you give any user the ability to see or change your variables.

3) Slower - This is arguably negligible, but it still exists. The way JavaScript variable lookups work is the JavaScript engine will do a lookup on the current scope the variable is being looked up in. If it can't find it, it will do a look up on the next parent scope. If it doesn't find it there, it will continue looking upward until it reaches the global object looking for that variable. If all of your variables are located on the global scope, the JavaScript engine will always have to go through every scope in order to finally reach the global scope to find the variable.

wiki.c2.com/?GlobalVariablesAreBad