[React][DJplaylist] redux-saga와 router 연결

jiseong·2021년 10월 17일
1

T I Learned

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

saga 내부에서 성공적인 로직일 때만 페이지 이동을 하고 싶었지만 saga 내부에서 history를 불러올 수가 없었다.

1) dispatch({data, history})

그래서 첫번째로 해결한 방식은 dispatch로 history를 넘기는 방식을 사용했다.

// searchFormContainer.js
dispatch(getMusicList({ keyword: myKeyword, history }));

// sagas/musicSaga.js
function* getMusicList({ payload }) {
  const { keyword, history } = payload;
  const beforeKeyword = yield select(state => state.music.keyword);

  try {
    if (keyword === beforeKeyword) throw new Error('동일한 키워드 검색');

    console.log('음악 찾기 시작...', keyword);
    yield put(setKeyword(keyword));
    const data = yield call(fetchPlayList, `${keyword} 플레이리스트`);
    yield put(getMusicListSuccess(data));
    history.replace(`/search?query=${keyword}`); // 페이지 이동
  } catch (e) {
    // yield put(getMusicListFail(e));
    console.log(e);
  }
}

2) redux-saga와 router 연결

위의 방식으로 history를 넘기는건 아닌 것 같아서 redux-saga와 router를 연결할 수 있는 방법을 찾게 되었고 stackoverflow에서 해당 답변을 찾을 수 있었다.

1) history 파일 생성

// util/history.js
import { createBrowserHistory } from 'history';

export default createBrowserHistory();

2) router에 해당 history 연결

import { Router, Route, Switch } from 'react-router-dom';
import history from './util/history';

기존에는 BrowserRouter를 사용했지만 history를 연결해주기 위해서는 Router를 사용해야 한다.

<ThemeProvider theme={mode ? lightTheme : darkTheme}>
  <GlobalStyles />
  <Router history={history}> // history 연결
    <Switch>
      <Route exact path={['/', '/main']} component={MainPage} />
      <Route path="/search" component={SearchPage} />
      <Route path="*" component={NotFoundPage} />
    </Switch>
  </Router>
  <PlayerContainer />
</ThemeProvider>

3) redux-saga 내부에서 history 사용하기

import history from '../../util/history';

function* getMusicList({ payload: keyword }) {
  const beforeKeyword = yield select(state => state.music.keyword);

  try {
    if (keyword === beforeKeyword) throw new Error('동일한 키워드 검색');

    console.log('음악 찾기 시작...', keyword);
    yield put(setKeyword(keyword));
    const data = yield call(fetchPlayList, `${keyword} 플레이리스트`);
    yield put(getMusicListSuccess(data));
    history.replace(`/search?query=${keyword}`);
  } catch (e) {
    // yield put(getMusicListFail(e));
    console.log(e);
  }
}

👍 결과


Reference

post-custom-banner

0개의 댓글