zustand #52
Replies: 4 comments 2 replies
-
const createStoreImpl: CreateStoreImpl = (createState) => {
type TState = ReturnType<typeof createState>
type Listener = (state: TState, prevState: TState) => void
let state: TState
const listeners: Set<Listener> = new Set()
const setState: StoreApi<TState>['setState'] = (partial, replace) => {
// TODO: Remove type assertion once https://github.com/microsoft/TypeScript/issues/37663 is resolved
// https://github.com/microsoft/TypeScript/issues/37663#issuecomment-759728342
const nextState =
typeof partial === 'function'
? (partial as (state: TState) => TState)(state)
: partial
if (!Object.is(nextState, state)) {
const previousState = state
state =
replace ?? (typeof nextState !== 'object' || nextState === null)
? (nextState as TState)
: Object.assign({}, state, nextState)
listeners.forEach((listener) => listener(state, previousState))
}
}
const getState: StoreApi<TState>['getState'] = () => state
const getInitialState: StoreApi<TState>['getInitialState'] = () =>
initialState
const subscribe: StoreApi<TState>['subscribe'] = (listener) => {
listeners.add(listener)
// Unsubscribe
return () => listeners.delete(listener)
}
const destroy: StoreApi<TState>['destroy'] = () => {
if (import.meta.env?.MODE !== 'production') {
console.warn(
'[DEPRECATED] The `destroy` method will be unsupported in a future version. Instead use unsubscribe function returned by subscribe. Everything will be garbage-collected if store is garbage-collected.',
)
}
listeners.clear()
}
const api = { setState, getState, getInitialState, subscribe, destroy }
const initialState = (state = createState(setState, getState, api))
return api as any
}
|
Beta Was this translation helpful? Give feedback.
-
Key features of Zustand
What things contribute to Zustand's lightweight feature?Zustand has small bundle size, which is typically around 1kB (minified and gzipped).
Zustand doesn't require your app to be wrapped in context providers. How?
export function useStore<TState, StateSlice>(
api: WithReact<ReadonlyStoreApi<TState>>,
selector: (state: TState) => StateSlice = identity as any,
equalityFn?: (a: StateSlice, b: StateSlice) => boolean,
) {
...
const slice = useSyncExternalStoreWithSelector(
api.subscribe,
api.getState,
api.getServerState || api.getInitialState,
selector,
equalityFn,
)
return slice
}
ImmutabilityZustand ensures immutability in state updates. This is achieved through its use of Immer, which is baked into Zustand's core functionality.
interface User {
name: string
age: number
}
interface UserState {
user: User
updateUser: (user: User) => void
}
const useUserStore = create<User>((set) => ({
user: { name: 'John', age: 30 },
updateName: (newName: string) => set((state) => {
// This looks like we're mutating state directly
state.user.name = newName
// But Zustand/Immer ensure a new immutable state is created
}),
...
})) How Zustand optimize performance despite ensuring immutability?Zustand is optimized to only trigger re-renders for components that are subscribed to the specific parts of the state that have changed. What happens when
|
Beta Was this translation helpful? Give feedback.
-
zustand 는 독일어로 상태, jotai 를 만든 카토 다이시가 제작에 참여
Core
React 의 hook API 에 적응한 설계 패턴 (사이드 이펙트 추가-즉시적, 삭제-콜백으로 후행적-을 제공) const subscribe = (listener, selector, equalityFn) => {
if (selector || equalityFn) {
return subscribeWithSelector(listener, selector, equalityFn);
}
listeners.add(listener);
return () => listeners.delete(listener);
}; 더 자세한건 코드 보면서 ㅎㅎ |
Beta Was this translation helpful? Give feedback.
-
다음주에 상태 관리 라이브러리 페어 프로그래밍 |
Beta Was this translation helpful? Give feedback.
-
zustand 라이브러리를 분석합니다 (다음주는 zod).
Beta Was this translation helpful? Give feedback.
All reactions