1

I am working on a react app and I have a notification message that appears when the server returns an error or a successful operation. For example when the input in the login section are wrong, the notification is fired each time I press on login which is annoying and I would like to be fired once and wait a few seconds before it can be fired again. This is the code from App.js:

  import { useAddNotification } from './components/Notifications/NotificationProvider';
  const dispatchAddNotification = useAddNotification();

  const handleLogin = () => {
    axios.post('http://localhost:5000/auth/login', {
      username,
      password
    })
      .then(response => {
        // code here ...
        dispatchAddNotification({ result: "SUCCESS", message: "Succesfully Logged in!" });
      })
      .catch(error => {
        dispatchAddNotification({ result: "ERROR", message: error.msg });
      });
  }

useAddNotification comes from NotificationProvider.jsx which is the context that wraps the entire app.

const NotificationContext = createContext()
  export const useAddNotification = () => {
    const dispatch = useContext(NotificationContext);
      return (props) => {
        dispatch({
          type: "ADD_NOTIFICATION",
          payload: {
            id: v4(),
            ...props
          }
        })
      }
    }

const NotificationProvider = (props) => {
  const notifications = []

  // second parameter of the callback anonymous function is the initial state
  const [state, dispatch] = useReducer((state, action) => {
    switch (action.type) {
      case "ADD_NOTIFICATION":
        return [...state, { ...action.payload }];
      case "REMOVE_NOTIFICATION":
        return state.filter(item => item.id !== action.payload.id);
      default:
        return state;
    }
  }, notifications);

  return ( ...

How can I make is so that dispatchAddNotification is fired max once every 5 seconds? I tried like this but nope:

export const useAddNotification = () => {
  const [isCallable, setIsCallable] = useState(true);

  const dispatch = useContext(NotificationContext);

  const func = (props) => {
    dispatch({
      type: "ADD_NOTIFICATION",
      payload: {
        id: v4(),
        ...props
      }
    })
    setIsCallable(false)
  }

  setTimeout(() => {
    setIsCallable(true)
  }, 10000);

  return isCallable && func;
}
Andrea D_
  • 2,028
  • 3
  • 15
  • 38
  • Try creating `debounce` function and try to debounce your `dispatch` call inside the `useAddNotification`. What it will do is, it will restrict execution of the function that you are debouncing for `1000ms` if you are debouncing it for `1sec`. Also, if you are using debounce function inside a react component or a hook, make sure you wrap it inside a `useCallback` hook to cache it. – Shubham Waje Feb 14 '23 at 07:24

0 Answers0