Skip to content

Commit

Permalink
refactor: PostReview 코드 가독성 및 로직 정리
Browse files Browse the repository at this point in the history
1. usePostReviews 위치 변경 : 상위 Review에 위치, 리뷰목록 보는 UI에 영향을 줌 => PostReview로 내려옴
2. 불필요한 함수 정의 생략 : 정의하자마자 실행하고 단한번인 경우 정의없이 바로 실행
3. 여기저기 흩어진 검증코드 모으기 : 42 인증 및 글자수 검증은 submit 클릭시 한번만 수행
4. 기타 함수, 변수명 선언형으로 수정함
  • Loading branch information
not-using committed Jul 18, 2023
1 parent c83a411 commit 9673631
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 78 deletions.
45 changes: 14 additions & 31 deletions src/api/reviews/usePostReview.ts
Original file line number Diff line number Diff line change
@@ -1,41 +1,24 @@
import { useEffect, useState } from "react";
import { useApi } from "../../hook/useApi";
import { useState } from "react";

import { useNewDialog } from "../../hook/useNewDialog";
import axiosPromise from "../../util/axios";

type Props = {
bookInfoId: number;
changeTab: (tab: number) => void;
resetTab: () => void;
};

export const usePostReview = ({ bookInfoId, changeTab }: Props) => {
const checkLogin = JSON.parse(window.localStorage.getItem("user") || "{}");
export const usePostReview = ({ bookInfoId, resetTab }: Props) => {
const [content, setContent] = useState("");
const { request } = useApi("post", "/reviews", {
bookInfoId,
content,
});

const refineResponse = () => {
changeTab(0);
};
const { addDialogWithTitleAndMessage } = useNewDialog();

const displayError = () => {
const title =
checkLogin === null
? "로그인 후 입력해주세요."
: "10자 이상 420자 이하로 입력해주세요.";
addDialogWithTitleAndMessage(title, title, "");
};

useEffect(() => {
const req = () => {
if (content !== "") {
request(refineResponse, displayError);
}
};
req();
}, [content]);
const { addErrorDialog } = useNewDialog();

return { setContent };
const request = () =>
axiosPromise("post", "/reviews", {
bookInfoId,
content,
})
.then(resetTab)
.catch(addErrorDialog);
return { content, setContent, request };
};
73 changes: 32 additions & 41 deletions src/component/book/review/PostReview.tsx
Original file line number Diff line number Diff line change
@@ -1,68 +1,59 @@
import {
ChangeEventHandler,
FormEventHandler,
ReactNode,
useState,
} from "react";
import { FormEventHandler } from "react";
import "../../../asset/css/Review.css";
import Button from "../../utils/Button";
import { useNewDialog } from "../../../hook/useNewDialog";
import { useRecoilValue } from "recoil";
import userState from "../../../atom/userState";
import { usePostReview } from "../../../api/reviews/usePostReview";

type Props = {
onClickPost: (post: string) => void;
bookInfoId: number;
resetTab: () => void;
};

const PostReview = ({ onClickPost }: Props) => {
const [content, setContent] = useState("");
const checkLogin = useRecoilValue(userState);
const checkValidUser = () => {
const user = checkLogin;
if (user) {
if (user.userName === user.email) {
return false;
}
}
return true;
};

const onChange: ChangeEventHandler<HTMLTextAreaElement> = e => {
setContent(e.target.value);
};
const PostReview = ({ bookInfoId, resetTab }: Props) => {
const { content, setContent, request } = usePostReview({
bookInfoId: +bookInfoId,
resetTab,
});

const user = useRecoilValue(userState);
const hasPermissionToPostReview = user && user.userName !== user.email; // 인증된 유저는 이메일과 다른 닉네임을 가짐
const isValidLength = content.length >= 10 && content.length <= 420;
const { addDialogWithTitleAndMessage, addConfirmDialog } = useNewDialog();
const submitReview = () => {
const validUser = checkValidUser();
if (validUser === false) {
const title = "42 인증 후 리뷰 등록이 가능합니다.";
addDialogWithTitleAndMessage(title, title, "");

const postReviewOrDisplayError: FormEventHandler = e => {
e.preventDefault();
if (hasPermissionToPostReview && isValidLength) {
addConfirmDialog(
`${content} 리뷰등록 확인`,
"리뷰를 등록하시겠습니까?",
"",
request,
);
return;
}
onClickPost(content);
};
const title = !hasPermissionToPostReview
? "42 인증 후 리뷰 등록이 가능합니다."
: "10자 이상 420자 이하로 입력해주세요.";

const onSubmitHandler: FormEventHandler = e => {
e.preventDefault();
addConfirmDialog(
`${content} 리뷰등록 확인`,
"리뷰를 등록하시겠습니까?",
"",
submitReview,
);
addDialogWithTitleAndMessage(title, title, "");
};

return (
<div className="do-review__review-box">
<form className="do-review__review-form" onSubmit={onSubmitHandler}>
<form
className="do-review__review-form"
onSubmit={postReviewOrDisplayError}
>
<textarea
className="review-area font-12"
value={content}
onChange={onChange}
onChange={e => setContent(e.target.value)}
maxLength={420}
required
placeholder={
checkLogin
user
? "10자 이상 420자 이내로 입력해주세요."
: "로그인 후 리뷰 등록이 가능합니다."
}
Expand Down
8 changes: 2 additions & 6 deletions src/component/book/review/Review.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { reviewTabList } from "../../../constant/tablist";
import PostReview from "./PostReview";
import ShowReviews from "./ShowReviews";
import { useTabFocus } from "../../../hook/useTabFocus";
import { usePostReview } from "../../../api/reviews/usePostReview";
import "../../../asset/css/Tabs.css";
import "../../../asset/css/Review.css";

Expand All @@ -12,10 +11,7 @@ type Props = {

const Review = ({ bookInfoId }: Props) => {
const { currentTab, changeTab } = useTabFocus(0, reviewTabList);
const { setContent } = usePostReview({
bookInfoId: +bookInfoId,
changeTab,
});
const resetTab = () => changeTab(0);

return (
<>
Expand All @@ -39,7 +35,7 @@ const Review = ({ bookInfoId }: Props) => {
{currentTab === "showReviews" ? (
<ShowReviews bookInfoId={+bookInfoId} />
) : (
<PostReview onClickPost={setContent} />
<PostReview bookInfoId={+bookInfoId} resetTab={resetTab} />
)}
</div>
</>
Expand Down

0 comments on commit 9673631

Please sign in to comment.