화면을 구성하는 요소들을 다음과 같이 나누어 볼 수 있습니다
두 레이아웃에서 반복적으로 사용되는 요소와 변화되는 요소들이 보이시나요?!
변화하는 부분들이 있다고 하더라도 매번 다른 코드로 처리할 필요 없이 컴포넌트화 하여 사용할 수 있습니다.
// 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로 전달되면서 컴포넌트 안쪽으로 전달되고 있는 값. 코드로 확인할 수 있다시피 하위 컴포넌트에서는 상위 컴포넌트에서 전달해주는 값에 따라 다른 데이터를 출력하게 됨.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 자리에 들어오게 된다는 뜻.