I'm using React Redux, Redux-form and reselect library (https://github.com/reactjs/reselect).
I have a component with two Fields: quota
and amount
. I want to update the amount
field based on quota
field. For the calculation of amount
I'm using a selector
with reselect
.
I want to update the amount
field only if is valid quota
.
I have tried without success onChange
field props because it's executed before the selector.
The best solution I've found is to use onChange
reduxForm() property because it's executed after the selector but I can't run after validation.
This is my code:
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { makeModalData } from '../selectors/Modal';
import { change, Field, reduxForm, formValueSelector } from 'redux-form';
const validate = values => {
const errors = {};
if (values.quota <= 1) {
errors.quota = "The quota must be greater than 1";
} else if (values.quota > 50) {
errors.quota = "The quota must be less than 50";
}
return errors;
}
const updateForm = (values, dispatch, props, previousValues) => {
if (props.valid) { // this not work because it shows the previous state of validation
if (values.quota !== previousValues.quota) {
let amount = props.modal_data.amount; // data with reselect
dispatch(change('modal', 'amount', amount));
}
}
}
class Modal extends Component {
constructor(props) {
super(props);
}
renderField = ({ input, label, type, meta: { touched, error } }) => (
<div>
<input {...input} type={type} placeholder={label} />
{touched && error && <span>{error}</span>}
</div>
)
// this not work because is executed before selector
/*
updateAmount(event) {
let amount = this.props.modal_data.amount;
this.props.dispatch(change('modal', 'amount', amount));
}*/
render() {
return (
<label>Quota</label>
<Field
name="quota"
component={this.renderField}
type="number"
label="Quota"
/*onChange={this.updateAmount.bind(this)} */
/>
<label>Amount</label>
<Field
name="amount"
component={this.renderField}
type="number"
label="Amount"
/>
)
}
}
const makeMapStateToProps = () => {
const modal_data = makeModalData(); // selector
const mapStateToProps = state => {
let my_modal_data = modal_data(state, state.modal)
return {
initialValues: {
quota: state.modal.quota,
amount: state.modal.amount,
},
}
}
return mapStateToProps;
}
Modal = reduxForm({
form: 'modal',
enableReinitialize: true,
touchOnChange: true,
validate,
onChange: updateForm
},makeMapStateToProps)(Modal);
Modal = connect(
makeMapStateToProps,
mapDispatchToProps
)(Modal);
export default Modal;
quota
field that watches for changes to theinput.value
prop and dispatch the change toamount
there when there is nometa.error
– Peter Riesz