I have created a React View, say MyView, which has 2 text inputs whose initial values will be passed by parent read from a DB.
I also want the changed values to be saved back to DB. So, the view is also passed a callback function for the same.
Consider that DB save operation is heavy and you should not do it very frequently. So, I decided to listen to onBlur events instead of onChange events on the input boxes as onChange is invoked on every key stroke.
First Approach:
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>
);
}
}
However, this does not work as React enforces a controlled input (with value attribute) always to be accompanied by an onChange listener.
Second Approach:
So, I tried to make these inputs as uncontrolled. That is, instead of value attribute, used defaultValue.
<input type="url" defaultValue={this.props.values.A}
onBlur={(evt)=>{this.props.saveValue('A', evt.target.value)}} />
But this also did not work as on reset/clear button click, although the view was made to re-render but defaultValue does not update once view is created.
Third Approach:
So, I finally added an onChange listener but as no-op.
<input type="url" value={this.props.values.A}
onChange={()=>{console.log('do nothing')}
onBlur={(evt)=>{this.props.saveValue('A', evt.target.value)}} />
Again, this did not work as the view re-renders after calling onChange and since value is not reflected in props yet, value seems to reset back to initial on every key stroke.
Fourth Approach:
Last I tried was to maintain a state in component and read value from state and on every onChange save the value back to state. This worked to most extent but whenever there were external changes to props and the view was re-rendered, state did not update. So, I added a getDerivedStateFromProps function to view:
static getDerivedStateFromProps(props, state) {
return props.values;
}
Now, this again did not work. Reason being that this function is invoked even if I temporarily save values to state and the state was reset to initial values in props.
Can some ReactJS expert help me with my use-case?