Reputation: 43
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.
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)
Upvotes: 2
Views: 2241
Reputation: 41440
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.
Upvotes: 0
Reputation: 2261
From what I understand, you do not use redux-form properly (correct me if I'm wrong).
From getting started:
Form Reducer
It serves for all of your form components, so you only have to pass it once.
Redux-form assumes that there's only one redux-form reducer in your entire application's state. In other words, form reducer shall not be nested.
Remove this
const signin = combineReducers({
error,
isLogging,
form: reduxFormReducer // <-- delete this line
})
and append this
import { reducer as reduxFormReducer } from 'redux-form'
...
const appReducer = combineReducers({
socket,
user,
auth,
brand,
search,
routing: routerReducer,
listing: createNamedWrapperReducer(listing, 'LISTING'),
form: reduxFormReducer // <-- that's all there is to it
})
export default (state, action) => appReducer(state, action)
then in your component
SigninForm = reduxForm({
form: 'signin',
validate,
getFormState: ({ form }) => form // <-- you don't need to use this line now
})(SigninForm)
From docs:
getFormState : Function [optional]
A function that takes the entire Redux state and returns the state slice which corresponds to where the redux-form reducer was mounted. This functionality is rarely needed, and defaults to assuming that the reducer is mounted under the form key.
Since we've mounted the formReducer under the form key, no need to have getFormState
there at all.
Upvotes: 2