Javascript 渲染后获取 React.refs DOM 节点宽度并仅在宽度值已更改时触发重新渲染

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35493942/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 17:48:38  来源:igfitidea点击:

Get React.refs DOM node width after render and trigger a re-render only if width has value has changed

javascriptreactjs

提问by Brad

I'm attempting to get the width of a refDOM element and set stateto then use within the Component render. The problem comes because this width changes on user input and when I try setStatewithin componentDidUpdateit starts an infinite loop and my browsers bombs.

我正在尝试获取refDOM 元素的宽度并设置state为然后在 Component 中使用render。问题来了,因为这个宽度会随着用户输入而改变,当我setStatecomponentDidUpdate它里面尝试时会开始一个无限循环,我的浏览器会爆炸。

I created a fiddle here http://jsbin.com/dizomohaso/1/edit?js,output(open the console for some information)

我在这里创建了一个小提琴http://jsbin.com/dizomohaso/1/edit?js,output(打开控制台获取一些信息)

My thinking was;

我的想法是;

  • Component Mounts, setState: refs.element.clientWidth

  • User inputs data, triggers render

  • shouldComponentUpdatereturns trueonly if new.stateis notequal to old.state. My problem is, I'm not sure where makes sense to update this state?

  • 组件安装, setState: refs.element.clientWidth

  • 用户输入数据,触发器 render

  • shouldComponentUpdate收益true只有当new.state等于old.state。我的问题是,我不确定在哪里更新这个有意义state

Any help will be much appreciated, thanks for reading!

任何帮助将不胜感激,感谢阅读!

Brad.

布拉德。

回答by David

var component = React.createClass({

  componentDidMount: function() {

    //Get initial width. Obviously, this will trigger a render,
    //but nothing will change, look wise.
    //But, if this is against personal taste then store this property 
    //in a different way
    //But it'll complicate your determineWidth logic a bit.        

    this.setState({
      elWidth: ReactDOM.findDOMNode(this.refs.the_input).getBoundingClientRect().width
    })
  },

  determineWidth: function() {

    var elWidth = ReactDOM.findDOMNode(this.refs.the_input).getBoundingClientRect().width

    if (this.state.elWidth && this.state.elWidth !== elWidth) {

      this.setState({
        elWidth: elWidth
      })

    }

  },

  render: function() {

    var styleProp = {}

    if (this.state.elWidth) {
      styleProp.style = { width: this.state.elWidth };
    }

    return (
      <input ref="the_input" onChange={this.determineWidth} {...styleProp} />
    )

  }

})

I like to use .getBoundingClientRect().widthbecause depending on your browser, the element might have a fractional width, and that width will return without any rounding.

我喜欢使用,.getBoundingClientRect().width因为根据您的浏览器,元素可能具有小数宽度,并且该宽度将返回而不进行任何舍入。