【问题标题】:Redux Reducer - Adding new data to nested stateRedux Reducer - 将新数据添加到嵌套状态
【发布时间】:2017-11-11 08:54:26
【问题描述】:

我在reducer中保存了以下客户端状态的json文件。现在,当我通过 ajax 添加新便笺时,我正在调用 NEW_NOTE_SUCCESS 减速器,它假设将新便笺添加到现有便笺数组中。

export default function clientProfile(state={}, action) {

    switch(action.type) {


        case NEW_NOTE_SUCCESS:
            console.log(action.payload);
            return { ...state, notes: [...state.notes, action.payload] }

        default:
            return state;
    }

}

但是,在我完成上述操作后,this.props.client.notes 将只有我添加的新注释,而不是旧注释。

我应该怎么做才能将新笔记“推送”到数组中,这样我每次添加新笔记时都不需要重新发送笔记json文件。

PS:action.payload 包含以下 json。

{
            "noteId": "10000000",
            "customerId": "34",
            "createdBy": "1",
            "created": "1510316194",
            "note": "ADDED A NEW NOTE. NEED TO ADD TO STATE"
        }

这是初始加载时的原始 json 文件。

{
    "customerId": "34",
    "agentId": "1",
    "createdDate": "1510223892",
    "firstname": "John",
    "lastname": "Doe",
    "mobile": "123456789",
    "address": "Something email here",
    "notes": {
        "0": {
            "noteId": "1",
            "customerId": "34",
            "createdBy": "1",
            "created": "1510316194",
            "note": "add something"
        },
        "1": {
            "noteId": "2",
            "customerId": "34",
            "createdBy": "1",
            "created": "1510316527",
            "note": "add something"
        },
        "2": {
            "noteId": "3",
            "customerId": "34",
            "createdBy": "1",
            "created": "1510317177",
            "note": "add new thing"
        },
        "3": {
            "noteId": "4",
            "customerId": "34",
            "createdBy": "1",
            "created": "1510318448",
            "note": "something"
        },
        "4": {
            "noteId": "5",
            "customerId": "34",
            "createdBy": "1",
            "created": "1510318476",
            "note": "this would be note number 5, lets see whether we can get something from this."
        }
    }
}

更新:Reducer 代码 - 对象而不是数组。

case NEW_NOTE_COMPLETE:
    return { ...state, notes: {...state.notes, action.payload.noteId: action.payload} }

【问题讨论】:

  • 当您收到带有3 键的便笺并且您已经收到带有该键的便笺时会发生什么?是否需要覆盖它或更改新音符的键?
  • 只有 noteId 是唯一的,所以我只是推入例如数组键 5
  • 嗯,在我看来,你有混合数据结构。你看,在你的 json 文件中 notes 是一个对象,但在你的 reducer 中它是一个数组。我希望看到这条线 notes: {...state.notes, "someKey": action.payload} 而不是这条线 notes: [...state.notes, action.payload]
  • 谢谢@Sag1v。因此,我在服务器端进行了更改,以使数组键成为 noteId。因此,当我推送新笔记时,“someKey”将是我的 payload.noteId。但是它返回了意外的令牌错误。
  • action.payload.noteId

标签: reactjs react-redux


【解决方案1】:

在我看来,您的数据结构混杂了。
在您的 json 文件中,note 键是 object,但在减速器内部,您将其作为 array 处理。
所以这一行:

return { ...state, notes: [...state.notes, action.payload] }

应该更像这样(我只是硬编码了密钥5,你应该让它以某种方式动态计算):

return {...state, notes: {...state.notes, "5": action.payload}}

编辑
作为您评论的后续行动:

但是你如何让它动态计算,它似乎并没有让 我用一个变量

假设您想使用noteId 作为您的密钥,那么您可以使用computed property names of es2015

[action.payload.noteId]: action.payload

我更新了 sn-p 来说明。

这是一个小的运行示例:

const jsonObj = {
  "customerId": "34",
  "agentId": "1",
  "createdDate": "1510223892",
  "firstname": "John",
  "lastname": "Doe",
  "mobile": "123456789",
  "address": "Something email here",
  "notes": {
    "0": {
      "noteId": "1",
      "customerId": "34",
      "createdBy": "1",
      "created": "1510316194",
      "note": "add something"
    },
    "1": {
      "noteId": "2",
      "customerId": "34",
      "createdBy": "1",
      "created": "1510316527",
      "note": "add something"
    },
    "2": {
      "noteId": "3",
      "customerId": "34",
      "createdBy": "1",
      "created": "1510317177",
      "note": "add new thing"
    },
    "3": {
      "noteId": "4",
      "customerId": "34",
      "createdBy": "1",
      "created": "1510318448",
      "note": "something"
    },
    "4": {
      "noteId": "5",
      "customerId": "34",
      "createdBy": "1",
      "created": "1510318476",
      "note": "this would be note number 5, lets see whether we can get something from this."
    }
  }
}

const newNote = {
  "noteId": "10000000",
  "customerId": "34",
  "createdBy": "1",
  "created": "1510316194",
  "note": "ADDED A NEW NOTE. NEED TO ADD TO STATE"
}
const action = {
  type: 'NEW_NOTE_SUCCESS',
  payload: newNote
};

function clientProfile(state = {}, action) {
  switch (action.type) {
    case 'NEW_NOTE_SUCCESS':
      {
        return {...state, notes: {...state.notes, [action.payload.noteId]: action.payload
          }
        }
      }

    default:
      return state;
  }
}


let reducer = clientProfile(jsonObj, {type: ''});
console.log("before the change",reducer.notes)
reducer = clientProfile(jsonObj, action);
console.log("after the change",reducer.notes)

【讨论】:

  • 非常感谢你,但你如何让它动态计算,它似乎不允许我使用变量。我想用 action.payload.noteId 作为 key,我什至试过 {action.paload.noteId} 和 ${action.payload.noteId}
  • 如果你修复了数据结构问题以避免任何未来的补丁,就像你现在要做的那样,那就更好了。有关更多信息,您可以在此处阅读 redux 作者stackoverflow.com/questions/33940015/…
  • @SomeoneSpecial 使用计算属性键(我已经更新了我的答案)
  • 我正在查看您的数据结构链接。我已经测试了你的代码并且它有效!谢谢你今天教我一些新东西!
猜你喜欢
  • 1970-01-01
  • 2017-08-08
  • 1970-01-01
  • 2020-12-05
  • 2019-07-28
  • 2017-07-12
  • 2017-04-30
  • 1970-01-01
  • 2018-08-04
相关资源
最近更新 更多