【问题标题】:redux-form getFormState side-effectsredux-form getFormState 副作用
【发布时间】:2017-08-26 08:38:19
【问题描述】:

我的应用中有很多表单。我在其父级减速器下为它们中的每一个创建了一个单一的表单减速器并将它们组合起来。为了获取他们的数据,我正在使用getFormState,在获取表单状态方面一切正常,但是在所有 redux-form reducer 中重复的 redux 状态活动形式!!! 每个 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)

【问题讨论】:

  • 请分享代码相关代码
  • @RIYAJKHAN 我做到了。

标签: reactjs redux redux-form


【解决方案1】:

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

来自getting started

表单缩减器

它适用于您的所有表单组件,因此您只需传递它 一次。

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 : 函数 [可选]

获取整个 Redux 状态并返回状态的函数 slice 对应于 redux-form reducer 的安装位置。 这个功能很少需要,并且默认假设 减速器安装在表单键下方。

由于我们已经在表单键下安装了formReducer,所以根本不需要getFormState

【讨论】:

  • @patrik-prevuznk 我知道这一点,我在我的问题中解释说,当我在表单属性下的根减速器中添加 reduxform 减速器时没有任何问题。我有问题当我在搜索和身份验证等其他顶级减速器下定义 redux-form 时,使用嵌套减速器。
  • @Naser,我认为问题出在getFormState:它是用来获取数据的
  • 那么,为什么要在其他顶级reducer下嵌套form呢?
  • 谢谢,我没有在文档中注意到整个应用程序应该有一个表单减速器,它帮助我简化了减速器。
【解决方案2】:

这更像是一个 Redux 问题。

请看,在 Redux 中,所有个 reducer 接收 所有个操作。
这是一个架构决策,可以很容易地对奇怪的商业想法做出反应。

因此,如果您在整个代码库中复制 redux-form reducer,您也复制了 all 表单的状态,因为 every 的操作类型相同 表格。

getFormState 选项并不适用于 reducer 的多个实例;它的目的是将您的 redux-form 状态放在其他地方,以防无法使用根级 form 键。

因此,解决方案是按照您在问题中所说的去做,并在整个应用程序中使用单个表单缩减器。

【讨论】:

    猜你喜欢
    • 2018-05-08
    • 2018-05-29
    • 1970-01-01
    • 2018-03-14
    • 1970-01-01
    • 2017-01-14
    • 2017-03-25
    • 1970-01-01
    • 2018-01-14
    相关资源
    最近更新 更多