1.0.0-alpha.7 • Published 6 years ago
redux-loop-composer v1.0.0-alpha.7
Redux-loop composer
Easely create actions, handle reducers and it's side effects thanks to redux-loop
Quick start
npm i -s redux-loop-composer
1. Create a module
import loopModule from 'redux-loop-composer';
const loginModule = loopModule.create('login');
2. Export actions
export const login = (username, password) => loginModule.action('login').payload({ username, password });
export const loginSuccess = (user) => loginModule.action('loginSuccess').payload({ user });
export const loginFailure = (error) => loginModule.action('loginFailure').payload({ error });
export const logout = () => loginModule.action('logout').noPayload();
export const tokenExpired = () => loginModule.action('tokenExpired').noPayload();
3. Handle reducers
loginModule
// initial state
.reducer({
logging: false,
loginSuccess: false,
user: null
})
.when('login')
.evolve(() => ({ logging: true, loginSuccess: false })) // change state
.when('loginSuccess')
.evolve(({ user }) => ({ logging: false, loginSuccess: true, user })) // change state
.when('loginFailure')
.evolve(() => ({ logging: false, loginSuccess: false })) // change state
.when(['logout', 'tokenExpired'])
.overwrite(() => ({user: null})) // overwrite state
.end(); // finish reducer composition
4. Schedule side effects
Handle side effects with redux-loop:
loginModule
.sideEffects()
.when('login')
.run(loginService.login) // remote call
.args(({ username, password }) => [username, password]) // extract arguments from current action payload
.then(loginSuccess) // success action
.catch(loginFailure) // failure action
.when('loginSuccess')
.action(showMessage) // simply dispatch another action
.args('Login successful') // static argument passed to the new action
.when('loginFailure')
.action(showErrorMessage) // simply dispatch another action
.args(({error}) => [error.message]) // extract arguments from current action payload
.when('tokenExpired')
.cmd(() => Cmd.action(showMessage('Session expired, please login again to proceed'))) // manually invoke Cmds
.end(); // finish side effects composition
5. Add an module to the appliacation
const store = loopModule.app('example').addModule(loginModule).addModule(messageModule).compose();
6. Access the state from a module
Direct access:
store.subscribe(() => {
const loginState = loginModule.fromStore(store.getState()).getState();
const user = loginState.user;
});
Select a state value with reselect:
const userDisplaySel = loginModule.selector(state => state.user).then(user => `${user.name} (${user.username})`);
store.subscribe(() => {
const userDisplay = userDisplaySel(store.getState());
console.log(userDisplay); // Foo (username)
});
7. Dispatch actions
// type: example.login.login
// payload:
// username: 'username'
// password: 'password'
store.dispatch(login('username', 'password'));
Using with React
import React from 'react';
import connect from 'react-redux';
import loginModule, { login } from './loginModule';
const mapStateToProps = state => {
const loginState = loginModule.fromStore(state).getState();
return {
user: loginState.user
}
};
const mapDispatchToProps = dispatch => ({
login: (username, password) => dispatch(login(username, password))
});
const UserMenu = ({user, login}) => {
return (
<div>
{/* display user and dispatch login action */}
</div>
);
};
UserMenu = connect(mapStateToProps, mapDispatchToProps)(UserMenu);
export default UserMenu;
1.0.0-beta.2
6 years ago
1.0.0-beta.1
6 years ago
1.0.0-alpha.7
6 years ago
1.0.0-alpha.6
6 years ago
1.0.0-alpha.5
6 years ago
1.0.0-alpha.4
6 years ago
1.0.0-alpha.3
6 years ago
1.0.0-alpha.2
6 years ago
1.0.0-alpha.1
6 years ago