Component 재사용

younghyun·2022년 3월 13일
0

화면을 보고 구성 요소 분할해보기


화면을 구성하는 요소들을 다음과 같이 나누어 볼 수 있습니다

두 레이아웃에서 반복적으로 사용되는 요소와 변화되는 요소들이 보이시나요?!
변화하는 부분들이 있다고 하더라도 매번 다른 코드로 처리할 필요 없이 컴포넌트화 하여 사용할 수 있습니다.

// before -> 두 개의 내용을 표현하기 위한 두 개의 컴포넌트
isMyID ? <ProfileMyID /> : <ProfileOtherID />

// after -> 두 개의 내용을 표현하기 위한 하나의 컴포넌트
const MY_ID = 'younuk'
const OTHER_ID = 'dohyun'

isMyID ? <Profile userID={MY_ID} /> : <Profile userID={OTHER_ID} />

위와 같이 Props를 통해 각각 달리 표시해주고 싶은 값들을 해당 컴포넌트에 넘겨주면 하나의 컴포넌트로 여러가지 형태로 사용할 수 있는 재사용성 높은 컴포넌트가 됨

하위 컴포넌트로 내려줘야 할 데이터 구조 결정하기

요소들을 어떻게 분할할지 결정했다면, 각 요소에 내려줄 prop 들의 구조를 결정해야 함. 아래 예시를 보며 확인.

// Modal.js
export default function Modal() {
  return (
    <div className="modal">
      <Form type="signUp" title="회원가입" inputData={signUpData} />
    </div>
  );
}

const signUpData = [
  {
    type: "name",
    text: "이름",
  },
  {
    type: "email",
    text: "이메일",
  },
  {
    type: "password",
    text: "비밀번호",
  },
]
// Form.js
import FormLayout from "./FormLayout";
import Input from "./Input";
import Button from "./Button";

// 일부 생략된 코드가 있습니다!
export default function Form({ type, title, inputData }) {

  return (
    <FormLayout>
      <h2>{title}</h2>
      <div>
        {inputData.map((input, index) => (
          <Input
            key={index}
            type={input.type}
            placeholder={input.text}
          />
        ))}
      </div>
      <Button value={title} />
      {type === "signUp" && (
        <p className="isAlreadyLogin">
          이미 가입하셨나요? <span>로그인</span>
        </p>
      )}
    </FormLayout>
  );
}

Modal.js의 signUpProps는

의 props로 전달되면서 컴포넌트 안쪽으로 전달되고 있는 값. 코드로 확인할 수 있다시피 하위 컴포넌트에서는 상위 컴포넌트에서 전달해주는 값에 따라 다른 데이터를 출력하게 됨.

  • type : signUp인지 signIn인지를 구분하기 위한 값 + 회원가입일 경우 "이미 가입하셨나요?"를 출력
  • title: 모달 창의 타이틀과 버튼에 출력될 텍스트
  • inputData: Input 컴포넌트를 그려내기 위해 필요한 정보를 담고 있는 배열
    • type: input 태그의 type이 password인지를 체크
    • text: input 태그의 placeholder에 출력될 텍스트

this.props.children.

import React from "react";

function FormLayout({ children }) {
  return (
    <div className="form">
      <header>
        <div className="logo" />
      </header>
      {children} // 컴포넌트로 감싸진 부분이 이곳에 들어옵니다!
    </div>
  );
}

export default FormLayout

// Form.js
<FormLayout>...</FormLayout>

앞서 살펴봤던 요소들 중에 "폼 레이아웃"과 "로고"를 다시 한번 살펴봄.
로그인 / 회원가입 양쪽에서 모두 쓰이며, 같은 자리에 위치하고 있음. 이 부분을 children을 사용해 묶어줄 수 있음.
리액트 컴포넌트는 props로 children이라는 걸 받음. 이를 통해 일반 JavaScript 데이터(ex. number, string, ...) 뿐만 아니라 HTML 태그(ex. div, li, ...) 컴포넌트(JSX Element) 등 어떤 값이든 배열로 받아올 수 있음.
단, Object만큼은 예외. 태그와 태그 사이의 자리에 Object 데이터가 들어오게 된다면 Uncaught Error: Objects are not valid as a React child 에러를 발생시킴.
추가적인 내용은 공식 문서를 보며 좀 더 자세히 학습.
일단 간단히만 설명하자면, 앞으로 <FormLayout></FormLayout> 로 감싸진 부분은 위 코드 예제의 props.children 자리에 들어오게 된다는 뜻.

profile
선명한 기억보다 흐릿한 메모

0개의 댓글