patternjavascriptreactCritical
Rerender view on browser resize with React
Viewed 0 times
viewresizererenderreactwithbrowser
Problem
How can I get React to re-render the view when the browser window is resized?
Background
I have some blocks that I want to layout individually on the page, however I also want them to update when the browser window changes. The very end result will be something like Ben Holland's Pinterest layout, but written using React not just jQuery. I’m still a way off.
Code
Here’s my app:
Then I have the
and the list/collection of
Question
Should I add jQuery’s window resize? If so, where?
Is there a more “React” way of doing this?
Background
I have some blocks that I want to layout individually on the page, however I also want them to update when the browser window changes. The very end result will be something like Ben Holland's Pinterest layout, but written using React not just jQuery. I’m still a way off.
Code
Here’s my app:
var MyApp = React.createClass({
//does the http get from the server
loadBlocksFromServer: function() {
$.ajax({
url: this.props.url,
dataType: 'json',
mimeType: 'textPlain',
success: function(data) {
this.setState({data: data.events});
}.bind(this)
});
},
getInitialState: function() {
return {data: []};
},
componentWillMount: function() {
this.loadBlocksFromServer();
},
render: function() {
return (
);
}
});
React.renderComponent(
,
document.getElementById('view')
)Then I have the
Block component (equivalent to a Pin in the above Pinterest example):var Block = React.createClass({
render: function() {
return (
{this.props.title}
{this.props.children}
);
}
});and the list/collection of
Blocks:var Blocks = React.createClass({
render: function() {
//I've temporarily got code that assigns a random position
//See inside the function below...
var blockNodes = this.props.data.map(function (block) {
//temporary random position
var topOffset = Math.random() * $(window).width() + 'px';
var leftOffset = Math.random() * $(window).height() + 'px';
return {block.description};
});
return (
{blockNodes}
);
}
});Question
Should I add jQuery’s window resize? If so, where?
$( window ).resize(function() {
// re-render the component
});Is there a more “React” way of doing this?
Solution
Using React Hooks:
You can define a custom Hook that listens to the window
The advantage here is the logic is encapsulated, and you can use this Hook anywhere you want to use the window size.
Using React classes:
You can listen in componentDidMount, something like this component which just displays the window dimensions (like
You can define a custom Hook that listens to the window
resize event, something like this:import React, { useLayoutEffect, useState } from 'react';
function useWindowSize() {
const [size, setSize] = useState([0, 0]);
useLayoutEffect(() => {
function updateSize() {
setSize([window.innerWidth, window.innerHeight]);
}
window.addEventListener('resize', updateSize);
updateSize();
return () => window.removeEventListener('resize', updateSize);
}, []);
return size;
}
function ShowWindowDimensions(props) {
const [width, height] = useWindowSize();
return Window size: {width} x {height};
}The advantage here is the logic is encapsulated, and you can use this Hook anywhere you want to use the window size.
Using React classes:
You can listen in componentDidMount, something like this component which just displays the window dimensions (like
Window size: 1024 x 768):import React from 'react';
class ShowWindowDimensions extends React.Component {
state = { width: 0, height: 0 };
render() {
return Window size: {this.state.width} x {this.state.height};
}
updateDimensions = () => {
this.setState({ width: window.innerWidth, height: window.innerHeight });
};
componentDidMount() {
window.addEventListener('resize', this.updateDimensions);
}
componentWillUnmount() {
window.removeEventListener('resize', this.updateDimensions);
}
}Code Snippets
import React, { useLayoutEffect, useState } from 'react';
function useWindowSize() {
const [size, setSize] = useState([0, 0]);
useLayoutEffect(() => {
function updateSize() {
setSize([window.innerWidth, window.innerHeight]);
}
window.addEventListener('resize', updateSize);
updateSize();
return () => window.removeEventListener('resize', updateSize);
}, []);
return size;
}
function ShowWindowDimensions(props) {
const [width, height] = useWindowSize();
return <span>Window size: {width} x {height}</span>;
}import React from 'react';
class ShowWindowDimensions extends React.Component {
state = { width: 0, height: 0 };
render() {
return <span>Window size: {this.state.width} x {this.state.height}</span>;
}
updateDimensions = () => {
this.setState({ width: window.innerWidth, height: window.innerHeight });
};
componentDidMount() {
window.addEventListener('resize', this.updateDimensions);
}
componentWillUnmount() {
window.removeEventListener('resize', this.updateDimensions);
}
}Context
Stack Overflow Q#19014250, score: 916
Revisions (0)
No revisions yet.