1.1.9 • Published 3 years ago

sio-redux v1.1.9

Weekly downloads
60
License
ISC
Repository
-
Last release
3 years ago

sio-redux

A small library for managing the state of the application more easily

Concepts

Reducer

  • The reducer is the place where the state it is managed
  • The reducer is a function that receives 2 parameters:
    • state which will have to be initialized the first time with the default operator from JS
    • action will hold and object with the type of the action that we want and the payload if any
  • All the time we have to produce a new state in order to be easy to reason about
  • The state will be updated using the switch case features
const initialState: TState = {};
const reducer = (state = initialState, action: Action): TState => {
  switch (action.type) {
    case LoginActions.Authenticate:
      return {
        ...state,
        loading: false,
        isAuthenticated: action.payload,
      };

    default:
      return state;
  }
};

Store

  • The reducer will be used to create a store
  • To create a store we can use the createStore function and send the reducer as argument
  • The Store will retun an object with 4 methods:
    • dipatch will be used to trigger the action that we need
    • select will be used to subscribe to the store. It receives a Selector as an argument an returns an Observable
    • getState used for getting the current state
    • registerEffects used for registering effects that will handle impure actions like HTTP requests
const loginStore = createStore(reducer);
// to register some effects
loginStore.registerEffects(SomeEffects); // If there are no effects, no need to register

Selectors

  • Selectors are functions where you specify what data you want to be returned
  • When the state changes, only the already created selectors that we subscribed to will be notified.
  • State changes in areas that we don't have selectors for, won't trigger a notification, this is performant and avoids hazard.
export const isAuthenticatedSelector = (state: LoginForm) =>
  state.isAuthenticated;

Actions

  • Actions are used to create a message in order to be used to communicate with the Store
  • Actions should have:
    • type where a string representing the type of the action will be defined
    • payload to hold some data to update the Store
  • When you need to trigger an action, just instantiate it and send the payload if necessary
enum LoginActions {
    Authenticate = '[Login] authenticate Action'
}

export class AuthenticateAction {
  type = LoginActions.Authenticate;
  payload: boolean;

  constructor(payload: boolean) {
    this.payload = payload;
  }
}

dispatch(new AuthenticateAction(true));

Effects

  • Should be used only for asynchronous requests and should dispatch an Action in case we need to update the store
  • For actions that are impure, such as HTTP Request, this is the best place to act in order to keep the state clean.
export const getLoginEffects = (dispatch: (action: Action) => void) => {
  return {
    [LoginActions.Login]: (data: LoginForm) => {
      fetch(
        `http://localhost:5000/login?username=${data.username}&password=${data.password}`
      )
        .then((response) => response.json())
        .then((response) => {
          const action = response.success
            ? new AuthenticateAction(response.success)
            : new ErrorAction(response.message);

          dispatch(action);
        })
        .catch((response) => dispatch(new ErrorAction(response.message)));
    },
  };
};
  • In the above example, we listen for a Login action and do an http request.
  • When the request is finised one of 2 actions can be triggered based on response.

How will be used

  • Inside the component we have to import the store
  • To subscribe to the store, use the select method
this.isLoading = loginStore.select((state: LoginForm) => state.isAuthenticate);
  • subscribing to the store can be done by assigning the returned observable to a variable and use the async pipe to subscribe and unsubscribe
  • explicit subscribe with loginStore.select((state: LoginForm) => state.isAuthenticate).subscribe
  • the selector should be defined in the same file where the reducer lives in order to reuse the selector in other parts of the application

  • To dispatch an action can be done in any place of the application, depending on different scenarios

  • For Logging into an application an Authenticate action will be dispached from Login event listener
login(loginForm: LoginForm) {
    loginStore
      .dispatch(new LoginAction(loginForm));
  }
  • if the dispatch action will be called through loginStore object we can chain the dispatch action for multiple actions
    loginStore
      .dispatch(new LoadingAction(true))
      .dispatch(new LoginAction(loginForm));
  • dispatching multiple action can be useful but it should be used carefully

  • NOTE if we use the dispatch action in a different context than the store., dispatch will fail because the this keyword inside will refer to global object.

1.1.9

3 years ago

1.1.8

3 years ago

1.1.7

3 years ago

1.1.6

3 years ago

1.1.5

3 years ago

1.1.4

3 years ago

1.1.3

3 years ago

1.1.2

3 years ago

1.1.1

3 years ago

1.1.0

3 years ago

1.0.15

3 years ago

1.0.14

3 years ago

1.0.13

3 years ago

1.0.12

3 years ago

1.0.11

3 years ago

1.0.10

3 years ago

1.0.9

3 years ago

1.0.8

3 years ago

1.0.7

3 years ago

1.0.6

3 years ago

1.0.5

3 years ago

1.0.4

3 years ago

1.0.3

3 years ago

1.0.2

3 years ago

1.0.1

3 years ago

1.0.0

3 years ago