라이브러리 React
+ 상태관리 Zustand
하고 싶었던 것 : 원하는 카테고리와 해당 아이템만 열고 닫기
문제 발생 : 하나의 카테고리만 클릭해도 모든 카테고리가 동시에 열렸다!
영상을 업로드하는 어플리케이션으로, 원하는 카테고리(시리즈)를 설정하여 게시글을 작성할 수 있다.
카테고리(시리즈)는 이렇게 관리했다.
// categories.Js
export const categories = [
{ id: 1, name: 'Series_1' },
{ id: 2, name: 'Series_2' },
{ id: 3, name: 'Series_3' },
];
import React, { useState, useEffect } from 'react';
import { categories } from 'api/categories';
import IconArrowDown from 'assets/img/icon-arrow-down.png';
import IconArrowUp from 'assets/img/icon-arrow-up.png';
import postStore from 'store/postStore';
import {
UlSeries,
CategorySeries,
IconArrow,
DivSeries,
PostLi,
} from 'components/PostPortfolioUl/PostPortfolioUlStyle';
export default function PostPortfolioUl() {
// useState 사용하여 토글 관리
const [toggle, setToggle] = useState(true);
// 게시글 상태관리
const allposts = postStore((state) => state.data);
const callGetAPI = postStore((state) => state.getApi);
useEffect(() => {
callGetAPI();
}, []);
// 토글 핸들러
const toggleHandler = () => {
setToggle((prev) => !prev);
};
return (
<>
// map 이용해 카테고리(시리즈)명 보여주기
{categories.map((series) => {
return (
<UlSeries>
<CategorySeries>
// 카테고리(시리즈)명 불러오기
{series.name}
// 토글시 펼치는<->닫히는 아이콘과 함께 카테고리 열고 닫기
{toggle ? (
<IconArrow
src={IconArrowUp}
alt='펼침'
onClick={toggleHandler}
/>
) : (
<IconArrow
src={IconArrowDown}
alt='닫힘'
onClick={toggleHandler}
/>
)}
</CategorySeries>
// 토글시 카테고리가 열리면서 카테고리에 맞는 아이템 보여주기
<DivSeries style={{ display: toggle ? 'block' : 'none' }}>
{allposts &&
allposts
.slice(0)
.reverse()
.map((post, idx) =>
series.name === post.series ? (
<PostLi key={idx}>
<img src={post.thumnail} alt='영상 미리보기 이미지' />
</PostLi>
) : null
)}
</DivSeries>
</UlSeries>
);
})}
</>
);
}
import React, { useState, useEffect } from 'react';
import { categories } from 'api/categories';
import IconArrowDown from 'assets/img/icon-arrow-down.png';
import IconArrowUp from 'assets/img/icon-arrow-up.png';
import postStore from 'store/postStore';
import {
ContPortfolio,
UlSeries,
CategorySeries,
IconArrow,
DivSeries,
PostLi,
} from 'components/PostPortfolioUl/PostPortfolioUlStyle';
export default function PostPortfolioUl() {
// 상태값 관리
const [showItem, setShowItem] = useState([]);
const allposts = postStore((state) => state.data);
const callGetAPI = postStore((state) => state.getApi);
useEffect(() => {
callGetAPI();
}, []);
// 스프레드 연산자를 활용해 나머지 값은 저장
// 파라미터로 받은 값을 key로 사용
// 해당 값을 ! 활용해 true/false
const toggleHandler = (id) => {
setShowItem((prevShowItem) => ({
...prevShowItem,
[id]: !prevShowItem[id],
}));
};
return (
<ContPortfolio>
// map 활용해 카테고리 보여주기
{categories.map((series) => {
return (
<UlSeries>
<CategorySeries key={series.id}>
{series.name}
// 클릭시 토글 핸들러 함수 호출
// 파라미터 값으로 key 전달
{showItem[series.id] ? (
<IconArrow
src={IconArrowUp}
alt='펼침'
onClick={() => toggleHandler(series.id)}
/>
) : (
<IconArrow
src={IconArrowDown}
alt='닫힘'
onClick={() => toggleHandler(series.id)}
/>
)}
</CategorySeries>
// showItem[series.id] 키 값이 true인 경우 해당 아이템 보여주기 (해당하지 않으면 null)
<DivSeries
style={{ display: showItem[series.id] ? 'block' : 'none' }}
>
{allposts &&
allposts.slice(0).map((post, idx) =>
series.name === post.series ? (
<PostLi key={idx}>
<img src={post.thumnail} alt='영상 미리보기 이미지' />
</PostLi>
) : null
)}
</DivSeries>
</UlSeries>
);
})}
</ContPortfolio>
);
}
이렇게 원하는 카테고리와 해당 아이템만 열고 닫을 수 있게 되었다.
적용한 걸 이해하기 위해 포스팅해보았다!