Redux Patterns: Add/Edit/Remove Objects in an Array

Written by justintulk | Published 2016/12/23
Tech Story Tags: javascript | react | redux | web-development | es6

TLDRvia the TL;DR App

Update: In practice, I’m simplifying this structure more and more. Not because it’s bad, but because it’s frequently more solution than I need. Read more:

Redux Patterns: Rethinking `byId` and `byHash` Structures_Iterate with Object.keys() and drop byId_medium.com

I wrote a post the other day about how to implement a Redux-flavored store and reducer in a single React component without actually using Redux. I didn’t code out the logic in the post, but when I was tinkering in JSBin I used a pattern for updating objects in an array that looks like this:

The problem with this method is that mapping the entire array for every update will see performance degradation as the array size grows. Also, we have to do some extra work to make sure that we don’t inadvertantly end up with more than one copy of each object in the array.

Hash Tables

What if we stored the data using a hash table instead of an array? Hash tables can be used to map items from an array into an object using key-value pairs such that duplicates are easily avoided and lookup performance is improved. However, certain array properties (such as length) will not be as readily accessible. To get around that limitation we’ll keep two properties in state, one will be an array of hashes, and the other will be a hash table of each individual object.

const initialState = {byId: [],byHash: {}}

Every time we add, edit, or update an object via our reducer we’ll perform two actions: one will update the array (if necesssary) and the other will update the hash table.

Presto: a much more efficient reducer when operating at scale. If we were using this in a React view to build out a list of subcomponents, we could leverage both parts of the state object to map out the subcomponents and then populate them.

// assuming Redux passes in the state object as this.props.data

{this.props.data.byId.map((item, index) => (<div key={index}>{this.props.data.byHash[item].content.title}</div>)}

In an actual Redux example, the state object could be built by combining two separate reducers to act independently on the byHash and byId properties of the state object to simply the logic.

Full disclosure: I’m not sure that this the optimum way to solve this problem. If you’ve got a better solution, or can link to anything related, please share.

Note: The reducer logic should make sure that _state_ is always being returned as a new object to ensure a view update in React/Redux. I’m not testing this code in a view while I write this blog post, so there may be a syntax error or two, or maybe there is just some unnecessary logic. Feel free to comment w/ suggested improvements.

Related

Redux Patterns: Caching an API Response_Avoid Duplicating Calls for Stable Data_medium.com

Implement Redux as Vanilla JS in a Single React Component_I’m currently working on a project where I’m patching a few React components piecemeal into an existing ASP.NET build…_medium.com


Published by HackerNoon on 2016/12/23