2

I am building a notifer component for my website. Basically one you hit say "add" and the item is "added" on the top of my website a green bar will come up and say "successfully created"

Now after a second I would like it to disappear. I am not sure what the best way to do this would be? Is it to have a javascript timer somewhere?

import React from 'react';

import 'materialize-css/sass/materialize.scss';
import 'font-awesome/scss/font-awesome.scss';

import 'materialize-css/js/materialize.js';
import classNames from 'classnames/index.js';

export default class Notifer extends React.Component {
    render() {
        var notifcationClasses = classNames({
            'notifcation-success': this.props.notiferReducer.success,
            'notifcation-error': this.props.notiferReducer.error,
            'hide': !(this.props.notiferReducer.success || this.props.notiferReducer.error)
        });
        return (
            <div id="notifcation" className={notifcationClasses}>
                Sucessfully created
            </div>
        );
    }
}

Action

import {actions}  from './Actions.js';

export function setNotifer(success) {
    return function (dispatch) {
        dispatch({ type: actions.SET_NOTIFIER, payload: success });
    };
}

Reducer

import { actions } from '../actions/Actions';

export default function NotiferReducer(state = {
    success: false,
    error: false
}, action) {
    switch (action.type) {
        case actions.SET_NOTIFIER: {
            return {
                success: action.payload,
                error: !action.payload
            };
        }
    }
    return state;
}

Normally I would use something like growl but I did not see anything for reactjs(well I did see some but none of them seemed to be very popular)

4
  • setTimeout(function(){ alert("Hello"); }, 3000); Since you are asking the best way... I would put an OK button on the dialog.... especially the error dialog to make sure the user has enough time to read and comprehend it. Commented Aug 15, 2016 at 21:20
  • 1
    I would set a timeout in your action creator to trigger another action to close the view. Commented Aug 15, 2016 at 21:56
  • @riscarrott can you put an more of an example of this? Which action are you talking about the "add" action " or "notifier" action. Commented Aug 15, 2016 at 22:02
  • Why not use something that has this built in? Take a look at: github.com/CodeSeven/toastr Commented Aug 15, 2016 at 22:44

2 Answers 2

4

As it looks like you're using redux-thunk I would set a timeout in your action creator to trigger another action to close the notification, e.g.

import {actions}  from './Actions.js';

export function setNotifer(success) {
    return function (dispatch) {
        dispatch({ type: actions.SET_NOTIFIER, payload: success });
        setTimeout(() => dispatch({ type: actions.CLOSE_NOTIFIER }), 1000) 
    };
}

Then your reducer would just nullify the success and error properties when it receives the CLOSE_NOTIFIER action.

This would keep your components synchronous and it's ultimately the same pattern commonly used when making ajax requests in redux.

Sign up to request clarification or add additional context in comments.

Comments

1

You can use a simple setTimeout to achieve this:

(*edit* I've updated the snippet to use redux and redux-thunk)

const { Component } = React;
const { render } = ReactDOM;
const { createStore, combineReducers, applyMiddleware } = Redux;
const { connect, Provider } = ReactRedux;

const message = (state = null, action) => {
  switch (action.type) {
    case 'SET_NOTIFICATION':
      return action.message;
    default:
      return state;
  }
};

const setNotification = (message, duration) => (dispatch, getState) => {
  dispatch({type: 'SET_NOTIFICATION', message: message});
  setTimeout(() => {
    dispatch({type: 'SET_NOTIFICATION', message: null});
  }, duration);
};


const store = createStore(
  combineReducers({message: message}),
  applyMiddleware(ReduxThunk.default)
);

class App extends Component {
      
  showMessage = () => {
    this.props.dispatch(
      setNotification('This message will self destruct in 3 seconds', 3000)
    );
  };

  render() {  
    return (
      <div>
        {this.props.message && <div className="message">{this.props.message}</div>}
        <br />
        <button onClick={this.showMessage}>Click to show message</button>
      </div>
    );
  }
}

App = connect(
  state => ({ message: state.message })
)(App);

render(
  <Provider store={store}>
    <App />
  </Provider>,
  
  document.getElementById('app')
);
.message {
  border: 1px solid green;
  background-color: rgba(0,255,0, 0.1);
  border-radius: 4px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<script src="https://npmcdn.com/[email protected]/dist/redux.min.js"></script>
<script src="https://npmcdn.com/[email protected]/dist/redux-thunk.min.js"></script> 
<script src="https://npmcdn.com/[email protected]/dist/react-redux.min.js"></script>

<div id="app"></div>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.