react-xs
Minimalism state manager
Features
react-xs | redux | |
---|---|---|
Provider element | ✓ | |
Action Dispatcher | ✓ | |
Action Creator | ✓ | |
Reducer | ✓ | |
Middleware | ✓ | |
connect() HOC | ✓ | |
State Mappings / Bindings | ✓ |
react-xs has nothing special but it is powerful, easy to use, reduce code complexity and great performance
Table of contents
- Counter App
- Todo App
- Creating simple state
- Handling state change
- Getting state value
- Sub States
- Binding states to component
- Mutating multiple states and performance issue
- Mutating state using helpers
- Handling multiple states change
- Computed state
- Getting values of multiple states
- Update values of multiple states
- Dispatching function one time when component did mount
- Best practice
- API
- Credits
Counter App
Simplest and shortest counter app
import React from "react";import render from "react-dom";import $ from "react-xs";const count = ;const Counter = ;;
Compare to redux version
import React from "react";import render from "react-dom";import createStore from "redux";import Provider connect from "react-redux"; const reducer = state = 0 action switch actiontype case "INCREMENT": return state + 1; default: return state; ; const store = ; const App = dispatch count <> <h1>count</h1> <button =>Increase</button> </>; ;
Redux like version
import React from "react";import render from "react-dom";import $ from "react-xs";const connect = $;const Count = ;const Increase = Countvalue++;const Counter = ;;
Todo App (Performance test)
Please refer this link , an example runs with 7000 todo items (over 28.000 elements). User can update todo text on the fly, without lagging. Redux or other state managers(Mobx, unstated) get lag with 1000-5000 todo items
Creating simple state
import $ from "react-xs"; const numberValue = ;const booleanValue = ; // mutate statesnumberValuevalue = 1000;booleanValuevalue = false; // keep in mind, state can be anything, no validation or restriction for state data typenumberValuevalue = ;
Handling state change
import $ from "react-xs"; const state = ;state;statevalue = 100;
Getting state value
import $ from "react-xs"; const person = ;personvaluename; // Hungperson; // Hungpersonget`name`; // Hung person; // abcpersonvalueaddressstreet; // abcpersonget`address.street`; // abc
Sub States
const person = ;personprop`address.street`value; // abcpersonvalue; // abc
Binding states to component
You can use overload $(component) to create component wrapper which binded with states. You dont need any Provider element, no mapStateToProps needed
import React from "react";import $ from "react-xs";const state = ;const WrappedComponent = ;
Mutating multiple states and performance issue
Sometimes you need to mutate many states at same time, that might lead to performance issue because when state changed, it notifies to all components which is using state
import React from "react";import $ from "react-xs"; const state1 = ;const state2 = ; const Comp1 = ;const Comp2 = ; { state1value = 100; // at this time, both Comp1 and Comp2 re-render state2value = 100; // Only Comp2 re-renders}
We can use $.mutate(action) to reduce component re-render times
{ $; // Comp1 and Comp2 re-render one time only}
Mutating state using helpers
react-xs provides many helpers for mutating object, array, date, number, boolean, string data types
import $ from "react-xs"; const number = ;number; // 1number; // -1number; // -4number; // -2 const obj = ;obj; // { name: 'Hung' }obj; // { name: 'Hung', male: true }objprop`parent.address.street`value = "abc"; // { name: 'Hung', male: true, parent: { address: { street: 'abc' } } }obj; // { name: 'Hung' }// set default value for prop if it is not presentobj; // { name: 'Hung', male: false }// nothing affected because male prop is presentobj; // { name: 'Hung', male: false } const array = ;array; // [1, 2, 3]array; // [1, 3]array; // [2, 6]array; // [2]array; // []array; // [1, 2]array; // [2]array; // [2, 5, 6, 2]array; // [5, 6]array; // [5]array; // [100]array; // [100, 99]array === 100; // truearray === 99; // truearray; // [99, 100] const date = ; date; // add 1 year, 2020-01-01date; // add 1 year, 2021-01-01// duration can be year/Y, month/M, day/D,// hour/h, minute/m, second/s, milli// you also add multiple durationsdate; // add 1 month and 2 days, 2021-02-03
If you want to extend more helpers, just call $.extend()
import $ from "react-xs";import immhelper from "immhelper"; $;const state = ; state; // { name: 'Hung' }
Handling multiple states change
import $ from "react-xs"; const state1 = ;const state2 = ; $; // using debounce option$; state1value = 1;state2value = 2; // output// test1 1 0// test1 1 2// test2 1 2
Computed state
import $ from "react-xs"; const state1 = ;const state2 = ;const state3 = ; // state3 = 3state1value = 100; // state3 = 102state2value = 101; // state3 = 201
Getting values of multiple states
import $ from "react-xs"; const state1 = ;const state2 = ; $; // { state1: 1, state2: 2 }
Update values of multiple states
import $ from "react-xs"; const state1 = ;const state2 = ;const state3 = ;$;// state1 = 5// state2 = 6// state3 = 3
Dispatching function one time when component did mount
import React from "react";import render from "react-dom";import $ from "react-xs"; // assign default async status to state value// initial { loading:false, done:false, data:undefined, error:undefined }// loading { loading:true, done:false, data:undefined, error:undefined }// resolved { loading:false, done:true, data:any, error:undefined }// rejected { loading:false, done:true, data:undefined, error:any }const userProfile = ;const LoadUserProfile = // do nothing if we already fetched data if userProfileget`done` return; // update state once promise resolved/rejected userProfile;; const UserProfileComponent = ; ;
Best practice
Sometimes we try to split our app to many modules, it is hard for other state management libraries. Here is sample project structure if you are using react-xs
src/ modules/ counter/ components/ Counter/ container.js index.js states.js actions.js index.js
modules/counter/states.js
import $ from "react-xs";const CountState = ;
modules/counter/actions.js
import CountState from "./state.js"; { CountStatevalue++;} { CountStatevalue--;} { const payload = await ; CountStatevalue = payloadcount;} // auto increase count each 3s;
modules/counter/components/container.js
import CountState from "../state.js";import Increase Decrease Load from "../actions.js";import $ from "react-xs"; $;
modules/counter/components/index.js
import React from "react";import container from "./container"; count increase decrease load return <> <h1>count</h1> <button =>Increase</button> <button =>Decrease</button> <button =>Load</button> </> ;;
Working with class component
You can use react-xs with any component types, even class component. That helps you bring react-xs power to old components and refactor them all to functional components later
import React Component from "react";import render from "react-dom";import $ from "react-xs"; const Count = ;const Increase = Countvalue++; _ = $; <> <h1>Countvalue</h1> <button =>Increase</button> </> ;;