2015-12-21 52 views
2

当所有模型字段都是标量并且与输入1:1映射时,可以很容易地创建一个受控输入的表单。受控输入和复合类型

但是如果该字段是复合的呢?对于确定性让我们说,该模型具有coordinates性质,看起来像这样:

{ 
    ... 
    coordinates: { 
     x: 10, 
     y: 20, 
     projection: 1234 
    } 
} 

而且我们说的形式存在,用于管理该领域的单一文本输入。

因此,我可以很容易地初始化带有序列化点的输入为(x, y)(投影无法修改)。

但是,由于受控输入会在每次更改时改变模型 - 出现这样的问题:如果输入不包含有效的序列化点,该怎么办?像foobar

该字符串不能反序列化回x-y-projection,因为受控元素触发了模型更改和重新呈现,所以不清楚在哪里存储此中间无效结果。

所以我的问题 - 如何在这种情况下表示数据,以及它如何通常在您的应用程序中解决?

回答

1

您使用状态。一旦输入组件有一个有效值,它应该只向其父节点发送有关值更改的消息。您可以设置子组件状态,以跟踪变化的无效的值,然后在完成后向父设备发送消息。它可能看起来像这样。 (这里是一个工作codepen,注意如何在标签不一样,如果你键入字母输入更改)

class PointInput extends React.Component { 
    constructor(props, ...args) { 
    super(props, ...args); 
    this.state = { x: props.x, y: props.y}; 
    } 
    update = (newValue) => { 
    newValue = Object.assign({}, this.state, newValue); 
    this.setState(newValue); 
    if (Number.isNaN(+newValue.x) || Number.isNaN(+newValue.y)) return; 
    this.props.onChange(newValue); 
    } 
    render() { 
    return (
     <div> 
     {'X: '}<input value={this.state.x} onChange={(e) => this.update({x: e.target.value})} /> 
     {'Y: '}<input value={this.state.y} onChange={(e) => this.update({y: e.target.value})} /> 
     </div> 
    ); 
    } 
} 
+1

我有同样的想法,甚至尽管它看起来像“解决方案”存在“的问题“有了它:受控因素带来的好处是,你现在看到的是什么现货是无效的了。因此,如果用户点击“提交”不是来自将要发送的输入字段的数据,而是可能不直观的“最后有效数据”。这可以通过额外的客户端验证来解决(尽管这可能会非常棘手,因为现在它不仅是商店,而且还应该验证内部组件的状态) – zerkms

+0

您开始引入其他问题,这些问题必然会改变行为。有几种方法可以解决这个问题。验证可以在商店级完成,但也可以由组件完成(可能通过在值无效时返回“null”值,以使商店验证失败)。如果商店真的确实需要价值,那么您可以将输入与解析的值分开。该商店将包含一个原始输入的值,一个用于序列化的点(原始输入有效后更新)。然后输入总是报告,并忽略有效性。 – Tyrsius

0

不依赖于你如何保存你的数据(状态/无状态),你可以在状态/存储中存储无效数据,并在组件的渲染方法中处理它。

任何附加条款可能导致更尖锐和完整的答案