Skip to content

Commit 8b56b3b

Browse files
committed
Update chatper 26
1 parent 797f978 commit 8b56b3b

File tree

10 files changed

+6284
-7288
lines changed

10 files changed

+6284
-7288
lines changed

26/blog/blog-frontend/package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@
77
"immer": "^3.1.3",
88
"qs": "^6.7.0",
99
"quill": "^1.3.6",
10-
"react": "^16.8.6",
11-
"react-dom": "^16.8.6",
10+
"react": "^17.0.2",
11+
"react-dom": "^17.0.2",
1212
"react-redux": "^7.1.0",
13-
"react-router-dom": "^5.0.1",
14-
"react-scripts": "3.0.1",
13+
"react-router-dom": "^6.2.1",
14+
"react-scripts": "^5.0.0",
1515
"redux": "^4.0.1",
1616
"redux-actions": "^2.6.5",
1717
"redux-devtools-extension": "^2.13.8",

26/blog/blog-frontend/src/App.js

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import React from 'react';
2-
import { Route } from 'react-router-dom';
1+
import { Route, Routes } from 'react-router-dom';
32
import PostListPage from './pages/PostListPage';
43
import LoginPage from './pages/LoginPage';
54
import RegisterPage from './pages/RegisterPage';
@@ -8,13 +7,16 @@ import PostPage from './pages/PostPage';
87

98
const App = () => {
109
return (
11-
<>
12-
<Route component={PostListPage} path={['/@:username', '/']} exact />
13-
<Route component={LoginPage} path="/login" />
14-
<Route component={RegisterPage} path="/register" />
15-
<Route component={WritePage} path="/write" />
16-
<Route component={PostPage} path="/@:username/:postId" />
17-
</>
10+
<Routes>
11+
<Route path="/" element={<PostListPage />} />
12+
<Route path="/login" element={<LoginPage />} />
13+
<Route path="/register" element={<RegisterPage />} />
14+
<Route path="/write" element={<WritePage />} />
15+
<Route path="/@:username">
16+
<Route index element={<PostListPage />} />
17+
<Route path=":postId" element={<PostPage />} />
18+
</Route>
19+
</Routes>
1820
);
1921
};
2022
export default App;

26/blog/blog-frontend/src/containers/auth/LoginForm.js

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import React, { useEffect, useState } from 'react';
22
import { useSelector, useDispatch } from 'react-redux';
3-
import { withRouter } from 'react-router-dom';
3+
import { useNavigate } from 'react-router-dom';
44
import { changeField, initializeForm, login } from '../../modules/auth';
55
import AuthForm from '../../components/auth/AuthForm';
66
import { check } from '../../modules/user';
77

