如何使用 react-redux-forms 和自定义 reducer 避免奇怪的表单对象嵌套
How to avoid weird nesting of forms objects using react-redux-forms and custom reducer
我正在尝试使用 react-redux-form 来管理我的表单,但是在我设置其他 reducer 时遇到了如何将其注入商店的问题。
我的店铺创建如下
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>
当我启动我的应用程序并检查状态时,我看到处于以下状态的表单:
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
}
我的状态看起来一样
state:
forms:
login:
username: ''
password: ''
forms:
$form:
focus: false
# ... etc
login:
$form:
focus: false
# ... etc
username: ''
password: ''
但表格本身不再有效。
我真正想要的是一个看起来像
的state
state:
forms:
login:
$form:
focus: false
# ... etc
username: ''
password: ''
没有所有奇怪的嵌套重复。
最终在我的表单组件中,我需要能够访问表单的 errors
对象,我宁愿不必深入研究 state.forms.forms.login.$form.errors
因为当我应该能够查看 state.forms.login.$form.errors
.
我应该如何将 combinedForms
与其他减速器一起注入到我的 combinedReducer
中?
在您给出的示例中,state.forms.login
将包含模型值。
state.forms.forms.login
将包含有关 form/field 状态的 react-redux-form
特定信息。
这是 react-redux-form
的预期功能。您的困惑可能源于使用 'forms'
作为组合表单的模型名称。
我正在尝试使用 react-redux-form 来管理我的表单,但是在我设置其他 reducer 时遇到了如何将其注入商店的问题。
我的店铺创建如下
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>
当我启动我的应用程序并检查状态时,我看到处于以下状态的表单:
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
}
我的状态看起来一样
state:
forms:
login:
username: ''
password: ''
forms:
$form:
focus: false
# ... etc
login:
$form:
focus: false
# ... etc
username: ''
password: ''
但表格本身不再有效。
我真正想要的是一个看起来像
的state
state:
forms:
login:
$form:
focus: false
# ... etc
username: ''
password: ''
没有所有奇怪的嵌套重复。
最终在我的表单组件中,我需要能够访问表单的 errors
对象,我宁愿不必深入研究 state.forms.forms.login.$form.errors
因为当我应该能够查看 state.forms.login.$form.errors
.
我应该如何将 combinedForms
与其他减速器一起注入到我的 combinedReducer
中?
在您给出的示例中,state.forms.login
将包含模型值。
state.forms.forms.login
将包含有关 form/field 状态的 react-redux-form
特定信息。
这是 react-redux-form
的预期功能。您的困惑可能源于使用 'forms'
作为组合表单的模型名称。