3/2 수업내용 정리 - (리팩토링)form을 array.map()으로 랜더링

piper ·2024년 3월 2일
0

React

목록 보기
17/22

수업내용: 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" },
];
  1. Array.map() 랜더링되는 부분
    *value 부분에서 아래의 상태를 사용하고 있다.
  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;
              }
            })}
  1. 만약 에러처리와 같은 부가적으로 또 화면에 랜더링 되는 부분이 있다면
    그 부분도 만들어 줄 수 있다.

예시 :

 const [error, setError] = useState({
    title: "",
    date: "",
    category: "",
    todo: "",
    file: "",
  });

{Object.values(error).some((value) => value) && (
      <p style={{ color: "red" }}>{error[field.name]}</p>
                      )}
profile
연습일지

0개의 댓글