更新Redux中的深层嵌套数组

时间:2018-07-05 13:03:23

标签: javascript reactjs redux

我一直在四处寻找解决问题的方法或指南。 我需要通过与操作一起传递的ID找到正确的子子文档,然后再由我与操作一起传递的ID找到正确的子子文档。

我正在从API提取对象,然后放入状态。 我与此类似的对象:

proj = {
  id:"zf123ada123ad",
  name:"examp",
  subdoc:{
    name:"subdoc examp",
    subsubdoc:[{
               id:"zcgsdf123zaar21",
               subsubsubdoc:[{
                             id:"af2317bh123",
                             value: "heyhey"   //this value I want to update
                            }]
              }]
}
}

在我的reducer中,我有类似atm的内容: 我知道这行不通,因为我没有在数组中获得特定的对象,但这就是我不知道该怎么做。我有要更改其值的subsubsubdoc的ID。

export function answerUpdate(state = [], action){
  switch(action.type){
    case 'ANSWER_UPDATE_FETCH_SUCCESS':
      return {
        ...state,
        proj: {
          ...state.proj,
          subdoc: {
            ...state.proj.subdoc,
            subsubdoc: {
                ...state.proj.subdoc.subsubdoc,
                subsubsubdoc: {
                    ...state.proj.subdoc.subsubdoc.subsubsubdoc,
                value: "hoy"
                }
            }
          }
        }
    default:
      return state
  }
}

这是我想要的,但是在reducer内可以正常工作的代码:

state.doc.subdoc.subsubdoc.where(x => x.id ==theInputId1)
   .subsubsubdoc.where(
   x => x.id == theInputId2).value = theInputValue

非常感谢每个答案!

2 个答案:

答案 0 :(得分:0)

假设action.payload是您的ID,则应执行类似操作

    case 'ANSWER_UPDATE_FETCH_SUCCESS': {
            const index = state.proj.subdoc.subsubdoc.findIndex(({id}) => id === action.payload);
            const updatedObject = {
               ...state.proj.subdoc.subsubdoc[index],
               value: newValue
            }

            return {
               ...state,
               proj: {
                 ...state.proj,
                 subdoc: {
                   ...state.proj.subdoc,
                   subsubdoc: [
                        ...state.proj.subdoc.subsubdoc.slice(0, index),
                        updatedObject,
                        ...state.proj.subdoc.subsubdoc.slice(index)
                      ]
                    }
                  }
            }
    }

您可以对不存在id的情况进行其他检查,通过将state.proj.subdoc.subsubdoc存储在变量中来简化使用。

建议在redux商店中不要使用此类深层嵌套。

答案 1 :(得分:0)

我首先要考虑的是将数据转换为常规格式。如果您无法控制API,请在收到格式后自行制作格式。这将为您节省大量复杂的代码。通常,智能数据结构和笨拙的程序代码要比笨拙的数据结构和大量复杂代码的性能更好。

var project = [
  { "id": "zf123ada123ad",
    "name": "examp",
    "value": null,
    "docs": [
      { "id": "zcgsdf123zaar21",
        "name": "examp-sub",
        "value": null,
        "docs": [
          { "id": "af2317bh123",
            "name": "examp-sub-sub",
            "value": "heyhey",
            "docs": []
          }
        ]
      }
    ]
  }
];
	// 1st option: Recusively search.
var search = function( id ) {
  var search_level = function( result, next ) {
    if ( result ) return result;
    else {
      if ( next.id === id ) return next;
      else return next.docs.reduce( search_level, null );
    }
  };
  return search_level;
};
var heyhey_search = project.reduce( search( "af2317bh123" ), null );
console.log( 'option 1:' );
console.log( heyhey_search );
// 2nd option: Make a hash table. This is preferred if you need to access records by id often.
var flatten_hash = function( result, next ) {
  // Own.
  result[ next.id ] = next;
  // Nested docs.
  return next.docs.reduce( flatten_hash, result );
};
var project_hash = project.reduce( flatten_hash, {} );
var heyhey_hash = project_hash[ "af2317bh123" ];
console.log( 'option 2:' );
console.log( heyhey_hash );

var state = [
	{
  	"id": 1,
    "docs": [
    	{
      	"id": 3,
        "value": "old value"
      }
    ]
  },
  {
  	"id": 2,
    "docs": []
  }
];
console.log( 'old state' );
console.log( JSON.stringify( state ) );
var object_3 = state[0].docs[0];
object_3.value = "new value";
console.log( 'new state' );
console.log( JSON.stringify( state ) );