Search code examples
javascriptreactjsreduxreact-router-v4reselect

how to take two lists, allow a user to make selections from each to create two new lists and combine data from new lists into a single result in redux


tldr: questions -

  1. best practice in redux for creating a new list based on user selection from a current list.
  2. best practice in redux/react for combining data from two user created lists
  3. comparing and combining differently named values from separate lists.

I know this probably isn't the best worded question and I can explain it better if anyone has specific questions. I am hoping for at least a point in the right direction. such as a library to learn (like React-Form will handle all this so easily. go read those docs...) more about or just docs in general to find more information

this is kind of a multi part question, but I'll explain it as best I can. I currently have three routes. One for list "A" that maps out a list of hundreds of people. On a user click it dispatches an action that calls a single person and shows a detail page of that person with changeable stats. Pretty standard redux async action. The only outside the norm approach I took here was to split the backend into two different calls. One for the entire people list and one for the individual person. My thoughts on this was not to have the entire 500mb be called every time someone visits the people page if it doesn't need to be as the people list just shows name and a photo. Just a side question, but is this the right approach in redux? or did I just overcomplicate my code for no reason? I am approaching this app in a positive way and hoping there will be thousands of visitors at a time and am relatively new to thinking about this much data transfer and wether or not it will become an issue

The other list "B" does the exact same, but for items. They however have a fixed data a user cannot change. I did approach this the same as the people container and split the api call into one for items and a second for itemDetail.

My primary question is the third page. I would like two render both lists. allow a user to select a single person to be added to a selected field above the peoples list. and then allow them to select up to six items to be shown above the items list as well. Then combine the stats from each selected item (up to six) with the stats of the selected person. One of the tricky parts I've run into is the fact the stats are named differently on the persons and the items. for example

selectedPerson =   

"stats": {
            "armorperlevel": 3,
            "attackdamage": 69.97,
            "mpperlevel": 32,
            "attackspeedoffset": -0.02,
            "mp": 338.8,
            "armor": 36,
            "hp": 592.8,
            "hpregenperlevel": 0.55,
            "attackspeedperlevel": 3.4,
            "attackrange": 125,
            "movespeed": 350,
            "attackdamageperlevel": 3.375,
            "mpregenperlevel": 0.7,
            "critperlevel": 0,
            "spellblockperlevel": 1.25,
            "crit": 0,
            "mpregen": 7.576,
            "spellblock": 32.1,
            "hpregen": 8.374,
            "hpperlevel": 85
        },
        "id": 24,

the items might have some of these. might have none of these, but there keys are different and offer a flat or percent option as well. such as "description": "<stats>+15 Attack Damage<br>+10% Life Steal</stats>",

"stats": {
            "FlatPhysicalDamageMod": 15,
            "PercentLifeStealMod": 0.1
        },
        "id": 1053,

As one of the main sections I am trying to learn more about. I can explain as well as I can without showing my logic. On the person detail page I have separated each stat into a function that applies my formula for that particular stat times the selected level. While I don't know if that's the best approach it works and returns the exact numbers I need. Now on this third page I want to show this stat box, but also add in the items stats to each of these functions. will I need to write hundreds of if (item.stats === 'whatever') to each person stat function? or is there a more Redux or React way to manage this?


Solution

  • The only outside the norm approach I took here was to split the backend into two different calls. One for the entire people list and one for the individual person.

    This is not outside the norm: most APIs will take some variation on this path. It's perfectly reasonable to have requests for individual entities, and most requests for lists of entities will have some kind of paging or limiting system to prevent dumping the entire record set unnecessarily.

    You asked if this is the correct approach for Redux, but I think you were speaking of a backend issue so I'm not really sure how to comment. It's certainly reasonable to issue different requests for "ALL the things" and "ONE of the things", and put the results in store. If managing massive quantities of stuff in the store becomes an issue, that's a good problem to have but also manageable by cleaning up the store periodically.

    I would like two render both lists. allow a user to select a single person to be added to a selected field above the peoples list. and then allow them to select up to six items to be shown above the items list as well. Then combine the stats from each selected item (up to six) with the stats of the selected person.

    Sure, sounds fine. Presumably your component will have a single set person and an array of items, and understand how to display each type.

    Now on this third page I want to show this stat box, but also add in the items stats to each of these functions. will I need to write hundreds of if (item.stats === 'whatever') to each person stat function? or is there a more Redux or React way to manage this?

    I think you might be confusing program logic with state management. Redux is basically an elegantly-designed bucket. It's a pretty useful bucket, but it's still just a bucket. It's a place to keep things, and retrieve/update them as necessary.

    You can choose to do whatever you wish with the bits in between. You may find that a lot of your logic ends up in the connecting code, where you retrieve values from Redux and map them to your component. However, it's completely up to you.

    In broad strokes I imagine you might consider maintaining a hash of items in the store, each object of which can translate its particular stat values to something that's meaningful for a person. If these can be made generic in some way (all attackdamage properties behave the same way) then by all means go for it.