redux-saga는 사용해본적이 많지 않아서 익숙해져보고자 이번 youtube api를 사용하면서 검색 기능을 만들 때 사용해보고자 했다.
// 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);
}
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;
};
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,
);
3)에서 store에 데이터가 저장되고 나면 useSelector에서 변경된 상태를 알려주기 때문에 해당 상태를 이용해서 화면에 출력해주게끔 했다.