I have a React/Redux app and am trying to figure out the best way to build a proper onChange event for a controlled input field. React onChange fires onInput so I made an onBlur event to fire only when the user leaves the field. The only way I could think to implement my "onChange" code was to set the input value in React state. Then I could compare the old state to the new state that comes from the Redux store. However I don't think this is an ideal solution since the value has to be stored in both React state and the Redux store. Is there a way to implement a proper onChange for a component while only having the value stored in the Redux store?
/************Parent component************/
const mapStateToProps = (state) => {
const fieldName = 'fieldName';
const fieldData = formFieldSelector(fieldName)(state);
return {
fieldName,
label: 'fieldName',
value: fieldData.value
}
};
const mapDispatchToProps = (dispatch) => ({
onChangeEvent(fieldName, value) {
dispatch(updateFieldValue(...))
},
onBlurEvent(fieldName, value) {
dispatch(validateFormField(...)
},
});
const MyFieldInput = connect(
mapStateToProps,
mapDispatchToProps
)(GenericInput);
/************Child Component************/
export default class GenericInput extends React.Component {
constructor(props) {
super(props);
this.state = {
value: ''
};
}
handleOnBlur (e) {
const value = e.target.value;
if(this.props.onBlurEvent && (value !== this.state.value)) {
this.props.onBlurEvent(this.props.fieldName, value)
}
this.setState({value});
}
render () {
const {
fieldName,
label = '',
value = '',
inputType = 'text',
onChangeEvent,
onBlurEvent,
} = this.props;
const onChange = onChangeEvent ? (e) => onChangeEvent(fieldName, e.target.value) : function () {};
return (
<div>
<label>{label}
<input name={fieldName} type={inputType} value={value} onChange={onChange} onBlur={this.handleOnBlur.bind(this)} />
</label>
</div>
)
}
}