-
Notifications
You must be signed in to change notification settings - Fork 20
[노현지] Sprint7 #69
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[노현지] Sprint7 #69
The head ref may contain hidden characters: "React-\uB178\uD604\uC9C0-sprint7"
Conversation
…sed on the current path
|
스프리트 미션 하시느라 수고 많으셨어요. |
| } | ||
|
|
||
| export async function getItemComments(productId = "", { cursor = 0 }) { | ||
| const query = `limit=${COMMENTS_LIMIT}&cursor=${cursor}`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
쿼리는 URLSearchParams로 손쉽게 사용할 수 있어요 !
| const query = `limit=${COMMENTS_LIMIT}&cursor=${cursor}`; | |
| const query = new URLSearchParams({cursor, limit: COMMENTS_LIMIT, }); |
URLSearchParams와 함께 객체로 손쉽게 핸들링할 수 있습니다 !
객체로 구성할 수 있어 가독성이 좋고, URL 인코딩을 자동으로 처리하여 특수 문자나 공백이 포함된 값에서도 안전하게 동작합니다 !
URLSearchParams:
URLSearchParams인터페이스는 URL의 쿼리 문자열을 대상으로 작업할 수 있는 유틸리티 메서드를 정의합니다.
| function PrimaryButton({ | ||
| children, | ||
| className = "", | ||
| onClick = () => {}, | ||
| disabled = false, | ||
| }) { | ||
| const buttonClass = `${styles.button} ${className}`; | ||
| return ( | ||
| <button className={buttonClass} onClick={onClick} disabled={disabled}> | ||
| {children} | ||
| </button> | ||
| ); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(심화/제안/고민해보기) 혹시 버튼 컴포넌트들을 공통 버튼 컴포넌트로 리팩토링 할 수는 없을까요?
MenuButton, DeleteButton, PrimaryButton.. 더 나아가서 SecondaryButton, UpdateButton 등등 목적에 따라 버튼이 생겨날 수 있을 것 같아요.
만약 디자인 시스템이 바뀌어서 일괄적으로 버튼의 radius를 바꿔야하는 상화이 온다면 유지보수하기가 어려워질 수 있겠지요?
예를 들어서 다음과 같은 컴포넌트를 만들어볼 수 있을 것 같아요:
import styles from "./Button.module.css";
function Button({
children,
variant = "primary",
icon,
// onClick = () => {},
className = "",
// disabled = false,
...rest
}) {
return (
<button
className={`${styles.button} ${styles[variant]} ${className}`}
// onClick={onClick}
// disabled={disabled} 해당 내용들은 `rest`에 자동 등재
{...rest}
>
{icon && <img src={icon} alt="" className={styles.icon} />}
{children}
</button>
);
}
export default Button;There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
방금 제안드린 내용에서 추가
사실, 여기서 icon 또한 button의 children으로 포함시킬 수도 있긴 하겠네요 😊
예를 들어서 다음과 같이요 !:
<Button variant="error" className="flex justify-between w-24 items-center">삭제<DeleteIcon /></Button>| import debounce from "lodash.debounce"; | ||
|
|
||
| function useWindowSize() { | ||
| function useWindowSize(delay = 300) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
크으 ~ 피드백 반영 좋습니다 현지님 👍
| <h2 className={styles.featureTag}>Search</h2> | ||
| <h3 className={styles.bold}>구매를 원하는 상품을 검색하세요</h3> | ||
| <p className={styles.featureDescription}> | ||
| 구매하고 싶은 물품은 검색해서 | ||
| <br /> | ||
| 쉽게 찾아보세요 | ||
| </p> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
h 시리즈가 순차적으로 잘 들어갔네요 👍
| <div className={`${styles.features} ${styles.wrapper}`}> | ||
| <div className={styles.feature}> | ||
| <img src={HomeImg1} width="68.5%" alt="인기 상품" /> | ||
| <div className={styles.featureContent}> | ||
| <h2 className={styles.featureTag}>Hot item</h2> | ||
| <h3 className={styles.bold}>인기 상품을 확인해 보세요</h3> | ||
| <p className={styles.featureDescription}> | ||
| 가장 HOT한 중고거래 물품을 | ||
| <br /> | ||
| 판다 마켓에서 확인해 보세요 | ||
| </p> | ||
| </div> | ||
| </div> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(제안/선택) section을 사용하셔도 될 것 같아요.
| <div className={`${styles.features} ${styles.wrapper}`}> | |
| <div className={styles.feature}> | |
| <img src={HomeImg1} width="68.5%" alt="인기 상품" /> | |
| <div className={styles.featureContent}> | |
| <h2 className={styles.featureTag}>Hot item</h2> | |
| <h3 className={styles.bold}>인기 상품을 확인해 보세요</h3> | |
| <p className={styles.featureDescription}> | |
| 가장 HOT한 중고거래 물품을 | |
| <br /> | |
| 판다 마켓에서 확인해 보세요 | |
| </p> | |
| </div> | |
| </div> | |
| <section className={`${styles.features} ${styles.wrapper}`}> | |
| <div className={styles.feature}> | |
| <img src={HomeImg1} width="68.5%" alt="인기 상품" /> | |
| <div className={styles.featureContent}> | |
| <h2 className={styles.featureTag}>Hot item</h2> | |
| <h3 className={styles.bold}>인기 상품을 확인해 보세요</h3> | |
| <p className={styles.featureDescription}> | |
| 가장 HOT한 중고거래 물품을 | |
| <br /> | |
| 판다 마켓에서 확인해 보세요 | |
| </p> | |
| </div> | |
| </section> |
영역이 구분되며 h로 각 섹션의 정체성이 명확하므로 section태그도 괜찮은 의미일 것 같아서 제안드려요:
다음은 MDN의 <section>에 대한 설명 중 첫 문장입니다.
The
<section>HTML element represents a generic standalone section of a document, which doesn't have a more specific semantic element to represent it. Sections should always have a heading, with very few exceptions.
<section>HTML 요소는 문서의 일반적인 독립형 섹션을 나타내며 이를 나타내는 더 구체적인 의미 요소가 없습니다. 섹션에는 거의 예외를 제외하고 항상 제목이 있어야 합니다.
| function ItemCommentCard({ | ||
| comment: { | ||
| content, | ||
| updatedAt, | ||
| writer: { nickname, image }, | ||
| }, | ||
| }) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
크으 이렇게 props를 받으니까 comment가 어떤 구성으로 되어있는지 파악하기 좋네요 👍👍
| {isEditMode ? ( | ||
| <div className={styles.buttonContainer}> | ||
| <button | ||
| type="button" | ||
| className={styles.cancelButton} | ||
| onClick={handleEditCancel} | ||
| > | ||
| 취소 | ||
| </button> | ||
| <PrimaryButton | ||
| type="submit" | ||
| className={styles.editCompleteButton} | ||
| disabled={!editAvailable} | ||
| onClick={handleEditComplete} | ||
| > | ||
| 수정 완료 | ||
| </PrimaryButton> | ||
| </div> | ||
| ) : ( | ||
| "" | ||
| )} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
다음과 같이 작성해볼 수 있습니다 !:
| {isEditMode ? ( | |
| <div className={styles.buttonContainer}> | |
| <button | |
| type="button" | |
| className={styles.cancelButton} | |
| onClick={handleEditCancel} | |
| > | |
| 취소 | |
| </button> | |
| <PrimaryButton | |
| type="submit" | |
| className={styles.editCompleteButton} | |
| disabled={!editAvailable} | |
| onClick={handleEditComplete} | |
| > | |
| 수정 완료 | |
| </PrimaryButton> | |
| </div> | |
| ) : ( | |
| "" | |
| )} | |
| {isEditMode && ( | |
| <div className={styles.buttonContainer}> | |
| <button | |
| type="button" | |
| className={styles.cancelButton} | |
| onClick={handleEditCancel} | |
| > | |
| 취소 | |
| </button> | |
| <PrimaryButton | |
| type="submit" | |
| className={styles.editCompleteButton} | |
| disabled={!editAvailable} | |
| onClick={handleEditComplete} | |
| > | |
| 수정 완료 | |
| </PrimaryButton> | |
| </div> | |
| )} |
| const handleLoad = async () => { | ||
| try { | ||
| const { list, nextCursor } = await getItemComments(productId, { | ||
| cursor, | ||
| }); | ||
| setComments((prev) => [...prev, ...list]); | ||
| setCursor(nextCursor); | ||
| } catch (error) { | ||
| alert(error.message); | ||
| console.error("ERROR: ", error); | ||
| } | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
해당 함수는 useCallback을 사용해볼 수 있습니다 !:
const handleLoad = useCallback(async () => {
try {
const { list, nextCursor } = await getItemComments(productId, { cursor });
setComments((prev) => [...prev, ...list]);
setCursor(nextCursor);
} catch (error) {
alert(error.message);
console.error("ERROR: ", error);
}
}, [productId, cursor]); // ✅ 의존성 추가|
수고하셨습니다 현지님 ! 미션 수행하시느라 수고 많으셨습니다 현지님 ! 😊👍 |
요구사항
기본
상품 상세
상품 문의 댓글
심화
주요 변경사항
handleLoad함수를useEffect안에 선언alt=""로 수정handleLoad함수를useEffect안에 선언alt=""로 수정alt=""로 수정멘토에게