8-
const LoginForm = ({ history }) => {
8+
const LoginForm = () => {
9+
const navigate = useNavigate();
910
const [error, setError] = useState(null);
1011
const dispatch = useDispatch();
1112
const { form, auth, authError, user } = useSelector(({ auth, user }) => ({
@@ -15,7 +16,7 @@ const LoginForm = ({ history }) => {
1516
user: user.user,
1617
}));
1718
// 인풋 변경 이벤트 핸들러
18-
const onChange = e => {
19+
const onChange = (e) => {
1920
const { value, name } = e.target;
2021
dispatch(
2122
changeField({
@@ -27,7 +28,7 @@ const LoginForm = ({ history }) => {
2728
};
2829

2930
// 폼 등록 이벤트 핸들러
30-
const onSubmit = e => {
31+
const onSubmit = (e) => {
3132
e.preventDefault();
3233
const { username, password } = form;
3334
dispatch(login({ username, password }));
@@ -53,14 +54,14 @@ const LoginForm = ({ history }) => {
5354

5455
useEffect(() => {
5556
if (user) {
56-
history.push('/');
57+
navigate('/');
5758
try {
5859
localStorage.setItem('user', JSON.stringify(user));
5960
} catch (e) {
6061
console.log('localStorage is not working');
6162
}
6263
}
63-
}, [history, user]);
64+
}, [navigate, user]);
6465

6566
return (
6667
<AuthForm
@@ -73,4 +74,4 @@ const LoginForm = ({ history }) => {
7374
);
7475
};
7576

76-
export default withRouter(LoginForm);
77+
export default LoginForm;

26/blog/blog-frontend/src/containers/auth/RegisterForm.js

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@ import { useDispatch, useSelector } from 'react-redux';
33
import { changeField, initializeForm, register } from '../../modules/auth';
44
import AuthForm from '../../components/auth/AuthForm';
55
import { check } from '../../modules/user';
6-
import { withRouter } from 'react-router-dom';
6+
import { useNavigate } from 'react-router-dom';
77

88
const RegisterForm = ({ history }) => {
9+
const navigate = useNavigate();
910
const [error, setError] = useState(null);
1011
const dispatch = useDispatch();
1112
const { form, auth, authError, user } = useSelector(({ auth, user }) => ({
@@ -15,7 +16,7 @@ const RegisterForm = ({ history }) => {
1516
user: user.user,
1617
}));
1718
// 인풋 변경 이벤트 핸들러
18-
const onChange = e => {
19+
const onChange = (e) => {
1920
const { value, name } = e.target;
2021
dispatch(
2122
changeField({
@@ -27,7 +28,7 @@ const RegisterForm = ({ history }) => {
2728
};
2829

2930
// 폼 등록 이벤트 핸들러
30-
const onSubmit = e => {
31+
const onSubmit = (e) => {
3132
e.preventDefault();
3233
const { username, password, passwordConfirm } = form;
3334
// 하나라도 비어있다면
@@ -75,14 +76,14 @@ const RegisterForm = ({ history }) => {
7576
// user 값이 잘 설정되었는지 확인
7677
useEffect(() => {
7778
if (user) {
78-
history.push('/'); // 홈 화면으로 이동
79+
navigate('/'); // 홈 화면으로 이동
7980
try {
8081
localStorage.setItem('user', JSON.stringify(user));
8182
} catch (e) {
8283
console.log('localStorage is not working');
8384
}
8485
}
85-
}, [history, user]);
86+
}, [navigate, user]);
8687

8788
return (
8889
<AuthForm
@@ -95,4 +96,4 @@ const RegisterForm = ({ history }) => {
9596
);
9697
};
9798

98-
export default withRouter(RegisterForm);
99+
export default RegisterForm;

26/blog/blog-frontend/src/containers/post/PostViewerContainer.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import React, { useEffect } from 'react';
22
import { useDispatch, useSelector } from 'react-redux';
3-
import { withRouter } from 'react-router-dom';
3+
import { useParams } from 'react-router-dom';
44
import { readPost, unloadPost } from '../../modules/post';
55
import PostViewer from '../../components/post/PostViewer';
66

7-
const PostViewerContainer = ({ match }) => {
7+
const PostViewerContainer = () => {
88
// 처음 마운트될 때 포스트 읽기 API 요청
9-
const { postId } = match.params;
9+
const { postId } = useParams();
1010
const dispatch = useDispatch();
1111
const { post, error, loading } = useSelector(({ post, loading }) => ({
1212
post: post.post,
@@ -25,4 +25,4 @@ const PostViewerContainer = ({ match }) => {
2525
return <PostViewer post={post} loading={loading} error={error} />;
2626
};
2727

28-
export default withRouter(PostViewerContainer);
28+
export default PostViewerContainer;
Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
import React from 'react';
22
import Pagination from '../../components/posts/Pagination';
33
import { useSelector } from 'react-redux';
4-
import { withRouter } from 'react-router-dom';
5-
import qs from 'qs';
4+
import { useParams, useSearchParams } from 'react-router-dom';
5+
6+
const PaginationContainer = () => {
7+
const [searchParams] = useSearchParams();
8+
9+
const { username } = useParams();
10+
const tag = searchParams.get('tag');
11+
// page가 없으면 1을 기본값으로 사용
12+
const page = parseInt(searchParams.get('page'), 10) || 1;
613

7-
const PaginationContainer = ({ location }) => {
814
const { lastPage, posts, loading } = useSelector(({ posts, loading }) => ({
915
lastPage: posts.lastPage,
1016
posts: posts.posts,
@@ -14,11 +20,6 @@ const PaginationContainer = ({ location }) => {
1420
// 포스트 데이터가 없거나 로딩 중이면 아무것도 보여주지 않음
1521
if (!posts || loading) return null;
1622

17-
// page가 없으면 1을 기본값으로 사용
18-
const { tag, username, page = 1 } = qs.parse(location.search, {
19-
ignoreQueryPrefix: true,
20-
});
21-
2223
return (
2324
<Pagination
2425
tag={tag}
@@ -29,4 +30,4 @@ const PaginationContainer = ({ location }) => {
2930
);
3031
};
3132

32-
export default withRouter(PaginationContainer);
33+
export default PaginationContainer;
Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import React, { useEffect } from 'react';
2-
import qs from 'qs';
3-
import { withRouter } from 'react-router-dom';
42
import { useDispatch, useSelector } from 'react-redux';
53
import PostList from '../../components/posts/PostList';
64
import { listPosts } from '../../modules/posts';
5+
import { useParams, useSearchParams } from 'react-router-dom';
76

8-
const PostListContainer = ({ location }) => {
7+
const PostListContainer = () => {
8+
const { username } = useParams();
9+
const [searchParams] = useSearchParams();
910
const dispatch = useDispatch();
1011
const { posts, error, loading, user } = useSelector(
1112
({ posts, loading, user }) => ({
@@ -16,11 +17,11 @@ const PostListContainer = ({ location }) => {
1617
}),
1718
);
1819
useEffect(() => {
19-
const { tag, username, page } = qs.parse(location.search, {
20-
ignoreQueryPrefix: true,
21-
});
20+
const tag = searchParams.get('tag');
21+
// page가 없으면 1을 기본값으로 사용
22+
const page = parseInt(searchParams.get('page'), 10) || 1;
2223
dispatch(listPosts({ tag, username, page }));
23-
}, [dispatch, location.search]);
24+
}, [dispatch, searchParams, username]);
2425

2526
return (
2627
<PostList
@@ -32,4 +33,4 @@ const PostListContainer = ({ location }) => {
3233
);
3334
};
3435

35-
export default withRouter(PostListContainer);
36+
export default PostListContainer;

26/blog/blog-frontend/src/containers/write/WriteActionButtonsContainer.js

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import React, { useEffect } from 'react';
22
import WriteActionButtons from '../../components/write/WriteActionButtons';
33
import { useSelector, useDispatch } from 'react-redux';
4-
import { withRouter } from 'react-router-dom';
4+
import { useNavigate } from 'react-router-dom';
55
import { writePost } from '../../modules/write';
66

7-
const WriteActionButtonsContainer = ({ history }) => {
7+
const WriteActionButtonsContainer = () => {
8+
const navigate = useNavigate();
89
const dispatch = useDispatch();
910
const { title, body, tags, post, postError } = useSelector(({ write }) => ({
1011
title: write.title,
@@ -27,20 +28,20 @@ const WriteActionButtonsContainer = ({ history }) => {
2728

2829
// 취소
2930
const onCancel = () => {
30-
history.goBack();
31+
navigate(-1);
3132
};
3233

3334
// 성공 혹은 실패시 할 작업
3435
useEffect(() => {
3536
if (post) {
3637
const { _id, user } = post;
37-
history.push(`/@${user.username}/${_id}`);
38+
navigate(`/@${user.username}/${_id}`);
3839
}
3940
if (postError) {
4041
console.log(postError);
4142
}
42-
}, [history, post, postError]);
43+
}, [navigate, post, postError]);
4344
return <WriteActionButtons onPublish={onPublish} onCancel={onCancel} />;
4445
};
4546

46-
export default withRouter(WriteActionButtonsContainer);
47+
export default WriteActionButtonsContainer;
Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,12 @@
1-
import qs from 'qs';
21
import client from './client';
32

43
export const writePost = ({ title, body, tags }) =>
54
client.post('/api/posts', { title, body, tags });
65

7-
export const readPost = id => client.get(`/api/posts/${id}`);
6+
export const readPost = (id) => client.get(`/api/posts/${id}`);
87

98
export const listPosts = ({ page, username, tag }) => {
10-
const queryString = qs.stringify({
11-
page,
12-
username,
13-
tag,
9+
return client.get(`/api/posts`, {
10+
params: { page, username, tag },
1411
});
15-
return client.get(`/api/posts?${queryString}`);
1612
};

0 commit comments

Comments
 (0)