Hendrik
Hendrik

Reputation: 1525

Redux-form: Set form values from state

I have a redux-form called addContactForm. This form listens to some actions in my application through a plugin. See code below for an illustration:

/reducers/index.js

import { combineReducers } from 'redux';
import { reducer as reduxFormReducer } from 'redux-form'
import AddContactFormPlugin from './add-contact-form-plugin';

const rootReducer = combineReducers({
    form:        reduxFormReducer.plugin({
        addContactForm: AddContactFormPlugin
    })
});

export default rootReducer;

/reducers/add-contact-form-plugin.js

import { SET_CURRENT_CONTACT, CLEAR_CURRENT_CONTACT } from '../constants';
export default function (state, {type, payload}) {
    switch (type) {
        case SET_CURRENT_CONTACT:
            // !!! MY PROBLEM IS ON THE NEXT LINE
            return {...state, values: { ...payload }};
        case CLEAR_CURRENT_CONTACT:
            return {...state, values: getEmptyValues()};
        default:
            return state;
    }
}

function getEmptyValues() {
    return {
        firstName: '',
        lastName: '',
        phone: ''
    }
}

To clarify what is happening here: when the action with type SET_CURRENT_CONTACT flows into this reducer, I set the form values to those of the contact person that was selected by the user. This part works correctly.

HOWEVER, the form is now marked as !pristine && dirty. As a result, my submit button is not disabled, which it actually should be until the user decides to make any changes.

So my question is: how can I update the form state so that it is marked as pristine?

(or invalid I guess, but pristine feels like a better option)

I have tried simply setting the value in the state object but this is not doing anything: return {...state, values: { ...payload }, pristine: true };

If I am using the wrong approach here, I would also appreciate being pointed into the right direction.

Upvotes: 2

Views: 1015

Answers (1)

Hendrik
Hendrik

Reputation: 1525

OK, so I found an 'answer' now. I basically just followed along with this example on the redux-form website Initialize values from state. However it did not work out of the box for me. I had to make two notable changes:

  1. In my call to reduxForm I had to pass a parameter enableReinitialize: true. Now updating values after selecting a contact worked correctly and the form was reset to pristine. But my validation function broke...
  2. That turned out to be because at some point in time the values to be validated were undefined. To circumvent this I added a clause to exit early from the validation function: if (!values) {return {};}

So now everything works as expected, event though change nr. 2 feels a bit wrong...

Below the most relevant part of my working code (in the redux-form connected component)

const getInitialValues = (currContact) => {
    if (currContact) {
        const { firstName, lastName, phone } = currContact;
        return { firstName, lastName, phone };
    }
    return { firstName: '', lastName: '', phone: ''};
}

const reduxConnectedForm = reduxForm({
    form: 'addContactForm',
    validate,
    enableReinitialize: true
})(AddContactForm);


function mapStateToProps (state) {
    return {
        initialValues: getInitialValues(state.currContact)
    };
}

const connectedForm = connect(
    mapStateToProps, 
)(reduxConnectedForm);
export default connectedForm;

Upvotes: 4

Related Questions