[Styled-components][DJplaylist] 다크모드 및 Youtube API

youtube api

GET https://www.googleapis.com/youtube/v3

일일 할당량이 10,000 뿐인데 search:list를 이용할 때마다 100씩 든다. 그래서 할당량을 최적화 할 수 있는 방법을 찾아봤는데 내가 구현할려는 기능과 관련된 할당 방법은 없는 것 같다..

대신 fields 매개변수를 사용하면 API 응답에서 중첩된 속성을 삭제할 수 있으므로 대역폭 사용량을 대폭 절감할 수 있다고 한다.

대역폭이란? 초당 전송될 수 있는 최대량

fields 매개변수는 part 매개변수 값에서 식별된 리소스 부분만 포함한 API 응답을 필터링하여 응답이 특정 필드 집합만 포함하도록 한다.

 https://www.googleapis.com/youtube/v3/search?key=YOUR_API_KEY
     &fields=(nextPageToken, items(id,snippet(title,channelTitle,description,thumbnails)))&part=snippet

fields 매개변수를 추가하여 API 응답에서 title,channelTitle,description,thumbnails속성만을 가져올 수 있다.

다크모드 지원

많은 웹과 앱에서 다크모드를 지원하는 추세라서 한 번쯤은 해보고 싶은 기능이였기 때문에 reduxstyled-component에서 지원하는 ThemeProvider 그리고 한번 저장한 정보를 기억하기 위해서 localStorage를 활용해서 다크모드 기능을 지원하도록 했다.

1) reducer 설정

// store/modules/common.js

import { createAction, handleActions } from 'redux-actions';
import { setItem } from '../../util/localstorage';
import { getInitTheme } from '../../util/utils';

// action 정의

const SET_MODE = 'common/SET_MODE';

// action obj 생성
export const setMode = createAction(SET_MODE, mode => mode);

// init state
const initialState = {
  // mode: getInitTheme(), //localstorage 활용 시
  mode: true,
};

// reducer 정의
const common = handleActions(
  {
    [SET_MODE]: (state, { payload: mode }) => {
      // setItem('theme', !state.mode); //localstorage 활용 시
      
      return {
        ...state,
        mode: !state.mode,
      };
    },
  },
  initialState,
);

export default common;

2) 라이트모드, 다크모드 색상 설정

// styles/common/theme.js

export const lightTheme = {
  header: 'rgb(255, 255, 255)',
  bg: 'rgb(255, 255, 255)',
};

export const darkTheme = {
  header: 'rgb(22, 27, 34)',
  bg: 'rgb(13, 17, 23)',
};

3) store에 mode 저장 및 값 가져오기

mode 값 가져오기

우선, store에 저장된 mode 값을 가져오기 위해서는 useSelector를 활용하면 된다.

import { darkTheme, lightTheme } from './styles/common/theme';

const mode = useSelector(state => state.common.mode);


<ThemeProvider theme={mode ? lightTheme : darkTheme}>
  <GlobalStyles />
  <Router>
    <Switch>
      <Route exact path={['/', '/main']} component={MainPage} />
      <Route path="/playlist" component={PlaylistPage} />
      <Route path="*" component={NotFoundPage} />
    </Switch>
  </Router>
</ThemeProvider>

가장 중요한 ThemeProvider가 있는데 store의 저장된 mode 값에 따라 2)번에서 설정한 theme가 적용된다.

그렇게되면 ThemeProvider의 하위 컴포넌트에서 따로 props로 전달하지 않아도 해당 theme의 값을 이용할 수 있다.

예를 들면 theme={lightTheme}로 적용되었을 때, 하위의 자식 컴포넌트에서 아래와 같이 props.theme.bg를 이용하여 lightTheme일때의 bg에 적용된 색상 값을 가져올 수 있다.

// childComponent
const Button = styled.button`
  backgroundcolor: ${props => props.theme.bg};
// === backgroundcolor: rgb(255, 255, 255);
`;

render(
  <div>
      <Button>Themed</Button>
  </div>
);
mode 저장


해당 버튼을 누를 때 toggleMode함수가 실행되며 dispatch를 통해 mode를 저장(변경)하도록 하였다.

// container/ToggleModeContainer.js
const dispatch = useDispatch();

const toggleMode = () => {
  dispatch(setMode());
};

// components/common/ToggleMode.js

<ToggleContainer onClick={toggleMode}>
  <img src={icons.sun.default} alt="sun-Icon" />
  <img src={icons.moon.default} alt="moon-Icon" />
</ToggleContainer>

좋은 웹페이지 즐겨찾기