0.2.0 • Published 2 years ago

trian v0.2.0

Weekly downloads
2
License
MIT
Repository
github
Last release
2 years ago

Trian

Trian is my experimental state management library for React, heavily inspired by Recoil.

  • Type Safe
  • Distributed - No single state object
  • Decoupled - No React Hook requirement for just running

Motivation

  • I like React Hooks, but I don't want to lock all the logic into Hooks.
    • Is it really a good practice to manage any states and effects by Hook? Even if they are UI-independent?
  • Recoil seems good so I made a minimum version that suits my preference.

Code Sample

Play without React

import { block, createStore, createDispatch, Thunk } from 'trian';

const Count = block({
    default: () => 0,
});

const Increment = (n: number = 1): Thunk => ({ update }) => {
  update(Count, (cnt) => cnt + n);
};

const store = createStore();

const dispatch = createDispatch(store);

console.log(store.getValue(Count)); //=> 0

dispatch(Increment);
console.log(store.getValue(Count)); //=> 1

dispatch(Increment, 20);
console.log(store.getValue(Count)); //=> 21

Use with React

import React from 'react';
import ReactDOM from 'react-dom';
import { block, createStore, TrianProvider, useValue, useDispatch, Thunk } from 'trian';

const Count = block({
  default: () => 0,
});

const Increment = (n: number = 1): Thunk => ({ update }) => {
  update(Count, (cnt) => cnt + n);
};

function Counter() {
  const count = useValue(Count);
  const dispatch = useDispatch();
  return (
    <div>
      <h1>Count: {count}</h1>
      <button onClick={() => dispatch(Increment)}>Increment</button>
    </div>
  );
}

const store = createStore();

ReactDOM.render(
  <TrianProvider store={store}>
    <Counter />
  </TrianProvider>,
  document.getElementById('root')
);
const store = createStore();

// FYI: You can customize the dispatcher.
// This maybe be useful for component testing.
const histories = [];
const dispatch = (action, ...args) => {
  histories.push({ action, args });
};
render(
  <TrianProvider store={store} dispatch={dispatch}>
    <Counter />
  </TrianProvider>
);

// FYI: You can change the state from outside of React components.
// This maybe be useful for component testing.
setTimeout(() => {
  store.setValue(Count, 100); //=> Update view
}, 1000);
  • useValue, useAsyncValue
  • useBlock
  • useSelector, useAsyncSelector
  • useAction
  • useDispatch