공통 패턴
실전 활용을 위한 패턴들입니다.
@ilokesto/store로 상태를 관리할 때 효과적인 패턴들을 살펴봅니다.
모듈 범위 스토어 (Module-scope Store)
공유되는 전역 상태의 경우, 모듈 수준에서 스토어를 생성하고 이를 내보낼 수 있습니다.
// store.ts
export const authStore = new Store({ user: null, isAuthenticated: false });액션과 유사한 래퍼 (Action-like Wrappers)
모든 곳에서 직접 setState를 호출하는 대신, 업데이트를 의미론적인 함수(액션)로 감싸서 관리하십시오.
export const login = (user: User) => {
authStore.setState({ user, isAuthenticated: true });
};
export const logout = () => {
authStore.setState({ user: null, isAuthenticated: false });
};읽기/쓰기 분리 (Read/Write Separation)
접근 제어를 위해 스토어의 다른 부분들을 개별적으로 내보낼 수 있습니다.
// 읽기 전용 뷰와 액션만 내보냄
export const getAuthState = () => authStore.getState();
export const subscribeToAuth = (listener: () => void) =>
authStore.subscribe(listener);재설정 패턴 (Reset Pattern)
getInitialState()를 사용하여 스토어를 초기 상태로 쉽게 재설정하십시오.
const resetStore = () => {
store.setState(store.getInitialState());
};파생된 값 (Derived Values)
Store는 원시 원자(raw atom)만을 관리하므로, 필요할 때마다 파생된 상태를 계산할 수 있습니다.
const getFullName = () => {
const { firstName, lastName } = userStore.getState();
return `${firstName} ${lastName}`;
};스토어 분리 (Splitting Stores)
모든 것을 하나의 거대한 스토어에 담을 필요는 없습니다. 관심사별로 여러 스토어를 분리하여 관리하십시오.
const themeStore = new Store("light");
const userStore = new Store({ id: 1, name: "Alice" });테스트 패턴 (Testing Patterns)
스토어 로직은 프레임워크 의존성이 없기 때문에 테스트하기가 매우 간단합니다.
test("increments count", () => {
const store = new Store({ count: 0 });
store.setState((prev) => ({ ...prev, count: prev.count + 1 }));
expect(store.getState().count).toBe(1);
});안티 패턴
- 깊은 수정(Deep mutation): 새로운 객체를 반환하는 대신 상태 속성을 직접 수정하는 것.
- 동기식 루프(Sync loops): 스토어를 구독하고 리스너 내부에서 동일한 스토어의
setState를 호출하는 것. - 모든 것을 하나의 스토어에 담기: 단일 원자가 강력하기는 하지만, 관련 없는 상태를 과도하게 중앙 집중화하면 컨슈머에게 불필요한 알림이 발생할 수 있습니다.