fkhadra / react-toastify

React notification made easy 🚀 !
https://fkhadra.github.io/react-toastify/introduction
MIT License
12.58k stars 692 forks source link

Not getting the science in your Component - example available? #94

Closed QRMarketing closed 6 years ago

QRMarketing commented 6 years ago

I am struggling to understand your examples. I have a parent Component triggering the toast Component. I want to trigger the toast from an event unrelated, not a button. All your examples come from a button. It works the first time through, but on every toast request after this, it does not show. I get the following console.log warning: EventManager.js:33 Event is not registered. Did you forgot to bind the event ? (interesting grammar coming from React, LOL)

Any suggestions might be interesting for me and others reading this post. Thanks in advance for reading.

In the parent of the Toast class above render() I have:

   ToastyReturn = () => {
        this.setState({ toastDisplay: false })
    }

    OrderopenReturn = (results) => {
        this.setState({ 
            toastDisplay: false
        })

        if(results.status === "send") {

            sendOrder(results).then(data => {
                // send data to server here is the call back point ... this works
                this.setState({ 
                    toastDisplay: true,
                    toastText: "This is trader: " + results.trader
                })

            });
        }
    }

Below render() I have:

        const { toastDisplay } = this.state

        let toastDisplayRender = null;
        if (toastDisplay) {

            toastDisplayRender = <OrderToasty callbackFromParent={this.ToastyReturn} toastText={this.state.toastText} />

        } else {

            toastDisplayRender = '';

        }

With return of the parent having:

{toastDisplayRender}

Here is my child Toast component:

import React, { Component } from 'react';
import { ToastContainer, toast } from 'react-toastify';

class OrderToasty extends Component {

    render(){

        var toasty = toast(this.props.toastText, {
              onClose: (childrenProps) => this.props.callbackFromParent()
        });

        return (

            <div>
                <ToastContainer 
                  position="bottom-left"
                  type="default"
                  autoClose={30000}
                  hideProgressBar={false}
                  newestOnTop={false}
                  closeOnClick
                  pauseOnHover
                />
                {toasty}
            </div>

        );
    }
}

export default OrderToasty
fkhadra commented 6 years ago

Hey @QRMarketing,

If you want to display a toast you don't need to render it like you did (see the comments below). The only component you need to mount is the ToastContainer:

class OrderToasty extends Component {

    render(){
         // wrong place -> It's like calling setState in the render method
        var toasty = toast(this.props.toastText, {
              onClose: (childrenProps) => this.props.callbackFromParent()
        });

        return (
            <div>
                <ToastContainer 
                  position="bottom-left"
                  type="default"
                  autoClose={30000}
                  hideProgressBar={false}
                  newestOnTop={false}
                  closeOnClick
                  pauseOnHover
                />
                {toasty} //You don't need that
            </div>
        );
    }
}

Each time you call the toast function a toast will be displayed.

In your case, I suppose that you need to display a toast when OrderToasty is mounted. To do so simply call toast inside componentDidMount:

class OrderToasty extends Component {
    componentDidMount(){
       toasty = toast(this.props.toastText, {
              onClose: (childrenProps) => this.props.callbackFromParent()
        });
   }
    render(){
        return (
            <div>
                <ToastContainer 
                  position="bottom-left"
                  type="default"
                  autoClose={30000}
                  hideProgressBar={false}
                  newestOnTop={false}
                  closeOnClick
                  pauseOnHover
                />
            </div>
        );
    }
}

Check the sample:

Edit React-toastify issue #94

If I misunderstood you please let me know.

QRMarketing commented 6 years ago

@fkhadra thanks for the reply. Yes I understand the science better now. Since I am using this with a popup modal, on taking it down from the parent, it got an setState not mounted error. So I had to do the following on the return from the child (others may want this):

ConfigopenReturn = (results) => { // <- return call from the child here in the parent

        this.setState({ 
            ConfigModal: false // <- takes down the child modal
        })

        setTimeout(function(){  // <- delay a bit for the render to finish before showing the toast

            var tmpDate = new Date().toLocaleTimeString()

            if(results === "save") {
                toast("New configurations set - " + tmpDate,{
                    className: 'toastSuccess',
                    progressClassName: 'progressClassName'
                }); 
            }
            if(results === "defaults") {        
                toast("Configuration defaults set - " + tmpDate,{
                    className: 'toastSuccess',
                    progressClassName: 'progressClassName'
                });  
            }

        }, 500);
    }

I also noticed that since - that on another toast I wanted to show a toast before taking down the modal I need to adjust the z-index, else the toast is under the modal. A little tricky on the selector, but I got it:

div.AppBodyLogin > div > div { // <- you will have to find the selector to adjust this, but
    z-index: 20000;                       // wrapping in a div with a class, helps to grab onto something
}

I could not do this on the classes you exposed. You may want to consider this.

Thanks again for the fast response.

fkhadra commented 6 years ago

Hey,

Regarding the zIndex, the next version will allow you to change the value with ease.

I'm glad I was able to help you