React: How to trigger "global" snackbar/notification from components


#1

I’m new to React and have been trying it out with Meteor 1.3 with great joy.

However, I’ve reached a problem that I’m not sure how best to solve, and I couldn’t find anything related:

Imagine I want to display a notification “Concept added” / “Concept edited” when the user adds/edits a concept record. I’m using Material UI and its snackbar component for that.

Ideally, I’d like to have a global function as with S-Alert ala sAlert.info('Concept added'), but of course in React it does not seem to be this easy. I have to have a real React Component for each possible snackbar (<SnackBar message="..." />) and manage it’s visible state manually.

I can’t just put it with the form, since I will also change the route after the form is submitted!

So… Where do I put it? Probably somewhere up high in the hierarchy. But how do I trigger the snackbar from all the way down in some form component?

Let’s say I add a Snackbars component to my page that includes a <Snackbar> for all possible messages, and a method trigger(type) that I can pass elsewhere. Do I have to really pass this all the way down to every single component that might be calling it?

Or, the other way: Say I add the snackbar in the view that the user gets redirected to after submitting the form. How does the view know to display it? How do I trigger it from the (destroyed) form view?

Thanks!


#2

S-Alert has solved the same problem in its react component using Redux!


#3

Yes, redux in awesome. I’m using react-redux-toastr


#4

Thanks guys, I’ll have a look at Redux!
From a first glance though, I thought we don’t need Redux since Meteor handles data flow?


#5

You want redux for local state, but in fact you can handle local state in meteor. Mantra uses a global (locally global ^^) ReactiveDict for this.


#6

I don’t know if I got it right, but you want to trigger the Snackbar from different components. I’m not using Redux for such simple things I use PubsubJS. For example, you would add something like this to your Snackbar component:

componentDidMount() {
  var listener = PubSub.subscribe( 'showMessage',(message) => { /*** some code that make the component visible plus message} );
}

…and in all other components that should fire a message, you do

PubSub.publish( 'showMessage', 'Hello world!' );

#7

Interesting, thanks Dennis!

Sooo, what I gather is: It is ok to sometimes pass around data on a global context. Are there any rules for when this is acceptable?
So far most sources I’ve seen say “In React you need to push data through manually, layer by layer, but you’ll get used to it and it’s very clean”… :slight_smile:


#8

Could you not do something like this inside the component that needs to make an alert?

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

    this.state = {
      dialogMessage: '',
    };
  }

  render() {
    const { dialogMessage } = this.state;
    
    return <div>
      <Snackbar
        open={dialogMessage !== ''}
        message={dialogMessage}
        autoHideDuration={4000}
      />
    </div>
  }
}

#9

@ffxsam yeah but as mentioned that component gets destroyed, e.g. the submitting form / page. So I’d need to move it up… and up… and up… And it would get really ugly.


#10

Ahh right. Yeah, I’d use Redux for something like this.