mvasin / react-div-100vh

A workaround for the '100vh' issue in mobile browsers

Home Page:https://react-div-100vh.vercel.app

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Ditch rvh for a React hook and rewrite in TypeScript

mvasin opened this issue · comments

Just want to share that I'm phasing out rvh units in favour of use100vh React hook and rewrite the whole thing in TypeScript along the way.

@mvasin check out https://github.com/streamich/react-use - there are some tools here that might help.

I merged to master and published on npm as react-div-100vh@0.4.0-beta.1. But I may miss something obvious; please try it out - your feedback is absolutely welcome!

The long-awaited rewrite using TypeScript and React hooks has been released as react-div-100vh@0.4.0, closing the issue.

From the looks of this hook's dependency array, it's going to run on every render. I think the dependency array should be empty, and the handler function should be moved into the scope of the effect closure. getRealHeight and setHeight are both constant, so they don't need to be included in the dependency array.

useEffect(() => {
window.addEventListener('resize', setRealHeight)
return () => window.removeEventListener('resize', setRealHeight)
}, [setRealHeight, height])

Thanks for putting this together. Let me know if you'd like some help with this.

Hi @jbaudanza! Sounds like a very reasonable optimisation, I will do it.

Hey @jbaudanza,

I wrote some tests https://github.com/mvasin/react-div-100vh/blob/master/lib/jsdom.test.tsx and looks like the hook does not re-attach event listeners on every re-render. What do you think?

I set a breakpoint in my browser debugger, and that effect hook is definitely getting invoked multiple times. I don't know why the test isn't failing. Maybe React doesn't propagate the render down through TestApp into Div100h for some reason?

As it's written, setRealHeight is going to be redefined on every render, and will have a new identity. Since it's part of the dependency array, it will always re-trigger the effect.

This is how it should look:

const [height, setHeight] = React.useState(getRealHeight())

React.useEffect(() => {
  function handler() {
    setHeight(getRealHeight());
  }

  window.addEventListener('resize', handler)
  return () => window.removeEventListener('resize', handler)
}, []);