ReactJS:在模糊时保存输入值,而不是在每个击键时保存输入值

我已经创建了一个反应视图,比如MyView,它有两个文本输入,它们的初始值将由Parent Read从数据库中传递。

我还希望将更改的值保存回数据库。因此,还会为该视图传递一个相同的回调函数。

考虑到数据库保存操作很繁重,不应频繁执行。因此,我决定监听onBlur事件,而不是输入框上的onChange事件,因为在每次击键时都会调用onChange

第一种方法:

class MyView extends React.Component {
    constructor(props) {
        super(props);
    }

    render() {
        return (
            <div>
              <input type="url" value={this.props.values.A}
                   onBlur={(evt)=>{this.props.saveValue('A', evt.target.value)}} />
              <input type="url" value={this.props.values.B}
                   onBlur={(evt)=>{this.props.saveValue('B', evt.target.value)}} />         

              <button type="button" onClick={this.props.resetValues}>Reset</button>
            </div>
        );
     }
}
但是,这并不起作用,因为React强制控制输入(具有value属性)总是伴随onChange侦听器。

第二种方法:

因此,我尝试将这些输入设置为uncontrolled。也就是说,使用defaultValue而不是value属性。

<input type="url" defaultValue={this.props.values.A}
       onBlur={(evt)=>{this.props.saveValue('A', evt.target.value)}} />

但这也不起作用,因为单击Reset/Clear按钮时,虽然视图被重新渲染,但defaultValue在创建视图后不会更新。

第三种方法:

因此,我最终添加了一个onChange监听程序,但不执行任何操作。

<input type="url" value={this.props.values.A}
       onChange={()=>{console.log('do nothing')}
       onBlur={(evt)=>{this.props.saveValue('A', evt.target.value)}} />

同样,这不起作用,因为在调用onChange之后重新呈现视图,并且由于props中没有反映值,value似乎在每次击键时都重置回初始。

第四种方法:

我上一次尝试是维护stateIn组件并从状态读取值,并且每onChange将值保存回状态。这在很大程度上是有效的,但只要道具有外部更改并重新呈现视图,state就不会更新。因此,我添加了一个getDerivedStateFromProps函数来查看:

static getDerivedStateFromProps(props, state) {
    return props.values;
}

现在,这又不起作用了。原因是,即使我临时将值保存到STATE,并且在属性中将状态重置为初始值,也会调用此函数。

某个ReactJS专家可以帮助我解决我的用例吗?


解决方案

根据对Liren Yeo解决方案的评论,我将在componentDidUpdate上处理道具-状态协调,其中您将获得旧的stateprops。这样,您就可以确定this.props是如何更新的,并采取相应的措施。当props中的值与stateoldProps不匹配时,更新是外部的,您应该覆盖状态中未保存的更改。

代码应如下所示

componentDidUpdate(prevProps) {

if (this.props.values !== prevProps.values && this.props.values !== this.state.values) {
  this.setState({values:this.props.values});
   }
}
如果采用此方法,还可以保留输入uncontrolled并通过引用更新其值。这解决了controlled输入的一些不可靠性问题,例如,当您键入小数逗号时,type='number'返回undefined作为其值。您仍然需要存储onChange值,但只需保存onBlur并在componentDidUpdate中处理状态属性对账

相关文章