sio-redux v1.1.9
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 casefeatures
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
createStorefunction and send the reducer as argument - The
Storewill retun an object with 4 methods:dipatchwill be used to trigger the action that we needselectwill be used to subscribe to the store. It receives aSelectoras an argument an returns anObservablegetStateused for getting the current stateregisterEffectsused 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 registerSelectors
- 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
Actionin 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
Loginaction 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
selectmethod
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
asyncpipe 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
Loginevent listener
login(loginForm: LoginForm) {
loginStore
.dispatch(new LoginAction(loginForm));
}- if the dispatch action will be called through
loginStoreobject we can chain thedispatchaction for multiple actions
loginStore
.dispatch(new LoadingAction(true))
.dispatch(new LoginAction(loginForm));dispatching multiple action can be useful but it should be used carefully
NOTEif we use thedispatchaction in a different context than thestore.,dispatchwill fail because thethiskeyword inside will refer toglobalobject.
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago