How can I get React to re-render the view when the browser window is resized?
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 likeBen Holland'sPinterest layout, but written using React not just jQuery. I’m still a way off.
Here’s my app:
varMyApp = React.createClass({//does the http get from the serverloadBlocksFromServer: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(<div><Blocksdata={this.state.data}/>div>); } }); React.renderComponent(<MyAppurl="url_here"/>,document.getElementById('view') )
Then I have the blockcomponent (equivalent to a pinin the above Pinterest example):
varBlock = React.createClass({render:function(){return(<divclass="dp-block"style={{left:this.props.top,top:this.props.left}}><h2>{this.props.title}h2><p>{this.props.children}p>div>); } });
and the list/collection of Blocks :
varBlocks = React.createClass({render:function(){//I've temporarily got code that assigns a random position//See inside the function below...varblockNodes =this.props.data.map(function(block){//temporary random positionvartopOffset =Math.random() * $(window).width() +'px';varleftOffset =Math.random() * $(window).height() +'px';return<Blockorder={block.id}title={block.summary}left={leftOffset}top={topOffset}>{block.description}Block>; });return(<div>{blockNodes}div>); } });
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?
You can define a custom Hook that listens to the window resizeevent, something like this:
importReact, { useLayoutEffect, useState }from'react';functionuseWindowSize(){const[size, setSize] = useState([0,0]); useLayoutEffect(() =>{functionupdateSize(){ setSize([window.innerWidth,window.innerHeight]); }window.addEventListener('resize', updateSize); updateSize();return() =>window.removeEventListener('resize', updateSize); }, []);returnsize; }functionShowWindowDimensions(props){const[width, height] = useWindowSize();return<span>Window size: {width} x {height}span>; }
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
importReactfrom'react';classShowWindowDimensionsextendsReact.Component{ state = {width:0,height:0};render(){return<span>窗口大小:{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); } }