Javascript 重新复制以前的状态已具有新的状态值
我正在尝试使用React&Redux来处理受控表单,我已经让它工作了,这样当我在输入字段中键入时,状态会按照预期更新并传递给输入组件 但是,在我的reducer中,当我控制台记录以前的状态时,表单字段的值不包含键入新字符之前的值,它已经有了新字符 我的减速机:Javascript 重新复制以前的状态已具有新的状态值,javascript,reactjs,redux,Javascript,Reactjs,Redux,我正在尝试使用React&Redux来处理受控表单,我已经让它工作了,这样当我在输入字段中键入时,状态会按照预期更新并传递给输入组件 但是,在我的reducer中,当我控制台记录以前的状态时,表单字段的值不包含键入新字符之前的值,它已经有了新字符 我的减速机: import initialState from '../state/form' const form = (prevState = initialState, action) => { switch (action.type
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
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
}
}
}
如果我的输入字段包含文本“tes”,那么我可以添加一个“t”,并按预期调度操作,但当它到达这个减缩器时,我会记录上一个状态,字段的值是“test”,而不是“tes”
我希望前一个状态有“tes”,减速器返回新状态有“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
})
}
}
}
因此,我的输入组件被传递到“control”函数。此后,我在上面的reducer代码中的console.log旁边使用了一个调试器语句,并使用Chrome的开发工具,这表明prevState完全符合我的预期(tes,而不是test)。尽管如此,console.log仍在记录“test”
看来我的redux实现还可以,只是控制台上有一些巫毒。log(prevState)=“test”,调试器允许我观察prevState变量,并显示它等于“tes”,正如预期的那样
谢谢你的回答@Pineda。在研究奇怪的控制台日志行为时(当您键入答案时),我发现变量是对对象的引用fact()-我已停止改变状态,并更新了我的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
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
方法中的错误,我似乎没有改变状态,必须解决这个问题才能使新的缩减器正常工作。我猜您是在将输入直接绑定到redux存储属性:
<input
value={this.props.name}
onChange={e => this.props.name = e.target.value}
/>
this.props.name=e.target.value}
/>
请记住,值是通过引用传递的,而不是通过值传递的,如果您直接修改存储值,那么当操作触发时,您将已经改变了redux存储状态(这是一个很大的禁忌)
我的建议是,试着找出如何在代码库中传递这种状态,您应该有如下内容:
<input
value={this.props.name}
onChange={e => dispatch({type: 'INPUT', field: 'name', value: e.target.value })}
/>
dispatch({type:'INPUT',field:'name',value:e.target.value})
/>
您正在这些行中改变状态:
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
然后使用变异状态创建新对象
解决方案:
进一步检查,当我在Chrome中使用debugger时,前面的状态显示为预期状态,因此我猜这可能是一个控制台日志问题。当我在输入标记上将一个函数传递给我的onChange处理程序时,该函数通过mapDispatchToProps传递,实际上完全按照第二个示例所示进行。此后,我使用了Chrome调试器(在console.log行的正上方使用调试器语句),与console.log不同,它按预期显示了以前的状态。看起来除了console.log之外,其他一切都正常工作!你介意用代码更新你的问题吗?