Neodymium Plated Magnet

    synaptik
    TypeScript icon, indicating that this package has built-in type declarations

    2.1.2 • Public • Published

    ⚡️ Synaptik

    The state management library you've been waiting for

    Build Status codecov npm npm JavaScript Style Guide MIT License

    Table of Contents

    1. Why synaptik?
    2. Usage
    3. Docs

    Why Synaptik?

    Redux is a great tool and undoubtedly helped push the web forward by providing a strong mental model around global state. Redux, however, does come with its flaws:

    1. Repetition. The boilerplate, just for the most simple task, has become wearisome.
    2. Distributed logic. Business logic is spread out. Some logic lives in the action, some in the reducer, and some in the component.
    3. Middleware. Apart from logging and handling promises, middleware ends up being a hassle and makes debugging terribly difficult.

    Some other state management solutions in the wild have attempted to solve these issues. Two to note, and mainly where inspiration for Synaptik was drawn, are Unstated and Statty. Both use a basic component with render props to access global state ❤️ - but each had shortcomings.

    Unstated's Container works well to control business logic and encapsulate several pieces of state, all while feeling very familiar to Component local state. Containers, otherwise known as Stores in synaptik, live on, only accessed differently on render.

    Statty's approach is great - by using a select prop to pluck only the pieces of state you want, it's easy to inject derived state as a render prop, while also making it easy to check for referential equality to prevent unecessary renders. Statty was only missing a dedicated logic unit.

    Thus, Synaptik was born - marrying the concepts of Unstated and Statty in what looks to be a happy union. Hope y'all like it! 😎

    Usage

    Begin by creating your first store, which extends from Store.

    import { Store } from 'synaptik';
    import { Stores } from 'app/lib/synaptik';
     
    interface TodoState {
      input: string;
      entries: string[];
    }
     
    export default class TodoStore extends Store<TodoState, Stores> {
      state = {
        input: '',
        entries: [],
      };
     
      updateInput = (input: string) => {
        this.setState({ input });
      };
     
      addTodo = (todo: string) => {
        // setState acts like React component's setState,
        // except that it runs synchronously
        this.setState({
          entries: [...this.state.entries, todo],
        });
      };
    }

    Next, create a file that will export your store Provider and useSynapse hook:

    // app/lib/synaptik.ts
    import { createSynaptik } from 'synaptik';
    import * as stores from './stores';
     
    const { Provider, useSynapse } = createSynaptik(stores);
     
    export type Stores = typeof stores;
    export { Provider, useSynapse };

    Lastly, wrap your application with the Provider.

    import { render } from 'react-dom';
    import { Provider } from 'app/lib/synaptik';
     
    /*
      `stores` look something like the following. The keys are used as
      identifier's when accessing the store during render.
      {
        todos: TodoStore,
        ...etc
      }
    */
     
    const App = () => (
      <Provider>
        <Entry />
      </Provider>
    );
     
    render(<App />, window.root);

    Now, you can access your stores and state with the useSynapse hook:

    NOTE: if your selector functions returns non-primitive values in an array, you must mark the array as const for Typescript to properly infer the signatures of the destructured elements

    import { useSynapse } from 'app/lib/synaptik';
     
    function TodoList() {
      const [todos, input, updateInput, addTodo] = useSynapse(({ todos }) => [
        todos.state.entries, 
        todos.state.input, 
        todos.updateInput, 
        todos.addTodo
      ]);
     
      return (
        <>
          <ul>
            {todos.map(todo => (
              <li>{todo}</li>
            ))}
          </ul>
     
          <form onSubmit={addTodo}>
            <input value={input} onChange={updateInput} />
            <button type="submit">Submit</button>
          </form>
        </>
      );
    }

    🚀 You've done it! You have your first todo app up and running 4 simple steps.

    LICENSE

    MIT License © HeyDoctor, LLC.

    Keywords

    none

    Install

    npm i synaptik

    DownloadsWeekly Downloads

    607

    Version

    2.1.2

    License

    MIT

    Unpacked Size

    24.8 kB

    Total Files

    10

    Last publish

    Collaborators

    • choochootrain
    • erikshestopal
    • schlegz
    • kylealwyn
    • heydoctor-ci
    • gerrymi
    • rosaliejames
    • wjossey