react 组件 , 从reducer 获取 state 数据, 读取 state子元素 undefined

图片描述

问题出现的环境背景及自己尝试过哪些方法

目前得解决方案 : dm = {...ApplyDatas.dm}

                
           == 这是模拟实际场景取值 ==
           
             let {a,b} = {...dm}
             let c = {...a}
             let d = {...c}
             
           == 这是模拟实际场景取值 ==
           

导致得解决问题是 : 每一次取子元素都需要要解构 , 十分繁琐 ,想知道出现这种情况得原因 ? 谢谢!

相关代码

reducer

export default function doctorIn(state = initialState, action) {
state = JSON.parse(JSON.stringify(state));
switch (action.type) {

case TYPES.DOCTORIN_GET_DOCTOR_APPLY_DATAS:
  let {ResultCode, Data} = action.ApplyDatas;
  if (ResultCode === 0 &&Data) {
    state.ApplyDatas = Data;
  }

return state
}

你期待的结果是什么?实际看到的错误信息又是什么?

阅读 4.3k
2 个回答

问题还原: https://codesandbox.io/s/cool...

问题代码: ApplyDatas[0].dm
异常:TypeError: Cannot read property 'dm' of undefined
原因分析:异常导致的原因是‘访问不存在的数组元素’

流程如下:

  • 组件渲染: 这时候ApplyDatas还是初始值[], 这时候ApplyDatas[0]返回的是undefined,访问undefined值的属性肯定是不行的
  • componentDidMount: 触发异步获取数据
  • 数据获取完毕,组件重新渲染,这时候ApplyDatas才有值

解决:

使用可能不存在的数据之前,应该判断数据是否存在再进行下一步操作

其他优化点:

  1. reducer
export default function test (state = initialState, action) {
  
  state = JSON.parse(JSON.stringify(state)); // <- 这里每次reducer执行都会重新生成新的对象,而且Redux只要触发dispatch,整个reducer树都会被重新执行,所以这里可能会导致没有意义重新渲染

  switch (action.type) {
    case TYPES.TEST:
      let { ResultCode, Data } = action.ApplyDatas;

      if (ResultCode === 0 && Data) {
        state.ApplyDatas = Data;
      }

      break;
  }

  return state
}

可以使用immer或者immutable.js

  1. import action from "./store/action/index";导入路径可以精简为import action from "./store/action"

深浅复制的道理, reducer代码改成这样

case TYPES.DOCTORIN_GET_DOCTOR_APPLY_DATAS:
  let {ResultCode, Data} = action.ApplyDatas;
  if (ResultCode === 0 &&Data) {
    state.ApplyDatas = Object.assign({}, Data)
  }
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题