https://github.com/jaredpalmer/mutik
A tiny (495B) immutable state management library based on Immer
https://github.com/jaredpalmer/mutik
immer react state-management
Last synced: 9 days ago
JSON representation
A tiny (495B) immutable state management library based on Immer
- Host: GitHub
- URL: https://github.com/jaredpalmer/mutik
- Owner: jaredpalmer
- License: mit
- Created: 2020-03-12T21:04:01.000Z (about 5 years ago)
- Default Branch: master
- Last Pushed: 2023-01-07T15:54:06.000Z (over 2 years ago)
- Last Synced: 2025-03-31T09:04:33.827Z (16 days ago)
- Topics: immer, react, state-management
- Language: TypeScript
- Homepage: https://npm.im/mutik
- Size: 988 KB
- Stars: 325
- Watchers: 4
- Forks: 8
- Open Issues: 26
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- Funding: .github/FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
- awesome-list - mutik
- javascript-awesome-packages - `Mutik` - A tiny (495B) immutable state management library based on Immer
- javascript-awesome-packages - `Mutik` - A tiny (495B) immutable state management library based on Immer
README
> A tiny (495B) immutable state management library based on Immer
## Quick Start
```bash
yarn add mutik
```or
[](https://codesandbox.io/s/mutik-2so66?fontsize=14&hidenavigation=1&theme=dark)
**Table of Contents**
- [Example](#example)
- [API](#api)
- [`createStore(intialState: S): Store`](#createstoresintialstate-s-stores)
- [`store`](#store)
- [`useSelector(selector: (s: S) => V)`](#useselectors-vselector-s-s--v)
- [``](#provider-)
- [Author](#author)
- [Inspiration](#inspiration)## Example
To use Mutik with React, you'll need to install React and React DOM from the experimental release channel because Mutik uses the recently-merged `useMutableSource` hook internally.
```bash
yarn add react@experimental react-dom@experimental
``````jsx
import React from 'react';
import { render } from 'react-dom';
import { createStore, Provider, useSelector } from 'mutik';// Create a lil' store with some state
let store = createStore({
count: 0,
});// Pass the store to the Provider.
function App() {
return (
);
}// You can mutate the store from anywhere you want to,
// even outside of React code. Mutate is based on immer.
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 subcribe to "slices" of state with useSelector
// Note: be sure to memoize these with React.useCallback if you need to select based on props
function Label() {
const selector = React.useCallback(state => state.count, []);
const count = useSelector(selector);
returnThe count is {count}
;
}render(, window.root);
```## API
### `createStore(intialState: S): Store`
Create a Mutik `store` given some initial state. 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 [`useSelector`](#useselectors-vselector-s-s--v) |
| `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;` | Immer-style updater function. |### `useSelector(selector: (s: S) => V)`
React hook to subscribe to Mutik state. Must be called underneath a Mutik `Provider`.
```jsx
const selector = state => state.count;function Label() {
const count = useSelector(selector);
returnThe count is {count}
;
}
```You can use props with Mutik selector. For performance, it's a good idea to memoize the selector with `React.useCallback`. For example:
```jsx
function User({ id }) {
const selector = React.useCallback(state => state.users[id], [id]);
const user = useSelector(selector);
returnThe username is {user.name}
;
}
```### ``
Mutik context provider. Pass your store as `store` prop. For example:
```jsx
import React from 'react';
import { createStore, Provider } from 'mutik';// Create a lil' store with some state
let store = createStore({
count: 0,
});// Pass the store to the Provider.
function App() {
return (
{/* ... stuff */}
);
}
```## Author
- Jared Palmer [@jaredpalmer](https://twitter.com/jaredpalmer)
## Inspiration
- [bey](https://github.com/jamiebuilds/bey)
- [react-copy-write](https://github.com/aweary/react-copy-write)
- [Brian Vaughn's fake redux](https://codesandbox.io/s/react-redux-usemutablesource-eyxoe)---
> MIT License