module state

λ¦¬μ•‘νŠΈμ—μ„œ λͺ¨λ“ˆ μƒνƒœλ₯Ό μ „μ—­ μƒνƒœλ‘œ μ‚¬μš©ν•˜λŠ” 방법

λͺ¨λ“ˆ μƒνƒœ(module state) μ‚΄νŽ΄λ³΄κΈ°

λͺ¨λ“ˆ μƒνƒœλŠ” λͺ¨λ“ˆ μˆ˜μ€€μ—μ„œ μ •μ˜λœ λ³€μˆ˜λ‹€. ν•¨μˆ˜ μ™ΈλΆ€μ—μ„œ μ •μ˜λœ λ³€μˆ˜λ₯Ό λͺ¨λ“ˆ μƒνƒœλΌκ³  κ°€μ •ν•˜κ³  μ˜ˆμ‹œ μ½”λ“œλ₯Ό μ‚΄νŽ΄λ³΄μž.

let state = {
    count: 0;
}

ν•΄λ‹Ή 객체가 λͺ¨λ“ˆ μƒνƒœλΌκ³  ν•  λ•Œ, 객체에 μ ‘κ·Όν•˜κ³  μƒνƒœλ₯Ό λ³€κ²½ν•˜λŠ” ν•¨μˆ˜λ₯Ό μ •μ˜ν•΄λ³΄μž.

export const getState = () => state

export const setState = (newState) => {
    state = newState
}

ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•΄ μƒνƒœλ₯Ό κ°±μ‹ ν•  수 있게 setStateλ₯Ό μˆ˜μ •ν•  수 μžˆλ‹€.

export const setState = (newState) => {
    state = typeof nextState === 'function' ? newState(state) : newState

setState((state) => {
    return {
        ...state,
        count: state.count + 1
    }
})
}

λͺ¨λ“ˆ μƒνƒœλ₯Ό 직접 μ •μ˜ν•˜μ§€ μ•Šκ³ , μƒνƒœμ™€ μƒνƒœμ— μ ‘κ·Όν•  수 μžˆλŠ” ν•¨μˆ˜κ°€ 내뢀에 μžˆλŠ” μ»¨ν…Œμ΄λ„ˆλ₯Ό λ§Œλ“€ 수 μžˆλ‹€.

export const createContainer = (initialState) =>
{
    let state = initialState
    const getState = () => state
    const setState = (newState) => {
        state = typeof newState === 'function' ? newState(state) : newState
    }
    return { getState, setState }

}

μ»¨ν…Œμ΄λ„ˆλŠ” λ‹€μŒκ³Ό 같이 μ‚¬μš©ν•  수 μžˆλ‹€.

const { getState, setState } = createContainer({ count: 0 })

λ¦¬μ•‘νŠΈμ—μ„œ λͺ¨λ“ˆ μƒνƒœ μ‚¬μš©ν•˜κΈ°

κ΅¬λ…μœΌλ‘œ λͺ¨λ“ˆ μƒνƒœ κ΅¬ν˜„ν•˜λŠ” μ—μ œ

type Store<T> = {
    getState: () => T;
    setState: (action: T | ((prev: T) => T)) => void;
    subscribe: (callback: () => void) => void;
}

const createStore = <T extends unknown>(
    initialState: T
): Store<T> => {
    let state = initialState
    const callbacks = new Set<() => void>();
    const getState = () => state
    const setState = (nextState: T | ((prev: T) => T))=> {
        state = typeof nextState === 'function' ? (nextState as (prev: T) => T)(state) : nextState;
        callbacks.forEach((callback) => callback())
    }
    const subscribe = (callback: () => void) => {
        callbacks.add(callback)
        return () => {
            callbacks.delete(callback)
        }
    }

    return { getState, setState, subscribe}
}

createStore μ‚¬μš©ν•˜κΈ°

import { createStore } from './store'

const store = createStore({ count: 0 })
store.setState({ count: 1})
store.subscribe(...)

store의 μƒνƒœ κ°’κ³Ό κ°±μ‹  ν•¨μˆ˜λ₯Ό νŠœν”Œλ‘œ λ°˜ν™˜ν•˜λŠ” μ‚¬μš©μž μ •μ˜ 훅을 λ§Œλ“€ 수 μžˆλ‹€.

const useStore = (store) => {
    const [state, setState] = useState(store.getState());

    useEffect(() => {
        const unsubscribe = store.subscribe(() => {
            setState(store.getState())
        });
        setState(store.getState())
        return unsubscribe
    }. [store])

    return [state, store.setState]
}

useStore μ‚¬μš©ν•˜κΈ°

const [state, setState] = useStore(store)

const inc = () => {
    setState((prev) => ({
        ...prev,
        count: prev.count + 1
    }))
}

return (
    <div>
        <h1>{state.count}</h1>
        <button onClick={inc}>Increment</button>
    </div>
)

Last updated