简体   繁体   中英

Redux managing arrays of objects and finding nested objects

I'm not sure what to name this, but basically I'm new to React and Redux and looking for a more correct/cleaner way to do this or just how to do this with my current set up. I have a state that looks like this

--Character
---id
---name
---race
----id
----raceName
----traits
-----trait
------id
------name
------description
-----trait
------id
------name
------description
---classes
----class
-----id
-----className
-----classLevel
-----traits
------trait
-------id
-------name
-------description
------trait
-------id
-------name
-------description
----class
-----id
-----className
-----classLevel
-----traits
------trait
-------id
-------name
-------description
------trait
-------id
-------name
-------description
---traits
----trait
-----id
-----name
-----description
----trait
-----id
-----name
-----description

As you can see(hopefully) traits is an array of object TRAIT and classes is an array of object CLASS, in the end the whole state is quite a messy deal. I've read that I can somehow reference them by ID's but I'm not sure how if IDs are autogenerated.

So I kind of have two questions:

  1. How do I simplify/flatten this structure if it even could be done?
  2. If I can't simplify this structure is there anyway I can find a specific Trait with a specific ID without looping through all the objects that have property traits?

Yes. You can find Trait with a specific ID easily. Let know if this is what you are asking.

// Search in traits directly under Character.

const traitForId = this.state.Character.traits.find((trait) => {
   return trait.id = "<SPECIFIC_ID>"
})


// Search in the list of traits under each Class.

const classTraits = this.state.Character.classes.map((class) => class.traits).flat();
const classTraitsForId = classTraits.find((trait) => {
   return trait.id = "<SPECIFIC_ID>"
})

Find below recursive way to find a Trait irrespective of where it's present in the state.

function findTraitForId(state, specific_id){
 if(state.traits){
   const traitForId = state.traits.find((trait) => {
      return trait.id == specific_id
   });
   if(traitForId)
      return traitForId;
 }
 return Object.keys(state).filter((key) => key != 'traits').map((stateItem) => {
   return findTraitForId(state[stateItem], specific_id);
 }).flat();
}

Tried above function for the input

findTraitForId({'classes':[{traits: [{id: 1, name: "A"}, {id: 2, name: "AB"}]}, {traits: [{id: 3, name: "ABC"}, {id: 4, name: "ABCD"}]}], traits: [{id: 5, name: "ABCDE"}, {id: 6, name: "ABCDEF"}]}, 3)

which return

[{id: 3, name: "ABC"}]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM