Skip to content

snakeUni/mut

Repository files navigation

mut

A tiny state management library based on Immer and useSyncExternalStoreExtra

Usage

Install

yarn add @bete/mutnpm install @bete/mut

Example

import * as React from 'react'
import * as ReactDOM from 'react-dom'
import { createStore, useSelector, Provider } from '@bete/mut'

interface State {
  count: number
  value: number
}

const store = createStore<State>({
  count: 0,
  value: 0
})

function App() {
  return (
    <Provider store={store}>
      <Label />
      <Label2 />
      <Buttons />
      <Reset />
    </Provider>
  )
}

function Label() {
  const selector = React.useCallback(state => state.count, [])
  const count = useSelector<State, number>(selector)
  console.log('render count:', count)
  return <div>count: {count}</div>
}

function Label2() {
  const selector = React.useCallback(state => state.value, [])
  const value = useSelector<State, number>(selector)
  console.log('render value:', value)
  return <div>value: {value}</div>
}

function Reset() {
  const reset = () => {
    store.reset()
  }

  return (
    <button onClick={reset}>decreaseValue</button>
  )
}

function Buttons() {
  const handleIncrease = () => {
    store.mutate(state => {
      state.count++
    })
  }

  const handleDecrease = () => {
    store.mutate(state => {
      state.count--
    })
  }

  const handleIncreaseV = () => {
    store.mutate(state => {
      state.value++
    })
  }

  const handleDecreaseV = () => {
    store.mutate(state => {
      state.value--
    })
  }
  return (
    <div>
      <button onClick={handleIncrease}>increase</button>
      <button onClick={handleDecrease}>decrease</button>
      <button onClick={handleIncreaseV}>increaseValue</button>
      <button onClick={handleDecreaseV}>decreaseValue</button>
    </div>
  )
}

ReactDOM.render(<App />, document.getElementById('root'))

Api

createStore

function createStore<T>(initialState: T): Store<T>
interface Store<T> {
  subscribe: (listener: Listener) => () => void
  unsubscribe: (listener: Listener) => void
  reset: () => void
  mutate: (updater: (draft: Draft<T>) => void | T) => void
  setState: (nextState: T | UpdateFn<T>) => void
  getState: () => T
}

Provider

const store = createStore()

<Provider store={store}>
  {children}
</Provider>

useSelector

function useSelector<T, K = unknown>(selector: (state: T) => K, equalityFn?: (a: K | undefined, b: K | undefined) => boolean): K

Example

const selector = React.useCallback(state => state.value, [])
const value = useSelector<State, number>(selector)

more about useSyncExternalStore

About

A tiny state management library based on Immer and useMutableSource

Resources

Stars

Watchers

Forks

Packages

No packages published