我想清理我的JSX,将表示标记与功能标记/ DOM元素分开。
我有一个表单,它将成为我的组件层次结构的顶层。在下面将有几个输入和表单元素来构成完整的组件层次结构。还有相当数量的twitter bootstrap“cruft”主要用于控制演示。
例如:
render: function() {
return (
<form role="form" className="form-horizontal">
<div className="form-group">
<label htmlFor="homePrice">Home Price</label>
<div className="input-group input-group-lg">
<span className="input-group-addon">$</span>
<input id="homePrice"
className="form-control"
onChange={this.priceChange}
value={this.state.homePrice}
/>
</div>
</div>
<div className="form-group">
<label htmlFor="depositAmount">Deposit Amount</label>
<div className="input-group input-group-lg">
<span className="input-group-addon">$</span>
<input id="depositAmount"
className="form-control"
onChange={this.depositChange}
value={this.state.depositAmount}
/>
</div>
</div>
... snip ...
理想情况下,我会为<form>
创建单独的组件,然后为每个<inputs>
创建单独的子组件,而不使用标签标记或<div className="form-group">
和<span className="input-group-addon">
并且能够将它们插入HTML文档中的各个点并维护组件层次结构。
那么我该如何实现这一点并维护组件层次结构。更改输入中的值会影响父级最顶层组件中的状态。
感谢。
答案 0 :(得分:6)
你可以通过作曲非常有效地做到这一点。您希望自定义组件的自定义程度取决于您;通过更多道具和条件逻辑,您可以获得更多可自定义性。
我经常会先编写我可以使用的标记/ JSX wish :
render: function() {
return (
<Form horizontal>
<Input id="homePrice"
addon="$" label="Home Price"
onChange={this.priceChange}
value={this.state.homePrice} />
<Input id="depositAmount"
addon="$" label="Deposit Amount"
onChange={this.depositChange}
value={this.state.depositAmount} />
</Form>
);
}
然后,您可以根据需要开始实施组件以使其工作:
var Form = React.createClass({
render: function() {
var direction = "vertical";
if (this.props.horizontal) direction="horizontal";
return (
<form role="form" className={"form-" + direction}
onSubmit={this.props.onSubmit}>
{this.props.children}
</form>
);
}
});
var Input = React.createClass({
render: function() {
return (
<div className="form-group">
<label htmlFor={this.props.id}>{this.props.label}</label>
<div className="input-group input-group-lg">
<span className="input-group-addon">{this.props.addon}</span>
<input id={this.props.id}
className="form-control"
onChange={this.props.onChange}
value={this.props.value} />
</div>
</div>
);
}
});
通过利用this.props.children
,getDefaultProps
,扩展运算符(例如,通过<someElement {...this.props} />
将道具转移到新元素)和条件,您可以为更复杂的组件创建非常好的抽象。此外,propTypes
允许您指定组件所具有的属性,作为文档以及在开发中捕获运行时错误的方法。
您可以考虑查看React Bootstrap的源代码,了解它们如何实现复合组件以包装更复杂的Bootstrap HTML;例如,这是您使用选项卡组件编写的内容:
<TabbedArea defaultActiveKey={2}>
<TabPane eventKey={1} tab="Tab 1">TabPane 1 content</TabPane>
<TabPane eventKey={2} tab="Tab 2">TabPane 2 content</TabPane>
</TabbedArea>
如果您对描述表单的结构更感兴趣,然后让库自动创建元素,您可能会查看React Forms之类的项目:
function Person(props) {
props = props || {}
return (
<Schema name={props.name} label={props.label}>
<Property name="first" label="First name" />
<Property name="last" label="Last name" />
</Schema>
)
}
var family = (
<Schema>
<Person name="mother" label="Mother" />
<Person name="father" label="Father" />
<List name="children" label="Children">
<Person />
</List>
</Schema>
)
React.renderComponent(
<Form schema={family} />,
document.getElementById('example'))