【发布时间】:2016-07-30 00:33:42
【问题描述】:
我正在用 React 组合一个表格控件,它几乎一直遵循这种模式,一直到单元格:
class Table extends Component {
static propTypes = {
tableClass: PropTypes.string,
columnDefinitions: PropTypes.array.isRequired
}
constructor(props) {
super(props);
}
render() {
const { tableClass, children } = this.props;
const passthroughProps = except(this.props, ['id', 'key', 'children', 'form', 'tableClass']);
const transformedChildren = React.Children.map(children, c => React.cloneElement(c, passthroughProps));
return (
<div className={ `${ tableClass ? `${tableClass} ` : '' }table` }>
{ transformedChildren }
</div>
);
}
}
export default Table;
except 只是一个实用程序,它可以获取对象的所有“自己的”属性除了第二个参数中定义的属性(作为属性名称数组)
在你告诉我使用高阶组件之前,让我提供更多细节。我以这种方式设计表格的原因是我希望人们能够使用如下所示的控件(他们可以提供自己的自定义实现)。
<Table columnDefinitions={columnDefinitions}>
<Row>
<Cell/>
<Cell/>
<Cell/>
</Row>
<CustomRow />
</Table>
即使我想放弃类似嵌入的方法 - 我不太确定如何使用高阶组件来执行此操作,因为它们似乎更适合用于更具确定性的方法。澄清一下,我们有一个用于 Card 和 CardList 的 HOC:
const CardListHOC = (Card) => CardList extends Component {
// propTypes, etc...
render() {
const { items } = this.props;
const passthroughProps = except(this.props, ['id', 'key', 'children', 'form', 'items']);
return (
{items.map(i => (<div className="card-list-wrapper"><Card {...passthroughProps} item={i}/></div>)}
);
}
}
const CardHOC = (Child) => Card extends Component {
// propTypes, etc...
render() {
const passthroughProps = except(this.props, ['id', 'key', 'children', 'form']);
return (
<div className="card-wrapper">
<Child {...passthroughProps} />
</div>
);
}
}
CardListHOC 只接受单一类型的Card,这意味着我传递给CardHOC 的Child 组件将必须为我的所有自定义类型的卡片实现所有自定义逻辑希望根据输入数据支持。
React.cloneElement 方法的问题在于,子元素首先呈现,因此在第一次通过时,子元素在“转换”之前没有来自其父级的道具 - 所以你最终会出现很多低效率和例如,我不能拥有 Row 组件,需要 columnDefinitions 作为道具,除非我像这样明确地将它们交给每个 Row:
<Table columnDefinitions={columnDefinitions}>
<Row columnDefinitions={columnDefinitions}>
<Cell/>
<Cell/>
<Cell/>
</Row columnDefinitions={columnDefinitions}>
<CustomRow columnDefinitions={columnDefinitions}/>
</Table>
有没有更好的方法来解决这个问题?也许有一种我没有看到的 HOC 方法?如果有人能指出我正确的方向,将不胜感激!
【问题讨论】:
-
嘿,马丁,在这种情况下你最终做了什么?我有同样的问题,孩子们没有新的道具。你最终选择了 HoC 路线吗?
标签: javascript reactjs transclusion