0.2.4 • Published 8 years ago

redux-flux-store v0.2.4

Weekly downloads
4
License
MIT
Repository
github
Last release
8 years ago

redux-flux-store

This store enhancer allows objects which resemble stores in traditional Flux to be used in a Redux Reducer. The motivation for this was to allow both the mutations for a property as well as the accessors to be in the same file, as a change in one will likely result in a change in the other. In traditional Flux this was the purpose of a Store, however Redux keeps these two tasks separated into Reducers and Selector.

Installation

npm i redux-flux-store

Usage

Note: The term store is used to describe an object with a reduce(state, action, waitFor) method.

  • state (Object) - The value of the entry in the global redux state.
  • action (Object) - The redux action of the form {type: String, ...}
  • waitFor (Function) - A function which takes an array of stores and ensures that the values for the specified stores will be updated before continuing execution.

fluxEnhancer(storeMap: Object)

storeMap: An object which matches a key in the global state to a flux store which manages that key.

// TeamStore.js
import Store from 'ReduxStore.js';

class TeamStore {
  getTeams() {
    return Store.getState().teams;
  }

  initializeBasicTeam(teamData) {
    return Object.assign({}, teamData, {score: 0});
  }
  addTeam(state, teamData) {
    let update = {};
    update[teamData.id] = this.initializeBasicTeam(teamData);
    return Object.assign({}, state, update);
  }

  reduce(state = {}, action, waitFor) {
    switch(action.type) {
    case 'ADD_TEAM':
      return this.addTeam(state, action.data.team);
    default:
      return state;
    }
  }
}

export default new TeamStore();

// LeaderboardStore.js
import TeamStore from 'stores/TeamStore';

class LeaderboardStoreClass {
  handleNewTeam(currentLeaderboard, teamId, waitFor) {
    waitFor([TeamStore]);
    let teams = TeamStore.getTeams();
    let newTeam = teams[teamId];
    let leaderboard = _.assign([], currentLeaderboard);
    let index = _.sortedIndex(currentLeaderboard, newTeam.id, (teamId) => {
      return teams[teamId].score;
    })
    leaderboard.splice(index, 0, newTeam.id);
    return leaderboard;
  }

  reduce(state = [], action, waitFor) {
    switch(action.type) {
    case 'ADD_TEAM':
      return this.handleNewTeam(state, action.data.team.id, waitFor);
    default:
      return state;
    }
  }
}

export default new LeaderboardStore();

// ReduxStore.js
import { fluxEnhancer } from 'redux-flux-store';
import TeamStore from 'stores/TeamStore';
import LeaderboardStore from 'stores/LeaderboardStore';

let finalCreateStore = compose(
  fluxEnhancer({
    leaderboard: LeaderboardStore,
    teams: TeamStore
  }),
  applyMiddleware(...middleware),
)(createStore);

let store = finalCreateStore(reducer);

console.log(store.getState());
// { teams: {}, leaderboard: [], ...reducer() }

store.dispatch({type: 'ADD_TEAM', data: {team: {id: 'H42'}}});
console.log(store.getState());
// { teams: {H42: {score: 0, id: 'H42'}}, leaderboard: ['H42'], ...reducer(state, action)}

export default store;
0.2.4

8 years ago

0.2.3

8 years ago

0.2.2

8 years ago

0.2.1

8 years ago

0.2.0

8 years ago

0.1.2

8 years ago

0.1.1

8 years ago

0.1.0

8 years ago