1. customHistory 만들어서 적용하기
프로젝트를 개발하다보면, thunk 함수 내에서 라우터를 사용해야 될 때도 있다. 예를 들자면 로그인 요청을 하는데 로그인이 성공 할 시 / 경로로 이동시키고, 실패 할 시 경로를 유지 하는 형태로 구현 할 수도 있는데
그러한 상황엔 어떻게 구현을 해야하는지 알아보도록 하겠다.
index.js
thunk 에서 라우터의 history 객체를 사용하려면, BrowserHistory 인스턴스를 직접 만들어서 적용해야 한다. 그리고, redux-thunk 의 withExtraArgument 를 사용하면 thunk함수에서 사전에 정해준 값들을 참조 할 수 있다. 스토어를 만드는 코드를 다음과 같이 변경하면된다.
import React from 'react'; import ReactDOM from 'react-dom'; import './index.css'; import App from './App'; import { createStore, applyMiddleware } from 'redux'; import { Provider } from 'react-redux'; import rootReducer from './modules'; import logger from 'redux-logger'; import { composeWithDevTools } from 'redux-devtools-extension'; import ReduxThunk from 'redux-thunk'; import { Router } from 'react-router-dom'; import { createBrowserHistory } from 'history'; const customHistory = createBrowserHistory(); const store = createStore( rootReducer, // logger 를 사용하는 경우, logger가 가장 마지막에 와야 한다. composeWithDevTools( applyMiddleware( ReduxThunk.withExtraArgument({ history: customHistory }), logger ) ) ); // 여러개의 미들웨어를 적용 할 수 있다. ReactDOM.render( <React.StrictMode> <Router history={customHistory}> <BrowserRouter> <Provider store={store}> <App /> </Provider> </BrowserRouter> </Router> </React.StrictMode>, document.getElementById('root') );
2. 홈 화면으로 가는 thunk 만들기
이제 홈 화면으로 가는 thunk를 작성해보도록 하겠다.
해당 함수를 posts 모듈에 추가 해준다.
modules/posts.js - goToHome
// 3번째 인자를 사용하면 withExtraArgument 에서 넣어준 값들을 사용 할 수 있다. export const goToHome = () => (dispatch, getState, { history }) => { history.push('/'); };
이제 PostContainer.js 에서 이 thunk 를 디스패치한다.
containers/PostContainer.js
import React, { useEffect } from 'react'; import { useSelector, useDispatch } from 'react-redux'; import { getPost, goToHome } from '../modules/posts'; import Post from '../components/Post'; function PostContainer({ postId }) { const { data, loading, error } = useSelector( state => state.posts.post[postId] ) || { loading: false, data: null, error: null }; // 아예 데이터가 존재하지 않을 때가 있으므로, 비구조화 할당이 오류나지 않도록 const dispatch = useDispatch(); useEffect(() => { dispatch(getPost(postId)); }, [dispatch, postId]); if (loading && !data) return <div>로딩중...</div>; // 로딩중이고 데이터 없을때만 if (error) return <div>에러 발생!</div>; if (!data) return null; return ( <> <button onClick={() => dispatch(goToHome())}>홈으로 이동</button> <Post post={data} /> </> ); } export default PostContainer;
'개발 공부한 내용 정리 > React' 카테고리의 다른 글
react- redux-thunk로 프로미스 다루기 (0) | 2020.11.12 |
---|---|
React- redux-thunk (0) | 2020.11.12 |
React- redux-logger 사용 및 미들웨어와 DevTools 함께 사용하기 (0) | 2020.11.07 |
React- 미들웨어 만들어보고 이해하기 (0) | 2020.11.06 |
React- 리덕스 미들웨어 실습을 위한 리덕스 프로젝트 준비 하기 (0) | 2020.11.05 |