코딩/전역 상태관리

[Justand] 전역상태관리

카슈밀 2025. 2. 7. 03:39
반응형

완전 쓸데없이 복잡한 redux같은 것에 비해서 완전 쉬운 상태관리 기술.

recoil이랑 같은데?

 

import {LatLng} from 'react-native-maps';
import {create} from 'zustand';

interface LocationState {
  moveLocation: LatLng | null;
  setMoveLocation: (location: string) => void;
}

const useLoactionStroe = create<LocationState>(set => ({
  moveLocation: null,
  setMoveLocation: (moveLocation: LatLng) => {
    set({moveLocation});
  },
}));

export default useLoactionStroe;

 

오우 편해라 근데, recoil이랑 차이점은 recoil은 함수 내부에서 쓰는 느낌이고,

이건 그냥 스토어에서 호출해서 사용하는 방식이네.
규모가 커지면 어떻게 되려나?

 

 

 

========== NOT Working ==========================================

LLM에 물어보고 진행될거라 생각한 부분인데, 해당 부분은 적용되지 않았습니다...

적용되지 않습니다. 제길...

공식 문서에는 redux를 도입하라는 글이 있는데 굳이 어려운 리덕스를...?

또한, unshallow 뭐시기 있는데 찾아보고 있습니다

 

찾아보니 방법이 있더라 ㅎ

나는 리덕스를 주로 쓰는 유저라서 그런지, 리듀서 개념을 도입할 수 있었음.

import { LatLng } from 'react-native-maps';

interface LocationState {
  moveLocation: LatLng | null;
}

interface LocationActions {
  setMoveLocation: (location: LatLng) => void;
}

export type LocationStore = LocationState & LocationActions;

export const createLocationReducer = (
  set: (fn: (state: LocationState) => LocationState) => void
): LocationStore => ({
  moveLocation: null, // ✅ 초기값을 여기 포함
  setMoveLocation: (moveLocation: LatLng) => {
    set(state => ({ ...state, moveLocation }));
  },
});


/// store.js
import { create } from 'zustand';
import { LocationStore, createLocationReducer } from './locationReducer';

const useLocationStore = create<LocationStore>((set) => createLocationReducer(set));

export default useLocationStore;

 

요렇게 리듀서 하나로 뽑아오는 방식.

 

아래가 다중 리듀서를 포함하는 방식.

// 리듀서 1
import { LatLng } from 'react-native-maps';

interface LocationState {
  moveLocation: LatLng | null;
}

interface LocationActions {
  setMoveLocation: (location: LatLng) => void;
}

export type LocationStore = LocationState & LocationActions;

export const createLocationReducer = (
  set: (fn: (state: LocationState) => LocationState) => void
): LocationStore => ({
  moveLocation: null,

  setMoveLocation: (moveLocation: LatLng) => {
    set(state => ({ ...state, moveLocation }));
  },
});


// 리듀서 2
interface MapState {
  zoomLevel: number;
  mapMode: 'standard' | 'satellite' | 'hybrid';
}

interface MapActions {
  setZoomLevel: (zoom: number) => void;
  setMapMode: (mode: 'standard' | 'satellite' | 'hybrid') => void;
}

export type MapStore = MapState & MapActions;

export const createMapReducer = (
  set: (fn: (state: MapState) => MapState) => void
): MapStore => ({
  zoomLevel: 10,
  mapMode: 'standard',

  setZoomLevel: (zoomLevel: number) => {
    set(state => ({ ...state, zoomLevel }));
  },

  setMapMode: (mapMode: 'standard' | 'satellite' | 'hybrid') => {
    set(state => ({ ...state, mapMode }));
  },
});

// 루트리듀서
import { create } from 'zustand';
import { LocationStore, createLocationReducer } from './locationReducer';
import { MapStore, createMapReducer } from './mapReducer';

// 여러 개의 리듀서를 통합한 상태 타입
type StoreState = LocationStore & MapStore;

const useLocationStore = create<StoreState>((set) => ({
  ...createLocationReducer(set),
  ...createMapReducer(set),
}));

export default useLocationStore;


// 사용예시
import React from 'react';
import { View, Button, Text } from 'react-native';
import useLocationStore from './useLocationStore';

const MapComponent = () => {
  const { moveLocation, setMoveLocation, zoomLevel, setZoomLevel, mapMode, setMapMode } = useLocationStore();

  return (
    <View>
      <Text>현재 위치: {moveLocation ? `${moveLocation.latitude}, ${moveLocation.longitude}` : '없음'}</Text>
      <Text>줌 레벨: {zoomLevel}</Text>
      <Text>지도 모드: {mapMode}</Text>

      <Button title="위치 변경" onPress={() => setMoveLocation({ latitude: 37.5665, longitude: 126.9780 })} />
      <Button title="줌 레벨 증가" onPress={() => setZoomLevel(zoomLevel + 1)} />
      <Button title="위성 모드" onPress={() => setMapMode('satellite')} />
    </View>
  );
};

export default MapComponent;

 

규모가 커질때, 이렇게 코드를 분할해야지 깔끔해지더라 ㅎㅎ

관리도 좋고

728x90