【发布时间】:2017-01-29 14:10:00
【问题描述】:
我正在尝试使用 React 和 Redux 来处理受控表单,并且我已经让它工作了,因此当我在输入字段中输入时,状态正在更新并按预期传递到输入组件.
但是,在我的 reducer 中,当我在控制台记录之前的状态时,表单字段的值不包含输入新字符之前的值,它已经有了新字符。
我的减速机:
import initialState from '../state/form'
const form = (prevState = initialState, action) => {
switch (action.type) {
case 'INPUT': {
console.log(prevState) // the value here equals "test"
debugger // the value here equals "tes"
let newFields = prevState.fields
newFields[action.field].value = action.value
return Object.assign({}, prevState, {
fields: newFields
})
}
default: {
return prevState
}
}
}
export default form
如果我的输入字段包含文本“tes”,然后我可以添加一个“t”并且按预期调度操作,但是当它到达这个减速器时,我控制台记录以前的状态并且该字段的值是“测试”,而不是“测试”。
我希望之前的状态有“tes”,reducer 用“test”返回新的状态。
在我的容器中,我有:
const dispatchToProps = (dispatch, ownProps) => {
return {
control: (e) => {
dispatch({
type: 'INPUT',
form: ownProps.formId,
field: e.target.getAttribute('name'),
value: e.target.value
})
},
clear: () => {
dispatch({
type: 'CLEAR_FORM',
form: ownProps.formId
})
}
}
}
所以我的输入组件正在传递“控制”功能。从那以后,我在上面的 reducer 代码中的 console.log 旁边使用了一个调试器语句,并使用 Chrome 的开发工具,这显示 prevState 完全符合我的预期(测试,而不是测试)。但是,console.log 仍在记录“测试”!
所以看来我的 redux 实现可能没问题,在 console.log(prevState) == "test" 的某个地方只有一些巫术,调试器允许我观察 prevState 变量并显示它等于 "tes",如期待!
感谢您的回答@Pineda。在查看奇怪的控制台日志行为时(当您输入答案时)我遇到了 variables are references to objects 事实 (here) - 我已经停止改变我的状态,并更新了我的减速器:
import initialState from '../state/form'
const form = (state = initialState, action) => {
switch (action.type) {
case 'INPUT': {
return Object.assign({}, state, {
fields: {
...state.fields,
[action.field]: {
...state.fields[action.field],
value: action.value
}
}
})
}
default: {
return state
}
}
}
现在一切正常。由于我的 mapStateToProps 方法中的错误,我可能似乎已经摆脱了变异状态,必须解决这个问题才能使新的减速器正常工作。
【问题讨论】:
-
进一步检查,当我在 Chrome 中使用调试器时,之前的状态会按预期显示,所以我猜这可能是控制台日志问题
标签: javascript reactjs redux