javascript - Redux 之前的状态已经有了新的状态值

标签 javascript reactjs redux

我正在尝试使用 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/

相关文章:

javascript - 在 Javascript 中使用键值对展平嵌套数组

javascript - Javascript 中按键事件的限制

javascript - 如何选择 CDN 来加载 Javascript 和 CSS 库?

javascript - 如何构建 Redux 组件/容器

javascript - 如何将文件图像转换为 Byte[] ReactJS?

javascript - React-Redux 中 TypeScript 中 reducer 的类型错误

javascript - Redux 中的 store.dispatch 是同步的还是异步的

reactjs - 如何使用reactjs创建大型菜单

javascript + php 不起作用

javascript - 图表加载后运行的 Highcharts 插件/扩展