벨로퍼트 리액트 - 7. 리덕스 미들웨어
7-7. thunk에서 라우터 연동하기
1) customHistory 만들어서 적용하기
thunk에서 라우터의 history 객체를 사용하려면 BrowserHistory 인스턴스를 직접 만들어야 한다.
index.js 수정
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
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(
<Router history={customHistory}>
<Provider store={store}>
<App />
</Provider>
</Router>,
document.getElementById('root')
);
serviceWorker.unregister();
⇒ 에러나서 예제에 첨부된 코드로 일단 실습
2) 홈 화면으로 가는 thunk 만들기
modules/posts.js - goToHome 추가
// 3번째 인자를 사용하면 withExtraArgument 에서 넣어준 값들을 사용 할 수 있습니다.
export const goToHome = () => (dispatch, getState, { history }) => {
history.push('/');
};
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;
7-8. json-server
1) 가짜 API 서버 열기
json-server : 가짜 API 서버를 만들 수 있는 도구. 단! 실제 프로젝트 개발용도로 사용하면 안됨!
src 밖에 data.json 파일 작성
{
"posts": [
{
"id": 1,
"title": "리덕스 미들웨어를 배워봅시다",
"body": "리덕스 미들웨어를 직접 만들어보면 이해하기 쉽죠."
},
{
"id": 2,
"title": "redux-thunk를 사용해봅시다",
"body": "redux-thunk를 사용해서 비동기 작업을 처리해봅시다!"
},
{
"id": 3,
"title": "redux-saga도 사용해봅시다",
"body": "나중엔 redux-saga를 사용해서 비동기 작업을 처리하는 방법도 배워볼 거예요."
}
]
}
파일 기반으로 서버 열기
$ npx json-server ./data.json --port 4000
4000 포트에서 보여지는 내용!
2) axios 를 사용하여 API 요청하기
api/posts.js 파일을 실제 API 요청을 하도록 수정
import axios from 'axios';
export const getPosts = async () => {
const response = await axios.get('<http://localhost:4000/posts>');
return response.data;
};
export const getPostById = async id => {
const response = await axios.get(`http://localhost:4000/posts/${id}`);
return response.data;
};