수업내용: form을 array.map()으로 랜더링
장점: 반복되는 코드 사용을 줄여서 간단히 만들고 최종적으로 컴포넌트화 시켜서 다시 사용할 수 있다.
이것을 하려면 몇가지 자바스크립트 문법을 알아야 더 유용하게 사용할 수 있다.
1)객체에 대해서 그리고 객체의 key 를 값으로 불러오는 방법
2)array.map()
3)switch문 : switch 문은 "만약~라면 아래와 같이하라" 에서 합치고는 싶은데 뭔가 종류가 다를데 만약~라면 사이에서 분류가 되어지는 용도로 쓰인다. 예시에서 input, textarea, select 태그가 세개 있었기 때문에 분류하기 위해서 썻다. if문과 다르게 조건식 두 개가 사용된다. switch 옆 소괄호 조건식의 값이 case의 비교조건식 값과 일치할 때 해당 실행문이 실행. switch문은 일치하는 case를 발견하면 일치여부와 상관없이 그 아래 case문을 모두 실행시키기 때문에 break문을 써서 수동으로 빠져나오는 것이 좋겠다.
let value = "z";
switch(value){
case 'A':
console.log("A");
break;
case 'B':
console.log("B");
break;
case 'C':
console.log("C");
break;
default:
console.log("아무것도 일치하지 않음")
}
//아무것도 일치하지 않음
과정
1. 먼저 순회하면서 form을 만들 list를 만든다. 특이사항은 value는 options에만 써주었다. 왜냐하면 { type: "text", name: "title", placeholder: "Title", tag: "input" , value={todo.title}} 이렇게 써주면 초깃값처럼 설정되어 버려서
onChange 핸들러가 작동하면서 setTodo 함수가 실행되며 value가 채워지는데 거기에 동적으로 대응할 수가 없다.
const formFieldArray = [
{ type: "text", name: "title", placeholder: "Title", tag: "input" },
{ type: "date", name: "date", placeholder: "Date", tag: "input" },
{
name: "category",
placeholder: "Category",
tag: "select",
options: [
{ value: "category", title: "category" },
{ value: "study", title: "study" },
{ value: "work", title: "work" },
{ value: "diary", title: "diary" },
],
},
{ name: "todo", placeholder: "To do", tag: "textarea" },
{ type: "file", name: "file", placeholder: "File", tag: "input" },
];
const [todo, setTodo] = useState({
id: uuidv4(),
title: "",
date: "",
file: "",
category: "",
todo: "",
});
value= {todo?.[map매개변수명.name]}
위와 같이 사용해준 이유는 todo의 상태에 접근하면서 동적으로 입력된 value의 내용을 가져오기 위해서 위와 같이 사용한다.
{formFieldArray.map((field) => {
switch (field?.tag) {
case "input":
return (
<input
type={field?.type}
name={field?.name}
placeholder={field?.placeholder}
value={todo?.[field?.name]}
onChange={handleChange}
/>
);
case "textarea":
return (
<textarea
value={todo?.[field?.name]}
name={field?.name}
placeholder={field?.placeholder}
onChange={handleChange}
/>
);
case "file":
return (
<input
type={field?.type}
name={field?.name}
onChange={handleChange}
/>
);
case "select":
return (
<select
name={field?.name}
value={todo?.[field?.name]}
onChange={handleChange}
>
{field?.options?.map((option) => {
return (
<option key={option.title}
value={option.value}>
{option.title}
</option>
);
})}
</select>
);
default:
return null;
}
})}
예시 :
const [error, setError] = useState({
title: "",
date: "",
category: "",
todo: "",
file: "",
});
{Object.values(error).some((value) => value) && (
<p style={{ color: "red" }}>{error[field.name]}</p>
)}