Skip to content

Instantly share code, notes, and snippets.

@sikanhe
Last active November 20, 2017 21:45
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sikanhe/9b940ce866d78354bba3 to your computer and use it in GitHub Desktop.
Save sikanhe/9b940ce866d78354bba3 to your computer and use it in GitHub Desktop.
Most efficient way to store domain state in Redux (Indexed Key-Value Store)
//After working on the backend for a while, I started to continue working on my front end,
//I revisited my redux “cache” store and I made this improvement that made my life a lot easier.
//In my project for example, some collections i need to get the document by id, some by slug, some by username, and etc.
//If I need to account for those cases I had to make new action creators/types, for different entities.
//This is very frustrating as it makes the code less dry and leads to more boilerplate.
//Then what I realized was, I can just pass a “index” option for my insert action creators!(which defaults to “id")
//Actions
const actions = {
INSERT_ONE: 'INSERT_ONE',
INSERT_MANY: 'INSERT_MANY'
}
//Action Creators
export function insert(collection, payload, { index } = { index: 'id'}) {
if(Array.isArray(doc)) {
return {
type: actions.INSERT_MANY,
collection,
docs: payload,
index
}
} else {
return {
type: actions.INSERT_ONE,
collection,
doc: payload,
index
}
}
}
//Reducer
const defaultState = {
users: {},
posts: {}
}
export default function cache(state = defaultState, action) {
const { collection, index, doc } = action;
switch(action.type) {
default:
return state;
case actions.INSERT_ONE:
return {
...state,
[collection]: {
...state[collection],
[doc[index]]: doc
}
};
case actions.INSERT_MANY:
const newDocs = {};
docs.forEach(doc => {
newDocs[ doc[index] ] = doc
});
return {
...state,
[action.collection]: {
...state[action.collection],
...newDocs
}
}
}
}
//How to insert
this.props.insert('users', user, {index: 'username'});
this.props.insert('posts', post, {index: 'slug'});
this.props.insert('posts', post); // index by "id"
// Now I can easily get document by the property I usually use for that type
const user = cache.users["some_username"]; //get using username
const post = cache.posts["some-title-slug"]; //get using slug
const post = cache.posts["234j2kl3j42h3j4l"] //get using id
//Joins in my components
const post = cache.posts["some-slug"];
post.user = cache.users[post.user_id];
//Easy peazy!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment