redux-form getFormState 副作用

redux-form getFormState side-effects

我的应用程序中有很多表格。我在其父减速器下为它们中的每一个创建了一个单一形式的减速器并将它们组合在一起。为了获取他们的数据,我正在使用 getFormState,在获取表单状态端一切正常,但在 redux 状态下,活动表单在所有 redux-form reducer 中重复!!! 每个 redux-form 操作适用于所有表单。

我不知道如何与您分享所有代码,以呈现整个情况。但我尝试在这里顺便分享一些代码:

这是我的注册表单:

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

注册reducer

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

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

export default signin

和过滤器形式:

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)

和我的根减速器:

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

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

P.S:当我在我的根减速器中使用单一形式的减速器而不使用 getFormState 一切正常。

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)

据我了解,您没有正确使用 redux-form(如果我错了请纠正我)。

来自getting started

Form Reducer

It serves for all of your form components, so you only have to pass it once.

Redux-form 假定在整个应用程序的状态中只有一个redux-form reducer。也就是说,form reducer 不能嵌套。

删除这个

const signin = combineReducers({
  error,
  isLogging,
  form: reduxFormReducer // <-- delete this line
})

并追加这个

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)

然后在你的组件中

SigninForm = reduxForm({
  form: 'signin',
  validate,
  getFormState: ({ form }) => form // <-- you don't need to use this line now
})(SigninForm)

来自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.

因为我们已经将 formReducer 安装在 form 键下,所以根本不需要 getFormState

这更像是一个 Redux 问题。

请参阅,在 Redux 中,all reducers 接收 all 动作。
这是一个架构决策,可以轻松应对奇怪的商业想法。

因此,如果您在代码库周围复制 redux-form reducer,那么您也在复制 all 表单的状态,因为操作类型是相同的每个表格。

getFormState 选项并不意味着可以解决 reducer 的多个实例;它意味着将你的 redux-form 状态放在其他地方,以防无法使用根级 form 密钥。

因此,解决方案是按照您在问题中所说的进行操作,并在整个应用程序中使用单一形式的 reducer。