javascript - 如何使用react-redux-forms和自定义reducer避免表单对象的奇怪嵌套

标签 javascript reactjs redux react-redux-form

我正在尝试使用 react-redux-form管理我的表单,但在设置其他 reducer 时遇到如何将其注入(inject)商店的问题。

我的商店创建如下

import { createStore, applyMiddleware, compose } from 'redux'

import { browserHistory }   from 'react-router'
import { routerMiddleware } from 'react-router-redux'

import { makeRootReducer }  from '../reducer'

const makeStore = (initialState = {}) => {
  const middleware = [
    routerMiddleware(browserHistory)
    // other middlewares
  ]

  const store = createStore(
    makeRootReducer(),
    initialState,
    compose(
      applyMiddleware(...middleware)
    )
  )
  store.asyncReducers = {}

  return store
}

module.exports = makeStore

我的根reducer如下

import { combineReducers } from 'redux'
import { routerReducer }   from 'react-router-redux'
import { combineForms }    from 'react-redux-form'

import { initialLoginState } from './components/forms/login'

const makeRootReducer = (asyncReducers) => {
  const customReducers = {
    // other of my own imported reducers
  }

  const forms = {
    login: initialLoginState
  }

  const allReducers = {
    ...customReducers,
    forms: combineForms(forms, 'forms'),
    routing: routerReducer,
    ...asyncReducers
  }

  return combineReducers(allReducers)
}

// mutate the store just this once.
const injectReducer = (store, { key, reducer }) => {
  store.asyncReducers[key] = reducer // eslint-disable-line no-param-reassign
  store.replaceReducer(makeRootReducer(store.asyncReducers))
}

module.exports = {
  makeRootReducer,
  injectReducer
}

我的表格是这样的

  <Form model='forms.login' onSubmit={login => console.debug(login)}>
    <label>Email</label>
    <Control.text model='.username' />
    <label>Password</label>
    <Control type='password' model='.password' />
    <button type="submit">Login</button>
  </Form>

当我启动应用程序并检查状态时,我看到状态中的表单如下:

first state example

state:
  forms:
    login:
      username: ''
      password: ''
    forms:
      $form:
        focus: false
        # ... etc
      login:
        $form:
          focus: false
          # ... etc
        username: ''
        password: ''

表单的行为符合预期。

如果我更改 allreducers 删除第二个 'forms' 参数,因此它看起来像这样:

  const allReducers = {
    ...customReducers,
    forms: combineForms(forms),
    routing: routerReducer,
    ...asyncReducers
  }

我的状态看起来一样

second state example

state:
  forms:
    login:
      username: ''
      password: ''
    forms:
      $form:
        focus: false
        # ... etc
      login:
        $form:
          focus: false
          # ... etc
        username: ''
        password: ''

但表单本身不再起作用。

我真正想要的是一个看起来像这样的状态

state:
  forms:
    login:
      $form:
        focus: false
        # ... etc
      username: ''
      password: ''

没有所有奇怪的嵌套重复。

最终,在我的表单组件中,我需要能够访问表单的 errors 对象,并且我不想深入研究 state.forms.forms.login.$form。错误,因为当我应该能够查看state.forms.login.$form.errors时,这对我来说似乎很糟糕。

我应该如何将 combinedForms 与其他 reducer 一起注入(inject)到我的 combinedReducer 中?

最佳答案

在您给出的示例中,state.forms.login 将包含模型值。 state.forms.forms.login 将包含有关表单/字段状态的 react-redux-form 特定信息。

这是react-redux-form的预期功能。您的困惑可能源于使用'forms'作为组合表单的模型名称。

关于javascript - 如何使用react-redux-forms和自定义reducer避免表单对象的奇怪嵌套,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42833165/

相关文章:

javascript - 节点创建的 DOM 回调

javascript - 获取 '' 不变违规 : Native module cannot be null .'' when I run the test

react-native - withNavigation 只能用于导航器的 View 层次结构

reactjs - 在 Redux 商店中存储凭证是一个很好的做法吗?

javascript - nuxt 身份验证 : Google provider return invalid_request

javascript - Ruby on Rails : How to TDD with javascript:void(0) route

javascript - Node.js 会继续支持旧版本的 Node 模块吗

node.js - `npm start` 给出生命周期错误并以状态 9 退出

reactjs - react native 动画动画工作一次

javascript - 这种模式适合相当小的 JS 应用程序吗?