Javascript React-存储和显示格式不同的双向绑定文本输入

Javascript React-存储和显示格式不同的双向绑定文本输入,javascript,reactjs,2-way-object-databinding,Javascript,Reactjs,2 Way Object Databinding,我想要一个文本输入列表,该列表与后端中的值列表同步。因此,在其中键入会更新值,并更新反映在文本输入中的值 这是典型的双向绑定情况,如下所示: class BoundInput extends Component { constructor(props) { super(props); this.state = {textVal: ''}; } handleChange = evt => this.setState({textVal

我想要一个文本输入列表,该列表与后端中的值列表同步。因此,在其中键入会更新值,并更新反映在文本输入中的值

这是典型的双向绑定情况,如下所示:

class BoundInput extends Component {

    constructor(props) {
        super(props);
        this.state = {textVal: ''};
    }

    handleChange = evt => this.setState({textVal: evt.target.value});

    render() {
        return <input type="text"
                      value={this.state.textVal}
                      onChange={this.handleChange} />
    }

}
类边界输入扩展组件{
建造师(道具){
超级(道具);
this.state={textVal:''};
}
handleChange=evt=>this.setState({textVal:evt.target.value});
render(){
回来
}
}
但是我希望存储的值不是用户输入的值,而是cm的转换。加入

不幸的是,转换和再转换并不是很完美

例如,键入
'2.
会立即转换回
'2'
,因此如果您想键入小数点或更高的值,您会被卡住

我希望能够让存储值更新输入显示,除非输入是活动的,在这种情况下,它应该只从输入更新存储值

因此,我有一个布尔值,允许我有条件地将
传递给文本输入,这样打字机就可以不受阻碍地输入,并且只有在它们离开焦点时,显示才会更新为等效的表示形式(例如,
'1.
突然变成
'1'
'1.0'
),这很好

我尝试了这个方法,但是我得到了一个错误,输入组件在其整个生命周期中必须是受控的,或者是不受控的。不要像我那样把它调大

对整体战略有什么建议,或者绕过这个关于受控与非受控的特别警告

在从传递<代码>值切换到不传递<代码>值之前,是否可以终止并重新装载输入组件


我做了一件很难看的事情,就是复制我的输入组件(我称之为
NiceInput
),当它不活动时,我交换重复的
NiceInput2
。这是可行的,但必须有一种比复制组件更不荒谬的方法:D

您可以在不断“生成”文本值的状态下存储第二个变量,然后在取消选择时,将“生成”文本值指定给可见文本值

您仍然使用“onDeselect”,但您可以节省制作第二个组件的时间

class BoundInput extends Component {

    constructor(props) {
        super(props);
        this.state = {textVal: '', niceVal: ''};
    }

    handleChange = evt => {
        this.setState({
            textVal: evt.target.value,
            niceVal: makeNice(evt.target.value),
        });    
    }

    handleDeselect = () => {this.setState({textVal: this.state.niceVal});}

    render() {
        return <input type="text"
                      value={this.state.textVal}
                      onChange={this.handleChange} 
                      onDeselect={this.handleDeselect}
                />
    }

}
类边界输入扩展组件{
建造师(道具){
超级(道具);
this.state={textVal:'',niceVal:''};
}
handleChange=evt=>{
这是我的国家({
textVal:evt.target.value,
niceVal:makeNice(evt.target.value),
});    
}
handleDeselect=()=>{this.setState({textVal:this.state.niceVal});}
render(){
回来
}
}

我最后做的是创建一个
非受控输入
组件,在将其余的道具转发到
输入之前从道具中删除

const UncontrolledInput = ({ value, ...otherProps }) => {
  return (
    <input {...otherProps} />
  )
}
两项重要补充:

1) 至少以父级尝试传递的内容开始输入值

2) 一个选项,用于在输入挂载后对其进行聚焦(因为当您希望聚焦输入时,很可能会使用此非受控等效项替换输入,但此组件替换会使其最初不聚焦)

我通过以下方式实现了这些目标:

1)
defaultValue

2)
ref

const UncontrolledInput = ({ value, focusOnMount, ...otherProps }) => {
  otherProps.defaultValue = value;
  if (focusOnMount) {
    otherProps.ref = input => input && input.focus();
  }
  return (
    <input {...otherProps} />
  )
}