在调整浏览器窗口的大小时,如何重新渲染视图?

出身背景

我有一些块,我想在页面上单独布局,但我也希望它们在浏览器窗口更改时更新.最终的结果大约是Ben Holland's个Pinterest布局,但不只是使用jQuery编写.我还有一段路要走.

密码

这是我的应用程序:

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 (
        <div>
      <Blocks data={this.state.data}/>
      </div>
    );
  }
});

React.renderComponent(
  <MyApp url="url_here"/>,
  document.getElementById('view')
)

然后我有Block个组件(相当于上面Pinterest示例中的Pin):

var Block = React.createClass({
  render: function() {
    return (
        <div class="dp-block" style={{left: this.props.top, top: this.props.left}}>
        <h2>{this.props.title}</h2>
        <p>{this.props.children}</p>
        </div>
    );
  }
});

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 order={block.id} title={block.summary} left={leftOffset} top={topOffset}>{block.description}</Block>;
    });

    return (
        <div>{blockNodes}</div>
    );
  }
});

问题

我应该添加jQuery的窗口调整大小吗?如果是,在哪里?

$( window ).resize(function() {
  // re-render the component
});

有没有一种更"react "的方式来做这件事?

推荐答案

Using React Hooks:

您可以定义一个监听Window resize事件的自定义钩子,如下所示:

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>;
}

这里的优点是逻辑是封装的,你可以在任何你想使用窗口大小的地方使用这个钩子.

Using React classes:

您可以在componentDidMount中收听,类似于这个只显示窗口尺寸(如<span>Window size: 1024 x 768</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);
  }
}

Javascript相关问答推荐

根据密钥中存储的概率在数组内 Select 随机对象

使用jQuery在 bootstrap 网格中添加/删除元素并防止删除第一个元素

阻止iOS浏览器在传输摄像机视频时启用全屏摄像机模式

在nodejs中使用快速路由的API路径

当我使用jQuery时,我的图标显示为[对象对象]

如何用变量productId替换 1"

try 在addEventHandler内设置表单的文件输入.值=空

d3可排序表标题行中有收件箱--如何使收件箱不触发排序?

带对角线分隔符的图像滑动器

我的YouTube视频没有以html形式显示,以获取免费加密信号

通过实现regex逻辑自定义数据表搜索

创建1:1比例元素,以另一个元素为中心

是否有方法在OpenWeatherMap API中获取过go 的降水数据?

Phaser框架-将子对象附加到Actor

每次子路由重定向都会调用父加载器函数

Cypress -使用commands.js将数据测试id串在一起失败,但在将它们串在一起时不使用命令有效

通过在页面上滚动来移动滚动条

Reaction组件在本应被设置隐藏时仍显示

在画布中调整边上反弹框的大小失败

JavaScript -复制到剪贴板在Windows计算机上无效