fkhadra / react-toastify

React notification made easy πŸš€ !
https://fkhadra.github.io/react-toastify/introduction
MIT License
12.72k stars 700 forks source link

Error: <SHOW_TOAST> Event is not registered. #109

Closed ProductOfAmerica closed 6 years ago

ProductOfAmerica commented 6 years ago

Edit: Scroll to Actual Error

Hello, I've tried my best to follow the directions on the readme, but I'm not getting the expected output. Anything helps, I'm new to react and whatnot so please go easy on me if I did something stupid. Here's my code, and an example of what I'm getting instead:

2017-12-21_21-34-05

import React, {Component} from 'react';
import {ToastContainer, toast} from 'react-toastify';
import {Switch, Route, Redirect} from 'react-router-dom';
import {Container} from 'reactstrap';
import Header from '../../components/Header/Header';
import Sidebar from '../../components/Sidebar/Sidebar';
import Dashboard from '../../views/Dashboard/Dashboard';

// Pages
import Monitor from '../../views/Monitor/Monitor';
import SimpleLineIcons from '../../views/Icons/SimpleLineIcons/SimpleLineIcons';

class Full extends Component {
  constructor(props) {
    super(props);

    Full.notify = Full.notify.bind(this);
    Full.error = Full.error.bind(this);
    Full.success = Full.success.bind(this);
  }

  static notify() {
    return toast('Hello World!', {position: "top-center"});
  }

  static error() {
    return toast.error('Danger!');
  }

  static success() {
    return toast.success('Success...');
  }

  render() {

    return (
      <div>
        <button onClick={Full.error}>WEfF</button>
        <ToastContainer autoClose={5000}/>
        <div className="app">
          <Header/>
          <div className="app-body">
            <Sidebar {...this.props}/>
            <main className="main">
              <Container fluid>
                <Switch>
                  <Route path="/dashboard" name="Dashboard" component={Dashboard}/>
                  <Route path="/monitor" name="Buttons" component={Monitor}/>
                  <Route path="/settings" name="Buttons" component={Monitor}/>
                  <Route path="/profile" name="Buttons" component={Monitor}/>
                  <Route path="/icons/simple-line-icons" name="Simple Line Icons" component={SimpleLineIcons}/>
                  <Redirect from="/" to="/dashboard"/>
                </Switch>
              </Container>
            </main>
          </div>
        </div>
      </div>
    );
  }
}

export default Full;
fkhadra commented 6 years ago

Hey @ProductOfAmerica ,

Which version of react-toastify are you using ?

fkhadra commented 6 years ago

Could you try to install the latest version? I'm getting the impression that you are running an old version. if you use npm:

npm install react-toastify@latest

if you use yarn:

yarn add react-toastify@latest
ProductOfAmerica commented 6 years ago

I'm using "react-toastify": "2.2.0", strange that it would've reverted, because at one point it was working fine. You solved my problem! Thank you! Again, I don't know how it would've gone back to a previous version, since it was working at one point. Any ideas?

fkhadra commented 6 years ago

Thanks for the reply @ProductOfAmerica. If you need to stick with the version 2, you have to import an additional css file as follow:

import 'react-toastify/dist/ReactToastify.min.css';

The version 3 rely on styled component. It means that the css rules are injected at runtime and only the necessary rules are injected.

To sum up:

Hope the explanation is clear enough. Otherwise, don't hesitate I'm here to help 😁

ProductOfAmerica commented 6 years ago

@fkhadra Thank you for that amazing explanation, I did move toastify to a different component, so that would make perfect sense, because I didn't move any CSS imports with it. I really appreciate your quick feedback!

ProductOfAmerica commented 6 years ago

Hey @fkhadra, sorry for the bother, but I'm having problems again. Instead of making a new issue I decided to comment here. So the issue is this: <SHOW_TOAST> Event is not registered. Did you forgot to bind the event ? EventManager.js?f85b:33.

I seem to get the error only after I hit the back/forward buttons on my browser.

