[POBTIL] 17일차

SWP·2022년 5월 21일
0

POBTIL

목록 보기
16/21
post-thumbnail

2022.05.21 토요일


오늘 할일

  1. 딥다이브 가볍게 읽기 _ CH10,11
  2. 싸피 테스트보기
  3. 강의 복습하면서 그립리팩토링
  4. 독서 15분

오늘배운것

다크모드 적용하기

라이브러리 store 이용하여, 로컬스토리지에 상태값 저장하고
리덕스 툴킷 이용하여 상태관리

0. 리덕스 및 리덕스 설치하고, 스토어 만들기!

yarn add @reduxjs/toolkit react-redux

import { Provider } from 'react-redux';
import { store } from './states';

const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement);
root.render(
  <React.StrictMode>
      <Provider store={store}>
        <BrowserRouter>
          <Routes />
        </BrowserRouter>
  </React.StrictMode>
);

툴킷 스토어

// states/index.ts

import { configureStore } from '@reduxjs/toolkit';

import search from './search';
import system from './system';

export const store = configureStore({
  reducer: {
    search,
    system,
  },
  devTools: process.env.NODE_ENV !== 'production',
  middleware: (getDefaultMiddleware) => getDefaultMiddleware({ serializableCheck: false }),
});

export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;

1. 리덕스툴킷 및 스토어(로컬스토리지) 설치하고 상태관리

yarn add store
yarn add @types/store --dev

툴킷 슬라이스

// states/system.ts

import { createSlice, PayloadAction } from '@reduxjs/toolkit';
import store from 'store';

import type { RootState } from '.';

interface SystemState {
  theme: string;
}

const initialState: SystemState = {
  theme: store.get('foundation.theme') || 'light',
};

const systemSlice = createSlice({
  name: 'theme',
  initialState,
  reducers: {
    setTheme: (state: SystemState, action: PayloadAction<string>) => {
      const newColorSet = action.payload;
      store.set('foundation.theme', newColorSet);
      document.documentElement.setAttribute('color-theme', newColorSet );
      state.theme = newColorSet;
    },

    toggleTheme: (state: SystemState) => {
      const newColorSet = state.theme === 'light' ? 'dark' : 'light';
      store.set('foundation.theme', newColorSet);
      document.documentElement.setAttribute('color-theme', newColorSet);
      state.theme = newColorSet;
    },
  },
});


export default systemSlice.reducer;

export const { toggleTheme } = systemSlice.actions;

export const getTheme = (state: RootState): string => state.system.theme;

2. 버튼만들어서 색 토글시켜주기

// src/routes/Search/index.tsx

import styles from './search.module.scss';
import SearchBar from 'routes/Search/SearchBar';
import Recommend from 'routes/Search/Recommend';
import { useAppSelector } from 'hooks';
import { getTheme, toggleTheme } from 'states/system';
import { useDispatch } from 'react-redux';

const Search = () => {
  const dispatch = useDispatch();
  const theme = useAppSelector(getTheme);

  const handleThemeClick = () => {
    dispatch(toggleTheme());
  };

  return (
    <main className={styles.main}>
      <header>
        국내 모든 임상시험 검색하고 <br />
        온라인으로 참여하기
        <div className={styles.rightWing}>
          <button type='button' onClick={handleThemeClick}>
            {theme}
          </button>
        </div>
      </header>
      <SearchBar />
      <Recommend />
    </main>
  );
};

export default Search;

3. 마운트 될 때 저장된 값 가져오기

리덕스 값을 가져오려면 provider안에 있어야하기 때문에 routes에서 코드작성
마운트됐을 때 값을 가져와서 document에 setAttribute로 컬러테마를 집어넣음

// src/routes/index.tsx
import { useMount } from 'react-use';
import styles from './Routes.module.scss';

import { useAppSelector } from 'hooks';
import { getTheme } from 'states/system';

import Search from './Search';

const App = () => {
  const theme = useAppSelector(getTheme);

  useMount(() => {
    document.documentElement.setAttribute('color-theme', theme);
  });

  return (
    <div className={styles.app}>
      <Search />
    </div>
  );
};

export default App;

4. css적용하기

html 꼭대기에 적용시켰으니 땡겨쓰기
:root[color-theme='dark'] & {}

// src/routes/Routes.module.scss
@use '/src/styles/mixins/flexbox';
@use '/src/styles/constants/colors';

.app {
  @include flexbox.flexbox('center', 'start');
  height: 100vh;
  padding: 100px;
  background-color: #cae9ff;
  transition: 0.2s;

  :root[color-theme='dark'] & {
    color: colors.$WHITE;
    background-color: black;
  }
}

constant폴더의 컬러셋을 dark모드인지에 따라 바꿔서 넣어줄 수 있으면 좋을 것 같은데... 아직 방법은 찾지못했다 ㅠㅠ

profile
잘하고싶다...

0개의 댓글