Get Viewport/Window Height in Reactjs

Get viewport/window height in ReactJS

class AppComponent extends React.Component {

constructor(props) {
super(props);
this.state = {height: props.height};
}

componentWillMount(){
this.setState({height: window.innerHeight + 'px'});
}

render() {
// render your component...
}
}

Set the props

AppComponent.propTypes = {
height:React.PropTypes.string
};

AppComponent.defaultProps = {
height:'500px'
};

viewport height is now available as {this.state.height} in rendering template

window width in react

Here's a simple example

const useWindowWide = (size) => {
const [width, setWidth] = useState(0)

useEffect(() => {
function handleResize() {
setWidth(window.innerWidth)
}

window.addEventListener("resize", handleResize)

handleResize()

return () => {
window.removeEventListener("resize", handleResize)
}
}, [setWidth])

return useWindowWidth > size
}

and to use it,

const Greeting = () => {
const wide = useWindowWide(600)
return (<h1>{wide ? "Hello World" : "Hello"}</h1>)
}

THere're quite a few hooks in the following reference might help you better.

  1. seWindowSize, https://usehooks.com/useWindowSize/
  2. useWindowSize, https://github.com/jaredLunde/react-hook/tree/master/packages/window-size

React execute script if window width

Use the above method that Mathis Delaunay mentioned to get viewport/window width, then to get rid of that button. Just simply add a condition to whether render it or not and then watch on state changes to trigger the function.
Here I use hooks to do it

import React, { useEffect, useState } from "react";
import ReactDOM from "react-dom";

function App() {
const [width, setWidth] = useState(window.innerWidth);

useEffect(() => {
function handleResize() {
setWidth(window.innerWidth);
}
window.addEventListener("resize", handleResize);
return () => window.removeEventListener("resize", handleResize);
}, [width]);

useEffect(() => {
width < 600 && handleSideNavToggle();
},[width]);

function handleSideNavToggle() {
console.log("toggle it");
}

return (
<div className="App">
{width > 600 && (
<button onClick={() => handleSideNavToggle()}>
Don't render huge images
</button>
)}
</div>
);
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Here is a working example. I set the width to be handled as 600 to make it easy to see.

https://codesandbox.io/s/react-hooks-counter-demo-w9wgv

How to detect window size in Next.js SSR using react hook?

You can avoid calling your detection function in ssr by adding this code:

// make sure your function is being called in client side only
if (typeof window !== 'undefined') {
// detect window screen width function
}

full example from your link:

import { useState, useEffect } from 'react';

// Usage
function App() {
const size = useWindowSize();

return (
<div>
{size.width}px / {size.height}px
</div>
);
}

// Hook
function useWindowSize() {
// Initialize state with undefined width/height so server and client renders match
// Learn more here: https://joshwcomeau.com/react/the-perils-of-rehydration/
const [windowSize, setWindowSize] = useState({
width: undefined,
height: undefined,
});

useEffect(() => {
// only execute all the code below in client side
// Handler to call on window resize
function handleResize() {
// Set window width/height to state
setWindowSize({
width: window.innerWidth,
height: window.innerHeight,
});
}

// Add event listener
window.addEventListener("resize", handleResize);

// Call handler right away so state gets updated with initial window size
handleResize();

// Remove event listener on cleanup
return () => window.removeEventListener("resize", handleResize);
}, []); // Empty array ensures that effect is only run on mount
return windowSize;
}

NB: Updated as Sergey Dubovik comment, we dont need to validate windows since useEffect run in client side

How to listen to width of page - React

To track the window's width in react you can make a custom hook to handle window resizing such as it is done here.

But in this concrete case I think you would be better off using CSS media queries with a mobile first approach.

.navbar-desktop {
display: none;
}

@media only screen and (min-width: 768px) {
/* For desktop: */
.navbar-desktop {
display: block;
}
.navbar-mobile {
display: none;
}
}

The code above hides the .navbar-desktop by default only showing it if the width of the viewport is greater than 768. Doing the exact opposite for the .navbar-mobile.

How to detect if screen size has changed to mobile in React?

What I did is adding an event listener after component mount:

componentDidMount() {
window.addEventListener("resize", this.resize.bind(this));
this.resize();
}

resize() {
this.setState({hideNav: window.innerWidth <= 760});
}

componentWillUnmount() {
window.removeEventListener("resize", this.resize.bind(this));
}

EDIT:
To save state updates, I changed the "resize" a bit, just to be updated only when there is a change in the window width.

resize() {
let currentHideNav = (window.innerWidth <= 760);
if (currentHideNav !== this.state.hideNav) {
this.setState({hideNav: currentHideNav});
}
}

UPDATE: Time to use hooks!
If you're component is functional, and you use hooks - then you can use the useMediaQuery hook, from react-responsive package.

import { useMediaQuery } from 'react-responsive';

...

const isMobile = useMediaQuery({ query: `(max-width: 760px)` });

After using this hook, "isMobile" will be update upon screen resize, and will re-render the component. Much nicer!

window.innerWidth in real time

Here's a way to do this:

import React from "react";
import ReactDOM from "react-dom";

class App extends React.Component {
constructor() {
super();

this.state = {
height: 0,
width: 0
};

window.addEventListener("resize", this.update);
}

componentDidMount() {
this.update();
}

update = () => {
this.setState({
height: window.innerHeight,
width: window.innerWidth
});
};

render() {
return (
<React.Fragment>
<p>height: {this.state.height}</p>
<p>width: {this.state.width}</p>
</React.Fragment>
);
}
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Working CodeSandbox here.

ReactJS - Get Height of an element

See this fiddle (actually updated your's)

You need to hook into componentDidMount which is run after render method. There, you get actual height of element.

var DivSize = React.createClass({
getInitialState() {
return { state: 0 };
},

componentDidMount() {
const height = document.getElementById('container').clientHeight;
this.setState({ height });
},

render: function() {
return (
<div className="test">
Size: <b>{this.state.height}px</b> but it should be 18px after the render
</div>
);
}
});

ReactDOM.render(
<DivSize />,
document.getElementById('container')
);
<script src="https://facebook.github.io/react/js/jsfiddle-integration-babel.js"></script>

<div id="container">
<p>
jnknwqkjnkj<br>
jhiwhiw (this is 36px height)
</p>
<!-- This element's contents will be replaced with your component. -->
</div>


Related Topics



Leave a reply



Submit