Skip to content

orYoffe/jstates-react

Repository files navigation

SWUbanner

Warning: Project is not actively maintained. This project was supposed to be an example of how simple state libraries can be.






jstates Logo







JStates for React.js

A subscribe function to and a useSubscribe hook use JStates state library

NPM

GitHub issues license npm bundle size npm

Install

npm i -S jstates-react

Usage

Creating a state instance

// counterState.js
import { createState } from "jstates-react";

const counterState = createState({ counter: 0 });

export default counterState;

Making state changes

// Counter.jsx
import counterState from "./counterState";

function Counter() {
  return (
    <div>
      <button
        onClick={() => {
          counterState.setState(({ counter }) => ({ counter: counter + 1 }));
        }}
      >
        add one +
      </button>
      <button
        onClick={() => {
          counterState.setState(({ counter }) => ({ counter: counter - 1 }));
        }}
      >
        remove one -
      </button>
      <button
        onClick={() => {
          counterState.setState({ counter: 0 });
        }}
      >
        reset
      </button>
    </div>
  );
}
export default Counter;

Subscribing to state changes

// App.jsx with hooks
import { useSubscribe } from "jstates-react";
import counterState from "./counterState";
import Counter from "./Counter";

function App() {
  const { counter } = useSubscribe(counterState);
  return (
    <div>
      <p>Current counter: {counter}</p>
      <Counter />
    </div>
  );
}

export default App;
// App.jsx with HOC
import { subscribe } from "jstates-react";
import counterState from "./counterState";
import Counter from "./Counter";

function App({ states }) {
  return (
    <div>
      <p>Current counter: {states[0].counter}</p>
      <Counter />
    </div>
  );
}

export default subscribe(App, counterState);

useSubscribe hook

useSubscribe should be called with one jstates state instance. Then would get updated whatever changes are made to the state it subscribed to

const someState = createState({ userLikes: "nothing yet" });

function App() {
  const { userLikes } = useSubscribe(someState);

  return (
    <div>
      <p>You like: {userLikes}</p>
      <button onClick={() => someState.setState({ userLikes: "Monkeys" })}>
        Monkeys
      </button>
      <button onClick={() => someState.setState({ userLikes: "Horses" })}>
        Horses
      </button>
    </div>
  );
}

HOC subscribe

Minimal requirement

subscribe should be called with a component and a state or an array with at least one jstates state instance. Then would get updated whatever changes are made to the states it subscribed to

const someState = createState({});

subscribe(Component, someState);

// With multiple states
const someOtherState = createState({});

subscribe(Component, [someState, someOtherState]);

mapStatesToProps

subscribe can be called with an additional function to map the states it subscribes to into the props of the component. This pattern can be seen also in libraries like react-redux and is easy to test

const mapStatesToProps = (counterState, otherState) => ({
  counter: counterState.counter,
  someOtherValue: otherState.someOtherValue,
});

function App({ counter, someOtherValue }) {
  return (
    <div>
      <p>Current counter: {counter}</p>
      <p>Another value: {someOtherValue}</p>
      <Counter />
    </div>
  );
}

subscribe(App, [counterState, otherState], mapStatesToProps);