Devrath
Devrath

Reputation: 42824

How to display toast message in react native

I am trying to display a toast message in react native on button click

import React,{ Component } from 'react';
import { StyleSheet,TextInput, View, Button, Text, ToastAndroid } from 'react-native';

export default class App extends Component {

  state = {
              placeName : "",
              titleText: "Text view"
          }

  placeNameChangeHandler = val =>{
   this.setState({
     placeName : val
   })
  }

  placeSubmitHandler = () =>{
    this.setState({
      titleText: this.state.placeName.trim() 

    })
  }

   render() {
      return (
      <View style={styles.rootContainer}>

        <View style={styles.btnEditContainer}>
          <View style ={styles.wrapStyle}>
          <TextInput
          style = {styles.textInputStyle}
          value = {this.state.placeName}
          onChangeText = {this.placeNameChangeHandler}
          />
        </View>
          <View style ={styles.wrapStyle}>
          <Button
          title="Add"
          style ={styles.buttonStyle}
          onPress ={this.placeSubmitHandler}/>
        </View>
        </View>

        <View style={styles.textContainer}>
          <View style ={styles.wrapStyle}>
            <Text
            style ={styles.textStyle}>
            {this.state.titleText}
            </Text>
          </View>
        </View>

        </View>
      );
   }
}

const styles = StyleSheet.create({
  rootContainer: {
    height:"100%",
    width:"100%",
    backgroundColor: "#008000",
    flexDirection:"column",
    alignItems:"center",
    justifyContent: "center"
  },
  btnEditContainer: {
    backgroundColor:"#008080",
    flexDirection:"row",
    alignItems:"center",
    justifyContent: "center"
  },
  textContainer: {
    backgroundColor:"#00FFFF",
    flexDirection:"column",
    alignItems:"center",
    justifyContent: "center"
  },
  textStyle: {
    fontSize: 20,
    flexDirection:"column",
    alignItems:"center",
    justifyContent: "center"
  },
  buttonStyle: {
  },
  textInputStyle: {
    borderColor:"black",
    borderWidth:1,
  },
  wrapStyle: { marginLeft:5,
    marginRight:5 },
});

Upvotes: 36

Views: 96302

Answers (6)

Johnson Fashanu
Johnson Fashanu

Reputation: 1130

Custom Toast Component

import { useRef, useState } from "react";
import { Animated, Text, TextProps, ViewProps } from "react-native";

const useToast = (dur = 1000) => {
  const [message, setMessage] = useState('');
  const [txtSty, setTxtSty] = useState<TextProps['style']>({});
  const [ctnSty, seCtnSty] = useState<ViewProps['style']>({});
  const [showToast, setShowToast] = useState(false);
  const fadeAnim = useRef(new Animated.Value(0)).current;

  const toast = ({ message, containerStyle, textStyle, duration }: { message: string, containerStyle?: ViewProps['style'], duration?: number, textStyle?: TextProps['style'] }) => {
    seCtnSty(containerStyle);
    setTxtSty(textStyle);
    if (!showToast) {
      setMessage(message);
      setShowToast(true);
      Animated.timing(fadeAnim, {
        toValue: 1,
        duration: 400,
        useNativeDriver: true,
      }).start();
      setTimeout(() => {
        Animated.timing(fadeAnim, {
          toValue: 0,
          duration: 400,
          useNativeDriver: true,
        }).start(() => {
          setShowToast(false);
        });
      }, duration || dur);
    }
  };

  const ToastContainer = ({ style, textStyle }: { textStyle?: TextProps['style'], style?: ViewProps['style'] }) => {
    return showToast ?
      <Animated.View
        style={[{
          backgroundColor: '#292929',
          borderRadius: 30,
          paddingVertical: 15,
          paddingHorizontal: 20,
          position: 'absolute',
          bottom: '5%',
          alignSelf: 'center'
        }, { opacity: 1 }, style, ctnSty]}>
        <Text style={[{ textAlign: 'center', color: 'white' }, textStyle, txtSty]}>
          {message}
        </Text>
      </Animated.View> : null
  }

  return {
    ToastContainer,
    toast
  }
}

export default useToast;

