당근마켓 클론을 하다가 막힌 곳. 이제부터 돌멩이라고 칭하겠다.
상품 업로드시 카테고리를 추가하는 작업을 하고 있었다.
RHF을 사용중인데 카테고리가 여러개에서 골라진 녀석을 register 값으로 넣어주고 싶었다.
interface UploadProductForm {
name: string;
price: number;
description: string;
image: FileList;
category: {
[key:string]: string
}
}
const { register, handleSubmit, watch } = useForm<UploadProductForm>();
{categoryList.map((item) => (
<div key={item.label} className="col-span-1">
<CategoryInput
label={item.label}
path={item.path}
icon={item.icon}
name={item.name}
register={register(category.item.name))}
/>
</div>
))}
타입오류가 계속 생겨서 고민고민고민.
useFieldArray를 알게되어서 살펴보니 이건 내게 지금 필요한 기능이 아니었다.
사용자에게 동적인 입력 필드를 추가하거나 삭제할 수 있게 하는 경우에 매우 유용한 기능.
그냥 카테고리에 디폴트 값을 주고 버튼을 눌렀을 때 디폴트 값이 바뀌도록 setValue를 쓰는걸로 합의!
const { register, handleSubmit, watch, control } = useForm<UploadProductForm>({
defaultValues:{
category: "기타"
}
});
const category = watch("category");
<CategoryInput
onClick={(category: any) => setValue("category", category)}
/>
<div>{icon}</div>
오류가 뜬다. 이유를 알아보아하니 다음과 같았다.
<div>{icon}</div>에서 icon을 렌더링하면 icon이 하나의 React 엘리먼트가 아니라 컴포넌트 렌더링이 아닌 React 엘리먼트를 렌더링하려고 하게 됩니다. 이렇게 하면 icon이 문자열 또는 객체가 아닌 React 엘리먼트여야 합니다. 그래서 이 경우에 문제가 발생할 수 있습니다.
const CategoryInput = ({ label, path, icon: Icon, onClick, selected }: CategoryInputProps) => {
return (
<div>
<Icon size={30} />
<div>{label}</div>
</div>
);
};
props을 받을 때 icon: Icon으로 바꾸고 전달받은 Icon 컴포넌트를 그대로 렌더링 해야한다!!!