벨로퍼트 리액트 - 7. 리덕스 미들웨어
7-5. redux-thunk로 프로미스 다루기
5) 리액트 라우터 적용하기
라우터 설치
$ npm add react-router-dom
src/index.js 수정
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { applyMiddleware, createStore } 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 { BrowserRouter } from 'react-router-dom';
const root = ReactDOM.createRoot(document.getElementById('root'));
const store = createStore(
rootReducer,
// logger를 사용하는 경우 logger가 맨 마지막에 위치해야함
composeWithDevTools(applyMiddleware(ReduxThunk, logger))
// 여러개의 미들웨어 적용 가능
);
root.render(
<React.StrictMode>
<BrowserRouter>
<Provider store={store}>
<App />
</Provider>
</BrowserRouter>
</React.StrictMode>
);
reportWebVitals();
6) 포스트 조회하기
포스트 하나를 조회하는 기능
→ 프리젠테이셔널 컴포넌트 Post.js 생성
import React from "react";
function Post({ post }) {
const { title, body } = post;
return (
<div>
<h1>{title}</h1>
<p>{body}</p>
</div>
);
}
export default Post;
containers/PostContainer.js 생성
import React, {useEffect} from "react";
import { useDispatch, useSelector } from "react-redux";
import { getPost } from "../modules/posts";
import Post from "../components/Post";
function PostContiner({ postId }) {
const { data, loading, error } = useSelector(state => state.posts.post);
const dispatch = useDispatch();
useEffect(() => {
dispatch(getPost(postId));
}, [postId, dispatch]);
if (loading) return <div>로딩중...</div>;
if (error) return <div>에러발생!</div>;
if (!data) return null;
return <Post post={data} />;
}
export default PostContiner;
→ postId 값을 props로 받아와서 라우트의 URL 파라미터에서 읽어올것
7) 라우트 설정하기
pages/PostListPage.js 생성
import React from "react";
import PostListContainer from "../container/PostListContainer";
import {Outlet} from 'react-router-dom';
function PostListPage() {
return (
<>
<PostListContainer />
<Outlet />
</>
);
}
export default PostListPage;
pages/PostPage.js 생성
import React from "react";
import { useParams } from "react-router-dom";
import PostContainer from "../container/PostContainer";
function PostPage() {
const params = useParams(); // url 파라미터 조회하기
return <PostContainer postId={parseInt(params.id, 10)} />;
}
export default PostPage;
App.js에서 라우트 설정
// import CounterContainer from "./container/CounterContainer";
import PostListContainer from "./container/PostListContainer";
import PostListPage from "./pages/PostListPage";
import PostPage from "./pages/PostPage";
import { Routes, Route } from 'react-router-dom';
function App() {
return (
// <CounterContainer />
// <PostListContainer />
<Routes>
<Route path="/" element={<PostListPage />} />
<Route path=":id" element={<PostPage />} />
</Routes>
);
}
export default App;
components/PostList.js → Link 컴포넌트 사용하기
import React from 'react';
import { Link } from 'react-router-dom';
function PostList({ posts }) {
return (
<ul>
{posts.map(post => (
<li key={post.id}>
<Link to={`${post.id}`}>{post.title}</Link>
</li>
))}
</ul>
);
}
export default PostList;