1.1.1 • Published 3 years ago

kiss-react-state v1.1.1

Weekly downloads
-
License
MIT
Repository
github
Last release
3 years ago

KISS-REACT-STATE

This module is aimed at reducing the work of web developers while setting up simple state management. The goal is to become a modular context state management simplification while still using Types to get your IDE to help you. It follows the Keep It Super Simple philosophy.

The work was based on my previous redux-auto-actions library, and after getting a termendous amount of inspiration from Kent C. Dodds article Application State Management with React - many thanks! Keep them comming :)

Import

import {
    StoreModule
} from 'kiss-react-state';

Usage

1 First create CountContext.ts

import React from 'react';
import { AnyAction, ProcessAction, SetupStore } from './index';

enum ActionType {
  INCREMENT,
  DECREMENT,
  RESET,
}
type CountState = { counter: number };

const s = new SetupStore<ActionType, CountState>('', { counter: 0 });

/**
 * Exportable Actions
 */
const increment = s.setPayloadAction<number>(
  ActionType.INCREMENT,
  (state, action) => ({
    ...state,
    counter: state.counter + action.payload,
  })
);
const decrement = s.setPayloadAction<number>(
  ActionType.DECREMENT,
  (state, action) => ({
    ...state,
    counter: state.counter - action.payload,
  })
);
const reset = s.setSimpleAction(ActionType.RESET, () => s.getInitialState());

/**
 * Processes
 */
type AppProcessType<R> = ProcessAction<R, CountState, null, AnyAction>;

type TestAsyncProcess = (amount: number) => AppProcessType<boolean>;
const testAsync: TestAsyncProcess = (amount) => (dispatch) => {
  setTimeout(() => dispatch(increment(amount)), 1000);
  return true;
};

const { Provider: CountProvider, useContext: useCount } = s.build(
  { increment, decrement, reset },
  { testAsync }
);

export { CountProvider, useCount };

2 Now add the Context to the DOM Provider (adding to App.ts )

import React from 'react';

import { CountProvider } from './CountContext';
import { CountPage } from './Page';
import './App.css';

export const App = () => (
  <div className="App">
    <header className="App-header">
      <CountProvider>
        <CountPage />
      </CountProvider>
    </header>
  </div>
);

3 You can create your CounterPage.tsx

import React from 'react';
import { CountProvider, useCount } from './CountContext';

export function Counter() {
  const {
    actions: { increment, decrement },
    processes: { testAsync },
  } = useCount();
  return (
    <>
      <button onClick={() => increment(1)}>+</button>
      <button onClick={() => decrement(1)}>-</button>
      <button onClick={() => testAsync(10)}>Test async (process/akind to thunk)</button>
    </>
  );
}

export function CountDisplay() {
  const { state } = useCount();
  return <div>The current counter count is {state.counter}</div>;
}

export function CountPage() {
  return (
    <div>
      <CountProvider>
        <CountDisplay />
        <Counter />
      </CountProvider>
    </div>
  );
}

Supper simple right? In 3 components, with very little boillerplate you can setup termendous amounts of power. Do keep an eye on re-renderers and now that you can setup any unmber of contexts you want, you could modulate your state way better than with redux. This way you run only specific hooks and can even provide update logics between stores by using useEffect . Be careful though! Every time you do that, double check you don't run into infinite loops or cyclic updates (ContextA Store -> updates -> ContextB Store -> which in turn updates Context A Store).

Have fun!

Performance

In order to be a bit more true to the test, we did 3 trials

  • Accumulating

    kiss-react-state

Operationmsmsms
Added 1003 33
Added 1 1001 21
Added 11 1002 22
Added 1 011 100143 132154
Added 11 011 1001019 9751026
Added 61 011 1002303 22422228

react-redux

Operationmsmsms
Added 100344
Added 1 100122
Added 11 100224
Added 1 011 1009711494
Added 10 011 10015431545932
Added 30 011 100337832122222
  • Resetting

    kiss-react-state

Operationmsmsms
Added 100111
Added 1 000111
Added 10 000222
Added 1 000 000321113298
Added 10 000 000112810721254
Added 50 000 000212323472190

react-redux

Operationmsmsms
Added 100323
Added 1 000111
Added 10 000222
Added 1 000 000858589
Added 10 000 000158715731872
Added 50 000 000509951474675

Help with work

Just fork and do a PR :) I will add you to the colaborators list with a BIG thank you!

  • If you want to buy me a coffee or a beer as a thank you, I'm very much appreciated :stuck_out_tongue_winking_eye: Donate

Guidelines

Whenever a new master is deployed, it should be tagged with the new deployed version. After we reach version 1.0.0 as the first release (production ready). After that, we follow semantic versioning.

Publishing

Remember to always publish on a merge request. Pipeline master:only actions will be created in the future, once we stabilize this library.

Enjoy!

Troubleshooting

  • Create an issue