我刚刚开始使用React。我有一个包含许多表的项目,有些非常复杂,但通常都会从一组数据中输出一个表。一些具有父子关系(具有可切换的子行),并且每个具有稍微不同的行输出格式(例如,一些具有打开模态的按钮)。通常情况下,我会使用jQuery DataTables,这对于这样的事情来说很容易和灵活。不过,我正在努力弄清楚如何在React中可持续地(可扩展?)。
我编写了一个基本的表组件,它通过props接受一组项目并吐出一个表并通过内部状态处理子行。今天我将它转换为使用两个组件:表和行的单独组件。我真的不想写X或2X不同的组件(其中X是项目中的表的数量),但我不知道如何使它可重用。所有表都应该有一些共同点,如样式,过滤器功能,分页等,我会尝试将其放在Table组件级别并重用。
到目前为止,我考虑过的最佳解决方案是通过props传递preRender
函数并使用它来创建实际的行JSX,并使render
函数只汇编所有那些片段分成一个输出(这基本上就是我已经用Array.map
做的了。然后我可以通过一个道具(如果有效)提供preRender
,如下所示:
var Table = React.createClass({
render: function() { // mixin?
var rows = [];
for (var i=0; i<this.props.items.length; i++) {
rows.push(this.props.preRender(this.props.items[i]));
}
return rows; // plus html boilerplate...
}
});
var Parent = React.createClass({
render: function() {
var foodItems = this.state.foodItems;
var drinkItems = this.state.drinkItems;
var foodRender = function(i) { return (<tr>{i} <a href?>Buy me</a></tr>); }
var drinkRender = function(i) { return (<tr>{i} <button>Drink me</button></tr>); }
return (
<Table items={foodItems} preRender={foodRender}/>
<Table items={drinkItems} preRender={drinkRender}/>
);
}
});
我想到的另一件事是以某种方式将不同的Row组件传递给Table组件,如果可能的话。我猜根本问题是:
有没有更好的方法来进行这种逻辑/依赖注入,或者我可能只需要制作大量略有不同的控件。
答案 0 :(得分:2)
我从这样的事情开始(为简洁起见使用ES6语法):
const FoodItem = React.createClass({
render() {
return (
<tr><td>{this.props.item} <a href="something">Buy me</a></td></tr>
);
}
});
const DrinkItem = React.createClass({
render() {
return (
<tr><td>{this.props.item} <button>Drink me</button></td></tr>
);
}
});
const Table = React.createClass({
render() {
const {items, itemComponent: ItemComponent} = this.props;
return (
<table>
{items.map(item => <ItemComponent item={item} />)}
</table>
);
}
});
const Parent = React.createClass({
render() {
return (
<div>
<Table items={this.state.foodItems} itemComponent={FoodItem}/>
<Table items={this.state.drinkItems} itemComponent={DrinkItem}/>
</div>
);
}
});
另一种模式(最好取决于您的要求):
const FoodItem = React.createClass({
render() {
return (
<tr><td>{this.props.item} <a href="something">Buy me</a></td></tr>
);
}
});
const DrinkItem = React.createClass({
render() {
return (
<tr><td>{this.props.item} <button>Drink me</button></td></tr>
);
}
});
const Table = React.createClass({
render() {
// I'm assuming you ultimately want your table to do something cleverer than just rendering a table element
return (
<table>{this.props.children}</table>
);
}
});
const Parent = React.createClass({
render() {
return (
<div>
<Table>{this.state.foodItems.map(item => <FoodItem item={item} />)}</Table>
<Table>{this.state.drinkItems.map(item => <DrinkItem item={item} />)}</Table>
</div>
);
}
});