在做出反应时,如何在孩子改变时注意到?

时间:2017-06-01 22:22:23

标签: javascript css reactjs

我正在创建一个名为Scrollable的类,如果子元素的宽度/高度超过某个值,则可以滚动。这是代码。

import React, { Component } from 'react';

const INITIAL = 'initial';

class Scrollable extends Component {
  render() {
    let outter_styles = {
      overflowX: (this.props.x? 'auto': INITIAL),
      overflowY: (this.props.y? 'auto': INITIAL),
      maxWidth: this.props.width || INITIAL,
      maxHeight: this.props.height || INITIAL,
    };
    return (
      <div ref={el => this.outterEl = el} style={outter_styles}>
        <div ref={el => this.innerEl = el}>
          {this.props.children}
        </div>
      </div>
    );
  }
};

export default Scrollable;

// To use: <Scrollable y><OtherComponent /></Scrollable>

这很有效。除了现在我想添加一个功能,使滚动总是滚动到底部。我知道如何做到这一点:

this.outterEl.scrollTop = this.innerEl.offsetHeight;

但这只需要在this.props.children高度变化时调用。对于如何实现这个目标有什么想法吗?

提前致谢。

2 个答案:

答案 0 :(得分:0)

我会推荐一个包element-resize-detector。它不是特定于React的,但您可以轻松地在其周围构建高阶组件或将Scrollable组件与其集成。

答案 1 :(得分:0)

现在我有了解决这个问题的想法。

因为我正在使用react-redux。问题是我无法在此Scrollable组件上使用生命周期挂钩,因为更新内容时可能不一定会更改this.props.children

实现此目的的一种方法是让Scroll组件识别redux state中的相应值。因此,当更新相关值时,我们可以向下滚动到底部。

可滚动组件:

import React, { Component } from 'react';

const INITIAL = 'initial';

class Scrollable extends Component {
  componentWillUpdate(){
    if(this.props.autoScroll){
      // only auto scroll when the scroll is already at bottom.
      this.autoScroll = this.outterEl.scrollHeight - this.outterEl.scrollTop - Number.parseInt(this.props.height) < 1;
    }
  }

  componentDidUpdate(){
    if(this.autoScroll) this.outterEl.scrollTop = this.outterEl.scrollHeight;
  }

  render() {
    let styles = {
      overflowX: (this.props.x? 'auto': INITIAL),
      overflowY: (this.props.y? 'auto': INITIAL),
      maxWidth: this.props.width || INITIAL,
      maxHeight: this.props.height || INITIAL,
    };
    return (
      <div ref={el => this.outterEl = el} style={styles}>
        <div ref={el => this.innerEl = el}>
            {this.props.children}
        </div>
      </div>
    );
  }
};

export default Scrollable;

可滚动容器:

import { connect } from 'react-redux';

import Scrollable from '../components/Scrollable';

const mapStateToProps = (state, ownProps) => Object.assign({
  state: state[ownProps.autoScroll] || false
}, ownProps);

export default connect(mapStateToProps)(Scrollable)

这样,当相应的状态改变时,将调用Scrollable的生命周期钩子。