export const dummy = [
{ fruit: "Apple", color: "Red" },
{ fruit: "Strawberry", color: "Red" },
{ fruit: "Cherry", color: "Red" },
{ fruit: "Banana", color: "Yellow" },
{ fruit: "Lemon", color: "Yellow" },
{ fruit: "Blueberry", color: "Blue" },
];
dummy의 fruit를 리스트로 출력하는데
Red
Apple
Strawberry
Cherry
Yellow
Banana
Lemon
Blue
Blueberry
이런식으로 color출력 후 fruit을 출력하도록 구현해야 한다.
처음 방식은 useState를 사용해서 color값이 바뀔 때 한번 출력해주는 식으로 구현하였는데 useState가 바뀌고 바로 사용해서 무한 렌더링 발생...
그래서 초기에 color에 따라서 미리 그룹화하면
Color 출력 -> 그룹화한 객체들 출력가능하다 !!
useEffect()로 초기 렌더링 시 dummy를 그룹화
interface Types {
description: string;
key: string;
type: string;
}
const [data, setData] = useState<{ [key: string]: Types[] }>({});
useEffect(() => {
const dum: Record<string, Types[]> = dummy.reduce((acc, obj) => {
if (!acc[obj.color]) {
acc[obj.color] = [];
}
acc[obj.color].push(obj);
return acc;
}, {} as Record<string, Types[]>);
setData(dum);
}, []);
그룹화된 결과를 담을 acc와 현재 값인 obj
color에 따라 그룹화하므로 obj.color를 가져와서 acc에 있는지 확인하고
없으면 해당 color 빈배열 생성한다.
있으면 그 배열에 현재 obj를 집어넣는다.
미리 color를 타입을 지정해서 해도 되지만 color에 뭐가 있는지 모를 수 있고
다른 color를 가진 데이터가 추가 되는 경우에 유연하게 사용가능하도록 구현하고자 한다.
Record<Key, Value>
키가 Key타입이고 값이 Value 타입인 객체 타입을 생성함
useState에 저장하기 위해서 키가 string이고 값이 객체 타입이 필요하다
그래서 Record를 사용했다.
<div className="search-area">
{Object.keys(data).map((category) => (
<div className="category" key={category}>
<div>{category}</div>
{data[category].map((text, index) => (
<div key={index}>{text.fruit}</div>
))}
</div>
))}
</div>
Object.keys() 로 객체의 키값들, color을 배열에 집어넣고
color를 우선 출력한다.
그 후 data를 가져와서 지금 키값이 가지고 있는 Value값을 map으로
하나씩 출력해주면 된다. 😀
