major697
major697

Reputation: 1862

React useState no changing value in render

I have a component with customButton for PWA:

const PWA = () => {
  const [supportsPWA, setSupportsPWA] = useState(false)
  const [deferredPrompt, setDeferredPrompt] = useState(null)

  useEffect(() => {
    const handler = e => {
      e.preventDefault()
      setDeferredPrompt(e)
      setSupportsPWA(true)
    }
    window.addEventListener('beforeinstallprompt', handler)

    return () =>
      window.removeEventListener('beforeinstallprompt', handler)
  }, [])

  return (
    <>
      {supportsPWA.toString()}
      {console.log(supportsPWA)}
      {supportsPWA && <div>test</div>}
    </>
  )
}
export default PWA

I have beforeinstallprompt which I change supportsPWA status from false to true. In render I have supportsPWA.toString() it's always false. Console log return me: false and next true, so if supportsPWA is true why React not render div test?

EDIT:

I found where is the problem. I render PWA component in another component: {showMobileMenu && (<PWA />)}. showMobileMenu I changing by button (from false to true ) and here is problem. When I remove showMobileMenu && ... and I have only <PWA /> then div test is rendering correctly. But I dont know how I can resolve it?

Upvotes: 1

Views: 158

Answers (1)

Mario Petrovic
Mario Petrovic

Reputation: 8312

Well in your case instead of doing {showMobileMenu && (<PWA />)} which dismounts and mounts your component every time just show/hide content in your PWA component, if that is acceptable:

const PWA = ({ showPWAComponent }) => {
  const [supportsPWA, setSupportsPWA] = useState(false)
  const [deferredPrompt, setDeferredPrompt] = useState(null)

  useEffect(() => {
    const handler = e => {
      e.preventDefault()
      setDeferredPrompt(e)
      setSupportsPWA(true)
    }
    window.addEventListener('beforeinstallprompt', handler)

    return () =>
      window.removeEventListener('beforeinstallprompt', handler)
  }, [])

  return showPWAComponent && (
    <div>
      {supportsPWA.toString()}
      {console.log(supportsPWA)}
      {supportsPWA && <div>test</div>}
    </div>
  )
}
export default PWA

And in the other component where you use PWA go:

{<PWA showPWAComponent={showMobileMenu} />)}

In any other case this case that you have will not work exactly because you have that removal of component there.

Upvotes: 1

Related Questions