If I send a dispatch to my redux, Toaster.js picks it up in the componentWillReceiveProps method, and will grab the messageType and message out of the current redux store (I'm sure you could figure that out faster than it took me to write it). So, any time the store is updated, Toaster.js should switch on it, and toast the output.

And it works! But not if I go back a page. As soon as I use my arrow keys to navigate the page, toaster no longer works because of that binding issue. Any ideas?

Here's an exmaple: 2017-12-23_08-16-46

My code:

index.js:

import React from 'react';
import ReactDOM from 'react-dom';
import {Provider} from 'react-redux';
import {HashRouter, Route, Switch} from 'react-router-dom';
import store from "./redux/store";
import axios from "axios";
// Styles
import 'font-awesome/css/font-awesome.min.css';
import 'simple-line-icons/css/simple-line-icons.css';
import '../scss/style.scss'
import '../scss/core/_dropdown-menu-right.scss'
// Containers
import Full from './containers/Full/Full'
// Views
import Login from "./views/Pages/Login/Login";
import Logout from "./views/Pages/Logout/Logout";
import Register from './views/Pages/Register/Register';
import Page404 from './views/Pages/Page404/Page404';
import Page500 from './views/Pages/Page500/Page500';
import Toaster from './views/Toaster/Toaster';

axios.defaults.baseURL = location.protocol + '//' + location.hostname + ':' + 8081;
axios.interceptors.response.use(null, function (error) {
  return Promise.reject(error);
});

ReactDOM.render(
  <Provider store={store}>
    <div>
      <Toaster/>
      <HashRouter>
        <Switch>
          <Route exact path="/login" name="Login Page" component={Login}/>
          <Route exact path="/register" name="Register Page" component={Register}/>
          <Route exact path="/404" name="Page 404" component={Page404}/>
          <Route exact path="/500" name="Page 500" component={Page500}/>
          <Route exact path="/logout" name="Logout Page" component={Logout}/>
          <Route path="/" name="Home" component={Full}/>
        </Switch>
      </HashRouter>
    </div>
  </Provider>, document.getElementById('root'));

Toaster.js:

import React, {Component} from 'react';
import {connect} from "react-redux";
import {toast, ToastContainer} from 'react-toastify';
import messageTypes from "./toasterTypes";
import toastDisp from "../../redux/dispatchers/toastDispatcher";

@connect((store) => {
  return {
    messageType: store.messageHandler.messageType,
    message: store.messageHandler.message
  }
})
class Toaster extends Component {
  constructor(props) {
    super(props);
  }

  componentWillReceiveProps(nextProps) {
    if (nextProps.messageType && nextProps.message) {
      const opts = {position: "top-center"};

      switch (nextProps.messageType) {
        case messageTypes.SUCCESS:
          toast.success(nextProps.message, opts);
          break;
        case messageTypes.INFO:
          toast.info(nextProps.message, opts);
          break;
        case messageTypes.WARN:
          toast.warn(nextProps.message, opts);
          break;
        case messageTypes.ERROR:
          toast.error(nextProps.message, opts);
          break;
      }

      toastDisp.removeMessage(this.props.dispatch);
    }
  }

  render() {
    return (
      <ToastContainer autoClose={5000}/>
    );
  }

}

export default Toaster;
ProductOfAmerica commented 6 years ago

Reopening, seems like a bug?

ProductOfAmerica commented 6 years ago

Good news, I found the solution to this problem. It occurs if you have two instances of ToastContainer in your project. I accidentally left one in a different component. I think what was happening was the two were conflicting, and one of the components containing the ToastContainer would dismount, causing the toast.whatever() calls to toast to the missing component.

Now we know! :D

fkhadra commented 6 years ago

@ProductOfAmerica I was unable to reproduce the issue. I'm glad you have been able to solve the issue 😁

jeffersoneagley commented 6 years ago

I just ran in to a similar-looking issue: image

I've doublechecked, I'm up to date and there's only one toastcontainer in the project... The toasts sort of brokenly insert themselves into the page wherever the toastcontainer element is.

I'm in the middle of migrating a project to reactstrap (bootstrap v4) from react-bootstrap (v3), and flow-typed. Not sure if either of those would interfere, but they're the only real new thing I've added.

fkhadra commented 6 years ago

@jeffersoneagley did you import the css file ?

import 'react-toastify/dist/ReactToastify.css'
jeffersoneagley commented 6 years ago

Well.. that fixed it... I am not sure why I didn't see that in any of the instruction sets I looked at.

I've also noticed when a toast pops up over a modal, the grayed out area goes transparent and starts strobing. image The light area around the toast is over a modal's gray box. it flickers between the gray and the clear.

ProductOfAmerica commented 6 years ago

@jeffersoneagley just saying....it was literally in the first code example: chrome_2018-07-18_14-45-43

Also, start a new issue.