0.0.1 • Published 5 years ago

@ezsper/redux-ensurable v0.0.1

Weekly downloads
-
License
MIT
Repository
gitlab
Last release
5 years ago

Preview

Redux Ensurable

Redux Ensurable helps you to create on demand (async) Redux state and actions...

Sometimes you have actions and states that loads heavy dependencies, like a provider SDK that you don't need loaded on every section of your app.

So, if it's not enough to just have your views/components asynchronous on your app, but your store as well, Redux Ensurable is the right choice for you.

Usage

1. Create your scope module
# ./store/counter.ts

import { action, PossibleAction } from 'redux-ensurable';

export interface CounterState {
  value: number;
}

export enum ActionType = {
  SET_VALUE = 'counter.SET_VALUE',
  INCREMENT_VALUE = 'counter.INCREMENT_VALUE',
  DECREMENT_VALUE = 'counter.DECREMENT_VALUE',
};

export const actions = {
  setValue(value: number) {
    return action({
      type: ActionType.SET_VALUE,
      payload: value,
    });
  },
  incrementValue(value: number = 1) {
    return action({
      type: ActionType.INCREMENT_VALUE,
      payload: value,
    });
  },
  decrementValue(value: number = 1) {
    return action({
      type: ActionType.INCREMENT_VALUE,
      payload: value,
    });
  },
};

const defaultState = {
  value: 0;
};

export const reducer = (state: CounterState = defaultState, actions: PossibleAction<typeof actions>) => {
  switch(action.type) {
    case ActionType.SET_VALUE:
      return {
        ...state,
        value: action.payload,
      };
    case ActionType.INCREMENT_VALUE:
      return {
        ...state,
        value: state.value + action.payload,
      };
    case ActionType.DECREMENT_VALUE:
      return {
        ...state,
        value: state.value - action.payload,
      };
    default:
      return state;
  }
});
2. Create your store
# ./store/index.ts

import {
  createEnsurableStore,
} from 'redux-ensurable';

const store = createEnsurableStore({
  {
    counter: require('./counter'),
    counter2: { async: () => import('./counter') },
    counter3: { async: () => import('./counter') },
  },
});
3. Resolve your state
Ensured state
store.ensure(['counter2', 'counter3'])
  .then((ensuredStore) => {
    let state = ensuredStore.getState();
    
    console.log('counter2', state.counter2.value);
    
    const {
      counter: counterActions,
    } = ensuredStore.actions;
    
    ensuredStore.subscribe(state => {
      console.log('counter2', state.counter.value);
    });
    
    ensuredStore.dispatch(counterActions.incrementValue());
  });
Partial state
const state = store.getState();

console.log('counter', state.counter.value);

if (state.counter2 != null) {
  console.log('counter2', state.counter2.value);
} else {
  store.subscribe(() => {
    const state = store.getState();
    if (state.counter2 != null) {
      console.log('counter2', state.counter2.value);
    }
  });
  store.load(['counter2']);
}

With React

You will need to add React Redux Ensurable to your dependencies

import * as React from 'react';
import { connect } from '@ezsper/react-redux-ensurable';
import { store } from '../store';

export interface MyCounterPropTypes {
  value: number;
  incrementValue: () => void; 
};

class MyCounter extends React.Component<MyCounterPropTypes> {
  
  handleClick = () => {
    return this.props.incrementValue();
  };

  render() {
    return <button onClick={this.handleClick}>{this.props.value}</button>;
  }
}

export default connect(MyCounterPropTypes)(
  store,
  ['counter2'], // ensure the scopes you want from the store
  (state, props) => ({
     value: state.counter2.value,
  }),
  (dispatch, actions) => ({
    incrementValue: () => dispatch(actions.counter2.incrementValue()),
  }),
);
0.0.1

5 years ago