An open API service indexing awesome lists of open source software.

https://github.com/zephraph/mustate

Minimal immutable state management for React
https://github.com/zephraph/mustate

Last synced: 6 months ago
JSON representation

Minimal immutable state management for React

Awesome Lists containing this project

README

          

# Mustate

> Minimal immutable state management for React

## Quick Start

```bash
npm install @just-be/mustate
```

**Table of Contents**

- [Example](#example)
- [API](#api)
- [`createStore(initialState: State): Store`](#createstorestateintialstate-state-storestate)
- [`createStoreHook(store: Store): useStore`](#createstorehookstatestore-storestate-usestore)
- [`createStoreWithHook(initialState: State): [Store, useStore]`](#createstorewithhookstateintialstate-state-storestate-usestore)
- [`store`](#store)
- [`useStore(selector: (state: State) => Value): Value`](#usestorevalueselector-state-state--value-value)

## Example

```jsx
import React from 'react';
import { render } from 'react-dom';
import { createStoreWithHook } from '@just-be/mustate';

// Create a lil' store with some state
let [store, useStore] = createStoreWithHook({
count: 0,
});

// The app doesn't need a provider
function App() {
return (





);
}

// You can mutate the store from anywhere you want to,
// even outside of React code. Mutate is based on mutative.
function increment() {
store.mutate(state => {
state.count++;
});
}

// Or you can update it like React.useState's update
function decrement() {
store.set(prevState => ({
...prevState,
count: prevState.count - 1
}));
}

// You don't need to pass the store down as a prop either
function Buttons() {
return (

-
+

);
}

// Lastly, you can subscribe to "slices" of state by passing a selector to
// useStore. The component will only be re-rendered when that portion of state
// changes.
function Label() {
const count = useStore(state => state.count);
return

The count is {count}

;
}

render(, window.root);
```

## API

### `createStore(initialState: State): Store`

Create a mustate `store` given some initial state. Returns a store instance that can be used anywhere in your application.

```jsx
import { createStore } from '@just-be/mustate';

const store = createStore({ count: 0, name: 'Alice' });
```

### `createStoreHook(store: Store): useStore`

Create a React hook for a specific store. This allows you to subscribe to state changes in React components.

```jsx
import { createStore, createStoreHook } from '@just-be/mustate';

const store = createStore({ count: 0 });
const useStore = createStoreHook(store);

// In a React component
function Counter() {
const count = useStore(state => state.count);
return

{count}
;
}
```

### `createStoreWithHook(initialState: State): [Store, useStore]`

Convenience function that combines `createStore` and `createStoreHook`. This is equivalent to calling both functions separately.

```jsx
import { createStoreWithHook } from '@just-be/mustate';

const [store, useStore] = createStoreWithHook({ count: 0, name: 'Alice' });
```

The `store` has the following API you can use in or out of React:

#### `store`

| **Method** | **Description** |
| ----------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `get()` | Get the current state. Do not use this inside of React, you should instead use [`useStore`](#usestorevalueselector-state-state--value-value) |
| `set(nextState: S \| (prevState: S) => V): void;` | Set state. This can either take a new value or and updater function (just like React.useState's updater) |
| `on(listener: Function): () => void;` | Subscribe to store. Pass in a callback function that will be executed on updates. `on()` returns the unsubscribe function for your convenience. |
| `off(listener: Function): void;` | Unsubscribe a given listener function |
| `reset(): void` | Set state back to the `initialState` used when creating the store |
| `mutate(updater: (draft: Draft) => void \| S): void;` | Mutative-style updater function. |

#### `useStore(selector: (state: State) => Value): Value`

React hook to subscribe to mustate state.

```jsx
const selector = state => state.count;

function Label() {
const count = useStore(selector);
return

The count is {count}

;
}
```

You can use props with mustate selector.

```jsx
function User({ id }) {
const user = useStore(state => state.users[id]);
return

The username is {user.name}

;
}
```

## Inspiration

This project was inspired by Jared Palmer's [Mutik](https://github.com/jaredpalmer/mutik).