ezflow
Powerful React state management
Features
- Support async action, no third party lib needed
- Support action flow
- Support cancellable action dispatching
- Support dynamic importing reducers and flows (useful for large project)
- Support debouncing and throttling for action dispatching
- Support future actions handling
Examples
- Counter App (verbose version)
- Counter App (compact version)
- Counter App (using connect() function)
- Handling async action
- Handling multiple actions using flow concept
- Using debounce and throttle
Counter App (verbose version)
import React from "react";import render from "react-dom";import createStore Provider useDispatch useSelector from "ezflow"; const initialState = count: 0 ;// define root reducer for storeconst reducer = state = initialState params const action = params; if action === Increase return ...state count: statecount + 1 ; return state;;// define Increase actionconst Increase = ;const CountSelector = statecount;const store = ; const Counter = // extract count value from store const count = ; // access store dispatch method const dispatch = ; const handleIncrease = ; return <> <h1>count</h1> <button =>Increase</button> </> ;; const App = return <Provider => <Counter /> </Provider> ;; ;
Counter App (compact version)
import React from "react";import render from "react-dom";import createDefaultStore useDispatcher useSelector from "ezflow"; const initialState = count: 0 ;// define root reducer for storeconst reducer = state = initialState params const action = params; if action === Increase return ...state count: statecount + 1 ; return state;;// define Increase actionconst Increase = ;const CountSelector = statecount; // no Provide needed if using default store; const App = // extract count value from store const count = ; const increase = ; return <> <h1>count</h1> <button =>Increase</button> </> ;; ;
Counter App (using connect)
import React from "react";import render from "react-dom";import createDefaultStore connect from "ezflow"; const initialState = count: 0 ;// define root reducer for storeconst reducer = state = initialState params const action = params; if action === Increase return ...state count: statecount + 1 ; return state;;// define Increase actionconst Increase = ;const CountSelector = statecount; // no Provide needed if using default store;// create containerconst AppContainer = ;// bind container to componentconst App = ;;
Handling async action
https://codesandbox.io/s/ezflow-example-async-action-k4xc6
import React useRef from "react";import ReactDOM from "react-dom";import createDefaultStore Loading delay useDispatch useSelector from "ezflow"; const LoadData = await ; return `Results of `;; const initialState = loading: "" data: "There is no data"; const reducer = state = initialState params const action target result payload = params; // Loading action will be triggered automatically whenever async action is dispatched if action === Loading && target === LoadData return loading: `Fetching for ...` ; else if action === LoadData return ...state loading: undefined data: result ; return state;; ; { const loading data = ; const dispatch = ; const inputRef = ; { ; inputRefcurrentvalue = ""; } return <div ="App"> <p> <input ="text" = ="Type something" /> <button =>Load</button> </p> <div>loading ? loading : data</div> </div> ;} const rootElement = document;ReactDOM;
Handling multiple actions using flow concept
https://codesandbox.io/s/ezflow-example-flow-17tzt
import React from "react";import ReactDOM from "react-dom";import createDefaultStore useStore Loading Cancel useDispatch useSelector from "ezflow"; const Login = ;const Logout = ;const UpdateProfile = ;const LoadProfile = await ; return username token: `:` ;; const RootFlow = while true const payload: username password = await ; const $key profile = await ; // LoadProfile dispatched if $key === "profile" ; // wait logout action dispatched await ; else // Logout dispatched // that means LoadProfile action is cancelled const currentProfile = ; ; }; const initialState = status: "" profile: username: "anonymous" lastLoggedIn: "never" ; const RootReducer = state = initialState action payload result target if action === Loading && target === LoadProfile const username = payload; return ...state status: `Loading profile for ` ; else if action === Cancel && target === LoadProfile return ...state status: "Profile loading cancelled" ; // profile loaded else if action === LoadProfile return ...state status: "Profile loaded" ; else if action === UpdateProfile return ...state profile: payload ; return state;; ; { // dynamic import flow to current store ; const dispatch = ; const profile status = ; { ; } { ; } return <> <button =>Login as admin</button> <button =>Logout</button> <p>status</p> <p>JSON</p> </> ;} const rootElement = document;ReactDOM;
Using debounce and throttle
https://codesandbox.io/s/ezflow-example-debounce-throttle-lhxch
import React from "react";import ReactDOM from "react-dom";import createDefaultStore useSelector useDispatcher from "ezflow"; const initialState = count: 0;const Increase = ;const IncreaseDebounced = ;const IncreaseThrottled = ;const RootReducer = state = initialState action if action === Increase return ...state count: statecount + 1 ; return state;;const RootFlow = debounce throttle ; ;; ; { const count = ; const increase increaseDebounced increaseThrottled = ; return <div ="App"> <h1>count</h1> <button =>Increase</button> <button => Increase with debouncing effect </button> <button => Increase with throttling effect </button> </div> ;} const rootElement = document;ReactDOM;