Skip to main content

Zustand Context

@toktokhan-dev/zustand-create-store-context 패키지는 Zustand 스토어에 대한 context, provider, hoc 를 생성함으로써, Zustand를 사용한 로컬 상태 관리를 가능하게 합니다.

zustand with next.js

Nextjs 와 같은 SSR 환경에선, 서버에서의 상태변경이 일어날 경우 각기 다른 클라이언트에서 서버상태를 공유하게 되는 이슈가 생길 수 있기 때문에, Zustand 를 Component를ontext 와 함께 사용하는 것을 권장합니다. Zustand의 공식 문서에서도 이러한 패턴을 설명하고 있으니, Zustand 공식문서를 참고해주세요.

Installation

only zustand-with-setter

npm i @toktokhan-dev/zustand-create-store-context

or with zustand-with-setter

npm i @toktokhan-dev/zustand-react

Usage

createStoreContext

zustand 의 create 와 완전히 동일한 값을 받아 context 를 생성할 수 있습니다.

import { createStoreContext } from '@toktokhan-dev/zustand-create-store-context'

type Store = {
count: number
setCount: (count: number) => void
}

const { Provider, useContext, withProvider } = createStoreContext<Store>((set, get, store) => ({
count: 0,
setCount: (count: number) => set(() => ({ count })),
}))

Provider

Provider 는 자식 컴포넌트에게 context 를 전달하는 역할을 합니다.

const App = () => (
<Provider>
<Component />
</Provider>
)

인자로 initial state 를 받아 초기 상태를 설정할 수 있습니다.

initial: Partial<Store>

const App = () => (
<Provider initial={{ count: 10 }}>
<Component />
</Provider>
)

useContext

useContext 는 context 를 사용하여 상태를 가져오는 역할을 합니다.

const Component = () => {
const count = useContext((store) => store.count)
const setCount = useContext((store) => store.setCount)
return (
<div>
<button onClick={() => setCount(count + 1)}>+</button>
<span>{count}</span>
</div>
)
}

withProvider

withProvider 는 Component 를 Provider 로 감싸 컨텍스트를 전달하는 HOC 입니다.

const Component2 = withProvider(Component)

// Same
const Component2 = (props: PropsOf<typeof Component>) => (
<Provider>
<Component {...props}/>
</Provider>
)

2번째 인자에 initial state 를 전달할 수 있습니다.

initial: Partial<Store>

const Component2 = withProvider(Component, { count: 10 })

Overview

import { createStoreContext } from '@toktokhan-dev/zustand-create-store-context'

const { Provider: CountProvider, useContext: useCountContext, withProvider: withCountProvider } = createStoreContext((set) => ({
count: 0,
setCount: (count: number) => set(() => ({ count })),
}))

const Component = () => {
const count = useCountContext((store) => store.count)
const setCount = useCountContext((store) => store.setCount)
return (
<div>
<button onClick={() => setCount(count + 1)}>+</button>
<span>{count}</span>
</div>
)
}

const Component2 = withProvider(Component)

const App = () => (
<>
<CountProvider>
<Component />
</CountProvider>
<CountProvider initialState={{ count: 10 }}>
<Component />
</CountProvider>
<Component2 />
</>
)