This ugly code works. Every second viewportHeight
is set to the value of window.visualViewport.height
const [viewportHeight, setViewportHeight] = React.useState(0);
React.useEffect(() => {
setInterval(() => {
setViewportHeight(window.visualViewport.height);
}, 1000);
}, []);
However this doesn't work. viewportHeight
is set on page load but not when the height changes.
React.useEffect(() => {
setViewportHeight(window.visualViewport.height);
}, [window.visualViewport.height]);
Additional context: I need the page's height in state and I need the virtual keyboard's height to be subtracted from this on Mobile iOS.
You can only use state variables managed by React as dependencies - so a change in window.visualViewport.height
will not trigger your effect.
You can instead create a div that spans the whole screen space and use a resize observer to trigger effects when its size changes:
import React from "react";
import useResizeObserver from "use-resize-observer";
const App = () => {
const { ref, width = 0, height = 0 } = useResizeObserver();
const [viewportHeight, setViewportHeight] = React.useState(height);
React.useEffect(() => {
setViewportHeight(window.visualViewport.height);
}, [height]);
return (
<div ref={ref} style={{ width: "100vw", height: "100vh" }}>
// ...
</div>
);
};