我正在尝试使用 React 和 Redux 来掌握受控表单,并且我已经开始工作,因此当我在输入字段中输入时,状态正在更新并按预期向下传递到输入组件.
但是,在我的 reducer 中,当我控制台记录以前的状态时,表单字段的值不包含键入新字符之前的值,它已经具有新字符。
我的 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”并按预期分派(dispatch)操作,但是当它到达这个 reducer 时,我控制台记录之前的状态并且该字段的值为“测试”,而不是“测试”。
我希望之前的状态有“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 的回答。在查看奇怪的控制台日志行为时(当你输入你的答案时)我遇到了变量是对对象的引用事实(here) - 我已经停止改变我的状态,并更新了我的 reducer :
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
方法中的错误,我似乎一直在逃避改变状态,必须解决这个问题才能使新的 reducer 正常工作。
最佳答案
你正在改变这些行中的状态:
let newFields = prevState.fields
newFields[action.field].value = action.value
// it's also worth noting that you're trying to access a 'value'
// property on newFields[action.field], which doesn't look
// like it'll exist
可以重写为:
prevState.fields[action.field] = action value
然后您使用您的变异状态创建一个新对象。
解决方案:
import initialState from '../state/form'
const form = (prevState = initialState, action) => {
switch (action.type) {
case 'INPUT': {
console.log(prevState);
// You create a new un-mutated state here
// With a property 'fields' which is an object
// with property name whose value is action.field
// which has the value action.value assigned to it
const newState = Object.assign({}, prevState, {
fields: { [action.field]: action.value}
});
return
}
default: {
return prevState
}
}
}
export default form
关于javascript - Redux 之前的状态已经有了新的状态值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41921791/