Search code examples
reactjsreduxredux-form

redux-form getFormState side-effects


I have many forms in my app. I created a single form reducer for each of them under its parent reducer and combined them. For fetching theirs data I am using getFormState, Everything is okay in fetching form states side, but in redux state active form duplicated in all redux-form reducers!!! Each redux-form action apply to all forms.

redux-form in redux-dev-tools screenshot

I don't know how I can share all code with you that I can present whole situation. but I try share some code btw here:

This is my signup form:

SigninForm = reduxForm({
  form: 'signin',
  validate,
  getFormState: ({ auth }) => auth.signin.form
})(SigninForm)

sign up reducer

import { combineReducers } from 'redux'
import { reducer as reduxFormReducer } from 'redux-form'

const signin = combineReducers({
  error,
  isLogging,
  form: reduxFormReducer
})

export default signin

and Filters form:

export default compose(
  connect(null, { ...actions }),
  reduxForm({
    form: 'filters',
    destroyOnUnmount: false,
    initialValues: {
      pool: 'either',
      open_house: false,
      listing_statuses: {
        ...activeStatuses
      },
      property_subtypes,
      minimum_sold_date: '3', // unit is month but it need to timestamp
      minimum_bedrooms: 'any',
      minimum_bathrooms: 'any',
      minimum_parking_spaces: 'any'
    },
    getFormState: ({ search }) => search.filters.form
  }),
  withHandlers({
    onSubmitHandler: ({ submitFiltersForm }) => values => {
      submitFiltersForm(values)
    }
  })
)(Filters)

and my root reducer:

const appReducer = combineReducers({
  socket,
  user,
  auth,
  brand,
  search,
  routing: routerReducer,
  listing: createNamedWrapperReducer(listing, 'LISTING')
})

export default (state, action) => appReducer(state, action)

P.S: when I use a single form reducer in my root reducer without use getFormState everything working well.

OS: Mac, node: 8.3.0, react: 15.4.2, redux: 3.6.0, redux-form: 7.0.0, browser: 60.0.3112.101 (Official Build) (64-bit)


Solution

  • This is more of a Redux issue than anything else.

    See, in Redux, all reducers receive all actions.
    This is an architectural decision that makes it simple to react to weird business ideas.

    Therefore, if you're duplicating the redux-form reducer all around your codebase, you're also duplicating the state of all forms, since the actions type is the same for every form.

    The getFormState option is not meant to work around multiple instances of the reducer; it's meant to place your redux-form state somewhere else, in case the root-level form key cannot be used.

    Therefore, the solution is to do what you say in the question, and use a single form reducer in your entire application.