Skip to content

Latest commit

 

History

History
155 lines (112 loc) · 3.86 KB

README.md

File metadata and controls

155 lines (112 loc) · 3.86 KB

redux-entitize

Automated redux-state management for all your entities.

redux-entitize helps you organize all your entities in unified and normalized state. It ships with:

  • a reducer
  • a set of action creators to populate your state with entity data
  • a set of selectors to retrieve entities from the state

Install

yarn add redux-entitize
# or
npm install --save redux-entitize

Getting Started

1. Define your schemas

You need to tell redux-entitize about all your normalizr-schemas by defining a schemaMap:

// schemaMap.js

import { normalize, schema } from 'normalizr';

const userSchema = new schema.Entity('users');
const commentSchema = new schema.Entity('comments', {
  commenter: userSchema
});

export const schemaMap = {
  users: userSchema,
  comments: commentSchema,
};

2. Add the entities-reducer

// reducers.js

import { createEntitiesReducer } from 'redux-entitize';
import { combineReducers } from 'redux';
import { schemaMap } from './schemaMap';

const entitiesReducer = createEntitiesReducer(schemas);

export const reducers = combineReducers({
  entities: entitiesReducer // must be called entities
  // ... your other reducers
});

Note: In order for the selectors to Just Work™, the state slice must be called entities.

Dispatch update actions

To add new entities or update existing ones, use updateEntityAction / updateEntitiesAction.

To remove an entity from your state, use deleteEntityAction.

// main.js

import { createStore } from 'redux';
import {
  updateEntityAction,
  updateEntitiesAction,
  deleteEntityAction,
} from 'redux-entitize';

import { reducers } from './reducers';

const store = createStore(reducers);

store.dispatch(
  updateEntityAction('users', {
    id: "1234",
    email: "[email protected]",
    age: 25,
  })
);

store.dispatch(
  updateEntitiesAction('comments', [{
    id: "567",
    message: "Hello world.",
    commenter: "1234",
  }, {
    id: "890",
    message: "Yet another comment. Even by the same commenter",
    commenter: "1234",
  }])
);

store.dispatch(
  deleteEntityAction('comments', "567");
);

Note: Where these actions are actually dispatched is dependent on how your app is interacting with the API.

Select entities from state

redux-entitize provides a selectors factory to simplify selecting entities from the state. It's strongly recommended to use these, because

  • selected entities will be automatically de-normalized
  • selectors are based on reselect, so they are memoized (otherwise you application will most likely be slow)
  • selectors are meant to remain stable throughout changes of the internal entities-state
// selectors.js

import { createSelectors } from 'redux-entitize';

// Assuming we have that `schemaMap` variable from above when you created your schemas
import { schemaMap } from './schemaMap'

export const selectors = createSelectors(schemaMap)

Import the selectors in your components and render data as you like.

// UserList.js

import React from 'react';
import { connect } from 'react-redux';

import UserList './UserList';
import {
  selectEntity,
  selectEntities
} from './selectors';

function mapStateToProps(state) {
  return {
    // Get all entities of a type
    allUsers: selectEntities(state, 'users'),

    // Get all entities of a type with certain IDs
    // (state.userList.filteredIds === ['id1', 'id2', 'id3'])
    filteredUsers: selectEntities(state, 'users', state.userList.filteredIds),

    // Get a single entity of a type with a certain ID
    // (state.login.userId === 'id123')
    loggedInUser: selectEntity(state, 'users', state.login.userId)
  };
}

export default connect(mapStateToProps)(UserList);