我希望在ReactJS中实现一个具有以下功能的表:
我想出了两种使用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。
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;}
问题是空状态也会动画化。
有关如何获得所需行为的任何建议?
谢谢!
答案 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>
);
}
});