[유데미X스나이퍼팩토리] 10주 완성 프로젝트 캠프 프론트엔드(리액트/react) - 22일차 Redux 활용/Movie Web

이율곡·2023년 7월 4일
0

부트캠프

목록 보기
22/37
post-thumbnail

22일차

22일차는 Redux를 사용해서 전에 만든 Movie Web을 수정했다. 이전에는 useFetchMovies라는 custom Hook을 사용했고, 이번에는 Redux. 즉, Reducer, Action, Store를 사용했다.

gitHub: https://github.com/leeyulgok/React-BootCamp-Team2/tree/main/src

이제 오늘 한 내용을 정리해보자.


Redux

본격적으로 정리하기 전에 Redux를 공부하면서 중요하다고 생각하는 부분이 있어서 한 번 정리하려 한다.

데이터 흐름/작동흐름

  1. 사용자가 컴포넌트를 요청.
  2. 컴포넌트에서 액션 함수를 호출하여 액션 객체를 생성.
  3. 액션 객체는 dispatch 메서드를 통해 스토어로 전달.
  4. 스토어는 전달받은 액션 객체를 리듀서로 전달.
  5. 리듀서는 현재 상태와 전달받은 액션을 기반으로 새로운 상태를 반환.
  6. 스토어는 리듀서가 반환한 새로운 상태로 상태를 업데이트.
  7. 업데이트된 상태는 스토어를 구독하고 있는 컴포넌트에 자동으로 전달되어 UI를 업데이트.


출처: https://chanyeong.com/blog/post/21

Redux 폴더트리

내가 만든 App의 Redux의 폴더 트리는 다음과 같다.

src

...

- redux
  -- reducers
    --- movieSlice.js
    --- rootReducer.js
  -- store.js

폴더 트리는 이렇게 설정했다. redux라는 폴더를 하나 만들고 그 안에 관련된 파일을 넣었다. 지금까지 계속해서 Redux를 사용했기 때문에 아주 중요한 부분만 짚고 넘어가려 한다.

movieSlice.js

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

const initialState = {
  loading: false,
  movies: [],
  movie: null,
  error: null,
};

const movieSlice = createSlice({
  name: 'movies',
  initialState,
  reducers: {
    fetchMoviesRequest: (state) => {
      state.loading = true;
    },
    fetchMoviesSuccess: (state, action) => {
      state.loading = false;
      state.movies = action.payload;
    },
    fetchMoviesFailure: (state, action) => {
      state.loading = false;
      state.error = action.payload;
    },
    fetchMovieDetailRequest: (state) => {
      state.loading = true;
    },
    fetchMovieDetailSuccess: (state, action) => {
      state.loading = false;
      state.movie = action.payload;
    },
    fetchMovieDetailFailure: (state, action) => {
      state.loading = false;
      state.error = action.payload;
    },
  },
});

export const {
  fetchMoviesRequest,
  fetchMoviesSuccess,
  fetchMoviesFailure,
  fetchMovieDetailRequest,
  fetchMovieDetailSuccess,
  fetchMovieDetailFailure,
} = movieSlice.actions;


export const fetchMovies = (url) => {
  return async (dispatch) => {
    dispatch(fetchMoviesRequest());
    try {
      const response = await fetch(url);
      const json = await response.json();
      dispatch(fetchMoviesSuccess(json.data.movies));
    } catch (error) {
      dispatch(fetchMoviesFailure(error.message));
    }
  };
};

export const fetchMovieDetail = (url) => {
  return async (dispatch) => {
    dispatch(fetchMovieDetailRequest());
    try {
      const response = await fetch(url);
      const json = await response.json();
      dispatch(fetchMovieDetailSuccess(json.data.movie));
    } catch (error) {
      dispatch(fetchMovieDetailFailure(error.message));
    }
  };
};

export default movieSlice.reducer;

이 코드는 createSlice를 사용해서 movieSlice라는 Slice를 만들었다. reducer와 action가 하나로 합쳐져 있다. 나머지는 이전 코드들과 똑같다. 이름과 초기값을 설정하고 안에 reducer가 설정되어 있다. 함수를 짜서 함수 요청에 따른 상태와 액션이 정해져 있다.

그리고 fetch 함수를 짜서 dispatch에 요청을 보내고 값에 따라 성공여부를 반환하도록 했다.

결과

아주 잘 되는 모습이다. 이렇게 Redux를 사용해서 홈페이지를 띄우는 것까지 해보았다.


정리하기

지금까지 홈페이지를 API를 띄우는 방식에 대해 여러가지 방식으로 해보았다. 처음에는 컴포넌트에 요청에 따라 fetch API도 요청하는 방식, 다음은 custom Hook을 만들어서 따로 요청하는 방식, 다음으로는 Redux로 store를 만들어서 요청하는 방식으로 했다.

뭐가 가장 중요한 게 아니라 각각의 장단점이 존대한다. 그렇기 때문에 모든 방식을 다룰 줄 아는 것이 중요하고 상황에 따라 이를 사용할 수 있게 다양한 방식으로 Web을 만들어 보는게 좋은 것 같다. 그러니 계속해서 만들어보자.


본 후기는 유데미-스나이퍼팩토리 10주 완성 프로젝트캠프 학습 일지 후기로 작성 되었습니다.
#프로젝트캠프 #프로젝트캠프후기 #유데미 #스나이퍼팩토리 #웅진씽크빅 #인사이드아웃 #IT개발캠프 #개발자부트캠프 #리액트 #react #부트캠프 #리액트캠프

profile
음악을 좋아하는 사람이 음악을 만들 듯, 개발을 좋아하게 될 사람이 쓰는 개발이야기

0개의 댓글