score:0

i found the root of the problem. sometimes you are too focused on something and you forget the little details of useeffect. it is always dangerous to provide objects as dependency arrays to useeffect. the dependency array values should be simple values. so now i introduced a new state (flag, setflag) with just boolean values and i make the second useeffect just to follow that simple value. everything is working just fine now.


import react, {useeffect, usestate} from 'react'
import i18n from '../../i18n'
import styled from 'styled-components'
import {createglobalstyle} from 'styled-components'
import {useselector} from 'react-redux'

const notificationstyle = createglobalstyle`
    @media (max-width: 500px) {
        .notification_mssg {
            left: 10px;
        }
    }
`

const container = styled.div`
  color: white;
  position: fixed;
  top: ${(props) => props.top}px;
  right: 16px;
  z-index: 2000;
  transition: top 0.5s ease;
`

const notificationicon = styled.div`
  float: left;
  font-size: 27px;
  width: 40px;
  height: 40px;
  text-align: center;
`

const notificationmessage = styled.span`
  padding: 10px;
  line-height: 40px;
`

function notificationalertroot(props) {

  const create_notification = useselector((state) => state.notifications.create_notification)

  const {message, code} = create_notification.success_info
  const [showstate, setshowstate] = usestate({top: -100, msg: message, bgcolor: '#444'})
  const [flag, setflag] = usestate(false) // when you follow the showstate at the second useeffect you have an infinite loop. because it is an object.

  // show notification
  useeffect(() => {
    setshowstate({top: 96, msg: i18n.t(message), bgcolor: backgroundcolor(code)})
    setflag(true)
  }, [message, code])

  // hide notification after 2 seconds
  useeffect(() => {
    const timerid = settimeout(() => {
      setshowstate({top: -100,msg: '', bgcolor: `#ffffff00`})
      setflag(false)
    }, 2000)

    return () => {
      cleartimeout(timerid)
    }
  }, [flag]) // showstate

  const notificationicon = (bgcolor) => {
    switch (bgcolor) {
      case '#32c786':
        return (
          <notificationicon style={{background: '#2aa872'}}>
            <i classname="zmdi zmdi-info" />
          </notificationicon>
        )
      case '#ffc721':
        return (
          <notificationicon style={{background: '#fabb00'}}>
            <i classname="zmdi zmdi-alert-triangle" />
          </notificationicon>
        )
      case '#ff6b68':
        return (
          <notificationicon style={{background: '#ff4642'}}>
            <i classname="zmdi zmdi-alert-circle" />
          </notificationicon>
        )
      default:
        return <span></span>
    }
  }

  const backgroundcolor = (code) => {
    switch (math.floor(code / 100)) {
      case 2:
        return '#32c786'
      case 3:
        return '#ffc721'
      case 4:
        return '#ff6b68'
      case 5:
        return '#ff6b68'
      default:
        return '#444'
    }
  }
  return (
    <react.fragment>
      <notificationstyle />
      <container
        classname="notification_mssg"
        top={showstate.top}
        style={{background: showstate.bgcolor}}
      >
        {notificationicon(showstate.bgcolor)}
        <notificationmessage>{showstate.msg}</notificationmessage>
      </container>
    </react.fragment>
  )
}

export default notificationalertroot





score:1

i guess the problem comes from your dependency array. your useeffect is dependent on showstate and each time, you are calling setshowstate in your useeffect when setshowstate is called showstate changes and then again, your useeffect gets invoked(it is dependent on showstate), and again setshowstate is called and ... infinity loop!


Related Query

More Query from same tag