logo

Simple Zustand

Feb 4 · 3min



export function create(createState: any) {
  let state: any
  const listeners = new Set<(state: any, prevState: any) => void>()
  const getState = () => state
  const setState = (partial: unknown) => {
    const prevState = state
    if (typeof partial === 'function') {
      state = { ...state, ...partial(state) }
    }
    else if (typeof partial === 'object' && partial !== null) {
      state = { ...state, ...partial }
    }
    listeners.forEach(l => l(state, prevState))
  }
  const subscribe = (l: (state: any, prevState: any) => void) => {
    listeners.add(l)
    return () => { listeners.delete(l) }
  }

  const api = { setState, getState, subscribe }
  state = createState(setState, getState)
  return api
}


interface Store {
  count: number
  increment: any
}

const store = create(set => ({
  count: 0,
  increment: () => set((state: Store) => ({ count: state.count + 1 })),
}))

export function useStore() {
  const [,tick] = useState(0)
  useEffect(() => {
    const unsubscribe = store.subscribe(() => {
      tick(prev => prev + 1)
    })
    return () => unsubscribe()
  }, [])
  return [store.getState()]
}
export default function Component() {
  const state = useClickPathStore.getState()
  const [store] = useStore()
  return (
    <div>
      <div onClick={store.increment}>
        Count:
        {' '}
        {store.count}
      </div>
    </div>
  )
}
© Cloud