const Page = () => {
  const { toast, ToastContainer } = useToast()
  const showToast = () => {
    toast({ message: 'Hello World' })
  }

  return (
    <SafeAreaView style={{ flex: 1 }} edges={['top']}>
      <View style={{ flex: 1, padding: 20 }} >
        <Calendar />
      </View>
      <View className="my-10 p-4">
        <TouchableOpacity onPress={showToast} className="border p-3">
          <Text className="text-center">Show Toast</Text>
        </TouchableOpacity>
      </View>
      <ToastContainer />
    </SafeAreaView>
  )
}

export default Page

Upvotes: 0

Rocky
Rocky

Reputation: 3235

Can use below notifyMessage to show toast message:

import { ToastAndroid, Platform, AlertIOS} from 'react-native';

function notifyMessage(msg: string) {
  if (Platform.OS === 'android') {
    ToastAndroid.show(msg, ToastAndroid.SHORT)
  } else {
    AlertIOS.alert(msg);
  }
}

OR

Use react-native-simple-toast in both iOS & Android.

import Toast from 'react-native-simple-toast';

Toast.show('This is a toast.');
Toast.show('This is a long toast.', Toast.LONG);

Upvotes: 74

JohnsonSharon
JohnsonSharon

Reputation: 11

Create a separate component for this customized toast and use this code there:

import React, {
     useState, 
    useImperativeHandle,
     forwardRef,
     useRef } from "react";
import {
      Text,
      StyleSheet,
      Animated,
      Platform,
      UIManager,
    } from "react-native";
    
    if (
      Platform.OS === "android" &&
      UIManager.setLayoutAnimationEnabledExperimental
    ) {
      UIManager.setLayoutAnimationEnabledExperimental(true);
    }
    
    const Toast = (props, ref) => {
      const [showToast, setShowToast] = useState(false);
      const fadeAnim = useRef(new Animated.Value(0)).current;
    
      const toast = () => {
        if (!showToast) {
          setShowToast(true);
          Animated.timing(fadeAnim, {
            toValue: 1,
            duration:500,
            useNativeDriver: true,
          }).start();
          setTimeout(() => {
            Animated.timing(fadeAnim, {
              toValue: 0,
              duration: 500,
              useNativeDriver: true,
            }).start(() => {
              setShowToast(false);
            });
          }, 3000); 
        }
      };
    
      useImperativeHandle(ref, () => ({
        toast,
      }));
    
      if (showToast) {
        return (
          <Animated.View style={[styles.toastContainer, { opacity: fadeAnim }]}>
            <Text style={styles.toastText}>{props.message}</Text>
          </Animated.View>
        );
      } else {
        return null;
      }
    };
    
    const styles = StyleSheet.create({
      container: {
        position: "absolute",
        borderRadius: 30,
        overflow: "hidden",
        flexDirection: "row",
        bottom: 20,
        right: 20,
        alignItems: "center",
        justifyContent: "center",
      },
      toastContainer: {
        backgroundColor: "#292929",
        borderRadius: 10,
        padding: 10,
        position: "absolute",
        bottom: 100,
        alignSelf: "center",
      },
      toastText: {
        color: "white",
        fontSize: 14,
      },
    });
    
    export default forwardRef(Toast);

And call it from the component you want; for your reference:

    const ToastRef = useRef(null);
     const showToast = () => {
        ToastRef.current.toast();
      };

    <Toast ref={ToastRef} message="Hello World!" />

Upvotes: 1

sminmgr
sminmgr

Reputation: 342

React Native now has built-in API Alert which works both on IOS and Android. https://reactnative.dev/docs/alert

Upvotes: 0

Gilad M
Gilad M

Reputation: 1010

You can also use the package toast message. Check react-native-toast-message

Upvotes: 0

jeanverster
jeanverster

Reputation: 294

If you're looking for a simple, JS only implementation of toast notifications for react native which works on both iOS and Android you can have a look at

https://github.com/jeanverster/react-native-styled-toast

Usage:

import { useToast } from 'react-native-styled-toast'

const { toast } = useToast()

return <Button onPress={() => toast({ message: 'Check me out!', ...config })} />

Upvotes: 0

Related Questions