我创建了一个 React View,比如说MyView
,它有 2 个文本输入,其初始值将由从数据库读取的父级传递。
我还希望将更改的值保存回数据库。因此,视图也传递了一个相同的回调函数。
考虑到数据库保存操作很繁重,您不应该经常这样做。因此,我决定收听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
. 也就是说,value
使用 代替属性defaultValue
。
<input type="url" defaultValue={this.props.values.A}
onBlur={(evt)=>{this.props.saveValue('A', evt.target.value)}} />
但这也不起作用,因为单击重置/清除按钮,虽然视图被重新渲染,但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
似乎在每次击键时都重置回初始值。
第四种方法:
最后我尝试的是维护一个state
组件并从状态中读取值,并在每次onChange
将值保存回状态时。这在很大程度上是有效的,但是每当道具发生外部更改并且视图被重新渲染时,state
都不会更新。所以,我添加了一个getDerivedStateFromProps
功能来查看:
static getDerivedStateFromProps(props, state) {
return props.values;
}
现在,这又不起作用了。原因是即使我暂时将值保存到状态并且状态已重置为道具中的初始值,也会调用此函数。
一些 ReactJS 专家可以帮助我解决我的用例吗?