Skip to content
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

고태호 [sprint 7] #101

Merged

Conversation

kotaeho
Copy link
Collaborator

@kotaeho kotaeho commented Sep 21, 2024

요구사항

기본

  • DetailPage 상세페이지 구현
  • 네비게이션 링크 구현
  • 검색기능 구현

심화

주요 변경사항

스크린샷

image

멘토에게

  • 셀프 코드 리뷰를 통해 질문 이어가겠습니다.

@kotaeho kotaeho added the 매운맛🔥 뒤는 없습니다. 그냥 필터 없이 말해주세요. 책임은 제가 집니다. label Sep 21, 2024
@kotaeho kotaeho changed the title React 고태호 고태호 [sprint 7] Sep 22, 2024
Copy link
Collaborator

@GANGYIKIM GANGYIKIM left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

태호님 이번 스프린트 미션 고생하셨습니다~
이름만 조금 더 신경써주시면 좋을 것 같아요~

background-color: ${(props) => (props.$active ? "#4a90e2" : "#9ca3af")};
`;

const Additemheader = ({ isButtonActive }) => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1:

Suggested change
const Additemheader = ({ isButtonActive }) => {
const AddItemHeader = ({ isButtonActive }) => {

Comment on lines +85 to +113
useEffect(() => {
const mediaQuery = window.matchMedia("(max-width: 768px)");
const fetchBestProducts = async () => {
const pageSize = mediaQuery.matches ? 2 : 4;
try {
const data = await fetchProducts(1, "favorite", pageSize);
setBestProducts(data.list);
} catch (error) {
console.error("Error fetching best products:", error);
}
};
fetchBestProducts();
}, []);

const [bestProducts, setBestProducts] = useState([]);
const [filterProducts, setFilterProducts] = useState([]);

useEffect(() => {
setFilterProducts(sortedProducts);
}, [sortedProducts]);

const handleSearchChange = (e) => {
const inputValue = e.target.value;

const filterProduct = sortedProducts.filter((element) => {
return element.name.startsWith(inputValue);
});
setFilterProducts(filterProduct);
};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3:
변수나 state는 최상단으로 배치해주시는게 가독성에 더 좋습니다.

Suggested change
useEffect(() => {
const mediaQuery = window.matchMedia("(max-width: 768px)");
const fetchBestProducts = async () => {
const pageSize = mediaQuery.matches ? 2 : 4;
try {
const data = await fetchProducts(1, "favorite", pageSize);
setBestProducts(data.list);
} catch (error) {
console.error("Error fetching best products:", error);
}
};
fetchBestProducts();
}, []);
const [bestProducts, setBestProducts] = useState([]);
const [filterProducts, setFilterProducts] = useState([]);
useEffect(() => {
setFilterProducts(sortedProducts);
}, [sortedProducts]);
const handleSearchChange = (e) => {
const inputValue = e.target.value;
const filterProduct = sortedProducts.filter((element) => {
return element.name.startsWith(inputValue);
});
setFilterProducts(filterProduct);
};
const [bestProducts, setBestProducts] = useState([]);
const [filterProducts, setFilterProducts] = useState([]);
const handleSearchChange = (e) => {
const inputValue = e.target.value;
const filterProduct = sortedProducts.filter((element) => {
return element.name.startsWith(inputValue);
});
setFilterProducts(filterProduct);
};
useEffect(() => {
const mediaQuery = window.matchMedia("(max-width: 768px)");
const fetchBestProducts = async () => {
const pageSize = mediaQuery.matches ? 2 : 4;
try {
const data = await fetchProducts(1, "favorite", pageSize);
setBestProducts(data.list);
} catch (error) {
console.error("Error fetching best products:", error);
}
};
fetchBestProducts();
}, []);
useEffect(() => {
setFilterProducts(sortedProducts);
}, [sortedProducts]);

Comment on lines +106 to +113
const handleSearchChange = (e) => {
const inputValue = e.target.value;

const filterProduct = sortedProducts.filter((element) => {
return element.name.startsWith(inputValue);
});
setFilterProducts(filterProduct);
};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1:
검색 input에 값이 입력된 것에 따라 상품 목록이 보이는것은 products api의 keyword param을 통해 구현하세요~

https://panda-market-api.vercel.app/docs/#/Product/ListProducts

<Container>
<Additemheader isButtonActive={isButtonActive} />
<main>
<ItemImage setItem={setItem} />
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3:
이렇게 set 함수 자체를 넘기게 되면 각 컴포넌트에서 해당하는 데이터 이외의 것도 변경이 가능해지니
onChange 함수를 하나 만드셔서

const onChange = (key, value) => {
  setItem((prev) => ({...prev, [key]: value }))
}

해당 함수를 전달하시면 각 컴포넌트 내부에서 변경될 값만 넘기게 처리가 가능합니다.

<ItemName onChange={(value) => onChange('name', value)} />
<ItemIntro onChange={(value) => onChange('intro', value)} />

더 추천하는 방식은 ItemName, ItmePrice 같은 input에 name 속성을 주시고 event 객체를 받아 내부에서 처리하는 것입니다.

const onChange = (e) => {
  const target = e.target;
  setItem((prev) => ({...prev, [target.name]: target.value }))
}
...
<ItemName onChange={onChange />

onKeyDown={handleKeyPress}
placeholder="태그를 입력해주세요"
/>
<div style={{ display: "flex", flexWrap: "wrap" }}>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2:
inline style보다 class를 통해 처리해주세요~

font-size: 18px;
line-height: 26px;
`;
const Itemprice = ({ setItem }) => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2:
만약 styledComponent로 만든 ItemPrice인풋과 이름이 겹처러 이렇게 작업하신거라면
ItemPrice를 Input같이 조금더 일반적인 이름으로 바꾸시고 Itemprice를 ItemPrice로 변경하시는걸 추천드립니다.

...prev,
intro: value.length > 0,
}));
console.log("intro");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3:

Suggested change
console.log("intro");

<PaginationButton
key={number}
onClick={() => handlePageClick(number)}
$clicked={activePage === number}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2:
clicked 보다 더 적절한 이름으면 좋겠네요.

Suggested change
$clicked={activePage === number}
$isActive={activePage === number}

Comment on lines +37 to +41
pageButtons.forEach((num, index) => {
pageButtons[index] = activePage + index + 1;
});
setActivePage(activePage + 1);
setPageButtons(pageButtons);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1:
state를 직접적으로 수정하지마세요.
아래처럼 pageButtons의 복사본을 만들고 이를 수정하세요.

      const newPageButtons = [...pageButtons];
      newPageButtons.forEach((num, index) => {
        newPageButtons[index] = activePage + index + 1;
      });
      setActivePage(activePage + 1);
      setPageButtons(newPageButtons);
      const newPageButtons = [...pageButtons].map((_, index) => {
        return  activePage + index + 1;
      });
      setActivePage(activePage + 1);
      setPageButtons(newPageButtons);

Comment on lines +63 to +64
<Link to={"/"}>자유게시판</Link>
<Link to={"/additem"}>중고마켓</Link>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3:
페이지 주소가 “/additem” 일때 상단네비게이션바의 '중고마켓' 버튼의 색상은 “3692FF”입니다. 해당 요구사항을 충족시키시려면 reactRouterDom 라이브러리의 NavLink 컴포넌트를 활용해보세요.

https://reactrouter.com/en/main/components/nav-link

@GANGYIKIM GANGYIKIM merged commit 13d6300 into codeit-bootcamp-frontend:React-고태호 Sep 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
매운맛🔥 뒤는 없습니다. 그냥 필터 없이 말해주세요. 책임은 제가 집니다.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants