saga 내부에서 성공적인 로직일 때만 페이지 이동을 하고 싶었지만 saga 내부에서 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);
}
}
위의 방식으로 history를 넘기는건 아닌 것 같아서 redux-saga와 router를 연결할 수 있는 방법을 찾게 되었고 stackoverflow에서 해당 답변을 찾을 수 있었다.
// util/history.js
import { createBrowserHistory } from 'history';
export default createBrowserHistory();
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>
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);
}
}