ReactCSSTransition表行和空表状态

时间:2017-02-27 17:50:51

标签: reactjs

我希望在ReactJS中实现一个具有以下功能的表:

  • 最初为空
  • 动态添加和删除行
  • 当没有行时,应显示空状态(例如显示“表空”的框)
  • 删除行时,应该有淡出过渡
  • 添加第一行时,空状态
  • 上不应有淡出过渡

我想出了两种使用ReactCSSTransitionGroup的方法。

1。仅将行换行到ReactCSSTransitionGroup

Codepen:https://codepen.io/skyshell/pen/OpVwYK

这里,表体呈现在:

renderTBodyContent: function() {
var items = this.state.items;
if (items.length === 0) {
  return (
    <tbody><tr><td colSpan="2">TABLE EMPTY</td></tr></tbody>
  );
}
const rows = this.state.items.map(function(name) {
  return (
    <tr key={name}>
      <td>{name[0]}</td>
      <td>{name[1]}</td>
    </tr>
  );
});
return (
  <ReactCSSTransitionGroup
    component="tbody"
    transitionName="example"
    transitionEnter={false}
    transitionLeave={true}>
      {rows}
  </ReactCSSTransitionGroup>
);}

问题是要删除的最后一行在消失之前没有得到淡出转换,因为在item.length === 0时没有呈现ReactCSSTransitionGroup。

2。将表体包装到ReactCSSTransitionGroup

Codepen:https://codepen.io/skyshell/pen/RpbKVb

这里,整个renderTBodyContent方法被包装到render方法中的ReactCSSTransitionGroup中:

<ReactCSSTransitionGroup
  component="tbody"
  transitionName="example"
  transitionEnter={false}
  transitionLeave={true}>
    {this.renderTBodyContent()}
</ReactCSSTransitionGroup>

RenderTBody方法如下:

renderTBodyContent: function() {
var items = this.state.items;
if (items.length === 0) {
  return (
    <tr><td colSpan="2">TABLE EMPTY</td></tr>
  );
}
const rows = this.state.items.map(function(name) {
  return (
    <tr key={name}>
      <td>{name[0]}</td>
      <td>{name[1]}</td>
    </tr>
  );
});
return rows;}

问题是空状态也会动画化。

有关如何获得所需行为的任​​何建议?

谢谢!

1 个答案:

答案 0 :(得分:0)

谢谢realseanp的指示。使用低级API和TweenMax而不是CSS转换,我提出了以下解决方案。首先,介绍一个Row组件:

var Row = React.createClass({
  componentWillLeave: function(callback) {
    var el = React.findDOMNode(this);
    TweenMax.fromTo(el, 1, {opacity: 1}, {opacity: 0, onComplete: callback})
  },

  componentDidLeave: function() {
    this.props.checkTableContent();
  },

  render: function() {
    const name = this.props.name;
    return (
      <tr>
        <td>{name[0]}</td>
        <td>{name[1]}</td>
      </tr>
    );
  }
});

然后根据isEmpty标志填充表格:

var Table = React.createClass({
  getInitialState: function() {
    return {
      items: [],
      isEmpty: true
    };
  },

  addRow: function() {
    var items = this.state.items;
    var firstName = firstNames[Math.floor(Math.random() * firstNames.length)];
    var lastName = lastNames[Math.floor(Math.random() * lastNames.length)];
    items.push([firstName, lastName]);
    this.setState({items: items, isEmpty: false});
  },

  removeLastRow: function() {
    var items = this.state.items;
    if (items.length != 0)  {
      items.splice(-1, 1);
      this.setState({items: items});
    }
  },

  checkTableContent: function() {
    if (this.state.items.length > 0) {
      this.setState({isEmpty: false});
    }
    else {
      this.setState({isEmpty: true});
      this.forceUpdate();
    }
  },

  renderTBodyContent: function() {
    if (this.state.isEmpty) {
      return (
        <tr><td colSpan="2">TABLE EMPTY</td></tr>
      );
    }
    var that = this;
    const rows = this.state.items.map(function(name) {
      return <Row
               key={name}
               name={name}
               checkTableContent={that.checkTableContent} />;
    });
    return rows;
  },

  render: function() {
    return (
      <div>
        <button onClick={this.addRow}>Add row</button>
        <button onClick={this.removeLastRow}>Remove row</button>
        <table>
          <thead>
            <tr>
              <th>First name</th>
              <th>Last name</th>
            </tr>
          </thead>
          <ReactTransitionGroup
            component="tbody"
            transitionName="example"
            transitionEnter={false}
            transitionLeave={true}>
            {this.renderTBodyContent()}
          </ReactTransitionGroup>
        </table>
      </div>
    );
  }
});

Codepen:https://codepen.io/skyshell/pen/yMYMmv