[React][DJplaylist] saga 비동기 액션 처리

jiseong·2021년 10월 14일
0

T I Learned

목록 보기
99/291
post-custom-banner

redux-saga 비동기 액션처리

redux-saga는 사용해본적이 많지 않아서 익숙해져보고자 이번 youtube api를 사용하면서 검색 기능을 만들 때 사용해보고자 했다.

1) 검색 시

// searchFormContainer.js
const handleSubmit = e => {
  e.preventDefault();
  if (myKeyword.length >= 1) {
    dispatch(getMusicList(myKeyword));
  }
};

위의 검색창에 검색할 단어를 입력하고 검색을 하게되면, redux-saga에서 모니터링 하고 있다가 GET_MUSICLIST 액션이 발생하면 fetchMusicList라는 함수를 실행시킨다.

// modules/music.js
export const GET_MUSICLIST = 'music/GET_MUSICLIST';
export const getMusicList = createAction(GET_MUSICLIST, keyword => keyword);
// sagas/musicSaga.js
import { GET_MUSICLIST } from '../modules/music';

// 아래 코드가 모니터링하는 코드
export default function* watchMusic() {
  yield takeEvery(GET_MUSICLIST, fetchMusicList);
  yield takeEvery(ADD_DJPLAYLIST, addDjplaylist);
  yield takeEvery(DELETE_DJPLAYLIST, deleteDjplaylist);
}

2) redux-saga의 비동기처리

redux-saga는 generator방식을 사용하기 때문에 위에서 순서대로 처리 할 수 있게 도와준다.

// sagas/musicSaga.js
import { fetchPlayList } from '../../api/youtube';
import { getMusicListSuccess } from '../modules/music';

function* fetchMusicList({ payload: keyword }) {
  console.log('음악 찾기 시작...', keyword);
  try {
    const data = yield call(fetchPlayList, `${keyword}`);
    yield put(getMusicListSuccess(data));
  } catch (e) {
    console.log(e);
  }
}

1)에서 받아온 keyword를 이용하여 youtube api에게 keyword를 전달하면서 검색을 하게 된다. 그 후, youtube api로 부터 응답을 받고 나서야 store에 저장하도록했다.

여기서 사용된 youtube api 방식은 아래와 같다.

// api/index.js
import axios from 'axios';

const url = 'https://www.googleapis.com/youtube/v3';
const KEY = process.env.REACT_APP_YOUTUBE_DATA_KEY;

const axiosInstance = axios.create({
  baseURL: url,
  params: {
    part: 'snippet',
    fields: 'nextPageToken, items(id,snippet(title,channelTitle,description,thumbnails))',
    type: 'video',
    maxResults: 50,
    key: KEY,
  },
});

export default axiosInstance;
// api/youtube.js
import axiosInstance from '.';

export const fetchPlayList = async (keyword, token) => {
  const res = await axiosInstance.get('/search', {
    params: {
      q: `${keyword}`,
      pageToken: token || '',
    },
  });

  return res.data;
};

3) 검색 결과 store에 저장

2)에서 youtube api로 부터 응답받은 데이터를 yield put(getMusicListSuccess(data));를 이용하여 dispatch를 하게 되면 store에 값이 저장될 수 있도록 했다.

// modules/music.js
export const GET_MUSICLIST_SUCCESS = 'music/GET_MUSICLIST_SUCCESS';

export const getMusicListSuccess = createAction(GET_MUSICLIST_SUCCESS, musicList => musicList);

// reducer 정의
const music = handleActions(
  {
    [GET_MUSICLIST_SUCCESS]: (state, { payload: musicList }) => {
      return {
        ...state,
        musicList,
      };
    }
  },
  initialState,
);

4) 검색 결과

3)에서 store에 데이터가 저장되고 나면 useSelector에서 변경된 상태를 알려주기 때문에 해당 상태를 이용해서 화면에 출력해주게끔 했다.

post-custom-banner

0개의 댓글