我正在做一个反应原生的表单助手,我还想在表单中实现一个名为 namespace 的功能,以获得模块化结果。
一个例子:
return(
<Form
ref="configForm"
>
<Form.TextInput
name="firstName"
/>
<Form.TextInput
name="lastName"
/>
<Form.Namespace name="address">
<Form.TextInput
name="city"
/>
<Form.TextInput
name="address"
/>
<Form.TextInput
name="zip"
/>
</Form.Namespace>
</Form>
);
在这种情况下,最终结果必须是:
{
firstName: 'John',
lastName: 'Tompson',
address: {
city: 'New York',
address: '3th Av 231',
zip: '32132'
}
}
要获取字段值,我将对FormNamespace的子项进行递归映射,然后克隆拥有属性 isFormValue 的元素(此属性由为Form提供值的元素拥有,即FormNamespace和FormField ):
wrapChildren(child) {
if (!child) {
return child;
}
if (Array.isArray(child)) {
return child.map((c) => this.wrapChildren(c));
}
if (child.type.isFormValue) {
let ref = child.ref || child.props.name;
child = React.cloneElement(child, {
ref: ref,
style: {borderWidth: 1, borderColor: 'red'}, // for debug
onUpdateValue: this.handleFieldChange.bind(this, ref),
});
}
if (child.props.children && !child.type.isFormStopableWrapper) {
child.props.children = this.wrapChildren(child.props.children);
}
return child;
}
render() {
let childs = this.wrapChildren(this.props.children);
debugger;
return(
<View style={this.props.style}>
{childs}
</View>
);
};
所有逻辑都在FormNamespace组件中,实际上,Form组件只呈现FormNamespace:
render() {
return(
<Namespace
ref="formData"
name="mainNamespace"
style={[styles.form, this.props.style]}
onUpdateValue={(data) => this._handleUpdateData(data)}
>
{this.props.children}
</Namespace>
);
};
Form组件在第一个深度上正常工作,但是当必须克隆FormNamespace元素时,由于某些问题,它不能正常工作。
调试,我检查了 React.cloneElement 是否应用于FormNamespace但是在最终渲染中,FormNamespace永远不会被引用(也不应用边框样式),这与FormField运行良好不同。 / p>
我不知道这里有什么问题,最终呈现的FormNamespace没有定义 onUpdateValue 道具。目标是将FormNamespace视为Form的简单值提供者(如字段组件),并管理他们自己的孩子。
完整的组件代码在这里: