Displaying Rails flash messages with React
Rails has a nice and useful mechanism to communicate to user via flash messages. By default these messages come from backend and are injected into the page while rendering the view.
But what if we want to show a client side message ? Or, for example, we did an unsuccessful Ajax request and want to warn user using a message in response. If you already use React in your project then you will find it as a good candidate to handle this.
The project sample is on Github.
- React in Rails for React/JSX/ES6 support in Rails app
- Twitter Bootstrap for Rails 3.x for Bootstrap styles
First what we would have to do is to implement Alert React component that could display a message using Bootstrap alerts:
As there might be multiple flash messages at once, we need to implement another React component that could display list of alerts. Let’s name it FlashMessages:
FlashMessages component is also a component where the state should live and it wraps a list of Alerts into a
Our React components are ready to use, so we can put them to the pages. First we would define a small application helper to convert Rails flash messages to the structure our React component expects it:
And now we can add react components to the pages using
react_component helper in application template:
So now Rails flash messages could be displayed using React. Nice. But two things need to be clarified:
- How to add new messages from client side ?
- Because we plan to add messages from client side, it would be nice to automatically hide older messages on timeout and unmount appropriate React components, wouldn’t it be ?
To achieve this we can slightly modify our components:
Now Alert component accepts
onClose callback and defines two new methods:
componentWillUnmount . These methods are used to set/clear timer to call
onClose callback. That’s it, after some period of time the component is going to be unmounted automatically.
Also now, the button to close an alert will call
onClose callback if being clicked instead of a
data-dismiss: 'alert' . This will let React to fully control the component. The process of dismissal was controlled by DOM itself.
Another small addition is type checking (
propTypes) and default properties (
defaultProps) that makes our component much more sensitive.
FlashMessages component is modified in the following way:
- In constructor we have saved a reference to this React component into a global variable. After a component being rendered, we can easily add a new message on client side:
- New methods
removeMessageto add a message to the list and remove it. Both use
updateaddon to change the collection.
- List of alerts are now wrapped into
CSSTransitionGroupto make some css animation. According the docs the animation itself has to defined using css transitions. So here it is:
This transition is really very similar to fade in and slide up effect. And the coolest thing is that now we have the same effect if we close alert manually or it is closed after a timeout:
It the article we found a pretty way to display Rails flash messages using React components. For this we created Alert and FlashMessages components and wrote a little of css for fade in and slide up effect.
This gives us a nicely looking and powerful mechanism to consistently talk to user from server side and client side as well.