React, Redux로 다크 모드 설정하기

Haram B·2022년 6월 30일
0

Frontend

목록 보기
1/5

다크 모드 만들기에 아주 꽂혀버려서 상태 관리를 하게 되었다
Redux를 사용해서 전체 웹에서의 상태(display mode)를 관리하고자 한다

설치

npm install @reduxjs/toolkit

redux 폴더를 하나 만들고 action.js, reducers.jsx, store.jsx 파일을 만든다.
action.js

export const IS_DARK = false;

export function displayMode(mode) {
    return {
        type: IS_DARK,
        mode,
    };
}

reducers.jsx

// state
// false or true
import { IS_DARK } from "./actions";

const initialState = false;
export function setMode(previousState = initialState, action){
    // 초기값 세팅
    // if (previousState === undefined) {
    //     return [];
    // }
    if (action.type === IS_DARK) {
        return action.mode;
    }

    return previousState;
}

store.jsx

import { configureStore } from '@reduxjs/toolkit';
import { setMode } from './reducers';

const display = configureStore({reducer: setMode});
export default display

이렇게 쓰고 index.js에서

import {displayMode } from "./redux/actions";

display.subscribe(() => {
  console.log(display.getState());
});
display.dispatch(displayMode(true));
display.dispatch(displayMode(false));

결과를 확인할 수 있다. displayMode에 true를 넣어주는지, false를 넣어주는지에 따라 console에 이렇게 결과가 출력된다.

redux에서는 store는 단일 스토어이다.
store에서 각 component의 상태를 관리 하게 된다.
스토어를 만들기 위해서 액션을 정의하고, 액션을 사용하는 리듀서를 만들고 합쳐진 리듀서를 인자로 단일 스토어를 생성한다.
스토어를 사용하려면

import react-redux

import 후 connect 함수를 이용해서 컴포넌트에 연결하면 된다.

index.js에서

<React.StrictMode>
    <App  display={display}/>
</React.StrictMode>

App.js로 display(스토어)를 보내준다

App.js

const [state, setState] = useState(display.getState);
useEffect(() => {
  const unsubscribe = display.subscribe(() => {
    setState(display.getState());
  });
  return () => {
    unsubscribe();
  }
}, [display]);
const changeMode = () => {
	display.dispatch(displayMode(!state));
}

여기서 changeMode는 원래 모드를 바꿔주던 전구 아이콘 버튼 안에 있던 함수이다. (onClick으로)

<p>{state.toString()}</p>

를 넣어서 확인해보자

true false로 잘 바뀌는 것을 볼 수 있다 -> 라고 썼는데 gif가 재생이 안되는군,,, 보이지 않지만 잘.. 바뀌었습니다😅

+upgrade ver(?) * HOOK으로 만들어서 전체 component에서 사용 가능하도록 하기
여기에선 createContext라는 것을 이용한다

contexts 폴더를 만들고 그 안에 ReduxContext.js 파일을 만들어 다음과 같이 적는다

import { createContext } from "react";
const ReduxContext = createContext();
export default ReduxContext;

그리고 hooks 폴더에 useReduxState.js와 useReduxDispatch.js를 만든다.
useReduxState.js에는 위에서 App.js에 추가했던 코드를 옮겨 온다

import { useEffect, useState, useContext } from "react";
import ReduxContext from "../contexts/ReduxContext";

export function useReduxState() {
  const display = useContext(ReduxContext); //ReduxContext를 불러오는 코드가 추가 됐다
  const [state, setState] = useState(display.getState);
  useEffect(() => {
    const unsubscribe = display.subscribe(() => {
      setState(display.getState());
    });
    return () => {
      unsubscribe();
    };
  }, [display]);
  return state;
}

useReduxDispatch.js에서 store를 dispatch 할 수 있도록 코드를 작성한다.

import { useContext } from "react";
import ReduxContext from "../contexts/ReduxContext";

export function useReduxDispatch() {
  const display = useContext(ReduxContext);
  return display.dispatch;
}

이제 App.js에서

import { useReduxState } from "./hooks/useReduxState";
import { useReduxDispatch } from "./hooks/useReduxDispatch";
function App() {
  const state = useReduxState();
  const dispatch = useReduxDispatch();
  ~중략~
  const changeMode = () => {
    dispatch(displayMode(!state));
  };
  ~중략~
}

이런 식으로 사용할 수 있다. 그리고 여기서 state는 다른 component 파일에서도

const state = useReduxState();

이렇게 불러와서 사용할 수 있다. => 이제 dark mode의 정보를 상태 관리를 통해 props로 직접 전달해주지 않아도 전체 component에서 사용할 수 있게 되었다!


2023.02.16 수정

ContextAPI를 사용하면 다크모드 정도는 redux를 사용하는 것보다 쉽게 구현할 수 있다
나의 버려진 티스토리 블로그에 포스팅 했었다
ContextAPI로 다크모드 만들기

profile
사회에 이로운 IT 기술에 대해 고민하고 모두가 소외되지 않는 서비스를 운영하는 개발자를 꿈꾸고 있습니다 ✨

0개의 댓글