[React] 컴포넌트의 계층 구조와 프로퍼티(Props)로 값 전달하기
1. 컴포넌트를 페이지에서 렌더링하기
App.js
import "./App.css";
const Header = () => {
return (
<header>
<h1>header</h1>
</header>
);
};
function App() {
return (
<div className="App">
<Header />
</div>
);
}
export default App;
리액트는 다른 컴포너트를 태그로 감싸 사용한다. 이때 App처럼 다른 컴포넌트를 return문 내부에 포함하는 컴포넌트를 '부모 컴포넌트'라고 하며, App의 return문에 포함된 컴포넌트를 '자식 컴포넌트'라 한다.
Index.js
import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<App />);
index.js에서 루트 요소 아래에 App 컴포넌트를 배치해 렌더링한다. 그러면 import App from './App'; 를 통해 App.js를 찾아서 function App()인 컴포넌트와 자식으로 포함된 Header 컴포넌트를 렌더링 한다. 리액트는 자식으로 배치한 컴포넌트를 부모 컴포넌트와 함께 렌더링 한다. 컴포넌트를 웹 페이지에서 렌 더링하려면, App의 자식으로 배치하거나 Header처럼 자식으로 이미 배치된 컴포넌트의 또 다른 자식으로 배치해야 한다.
2. 컴포넌트를 파일로 분리
리액트에서는 보통 하나의 파일에 하나의 컴포넌트를 만든다. 컴포넌트를 여러 파일로 나누고, 하나의 폴더에서 관리한다.
Header.js
const Header = () => {
return (
<header>
<h1>header</h1>
</header>
);
};
export default Header;
Body.js
function Body() {
return (
<div>
<h1>body</h1>
</div>
);
}
export default Body;
Footer.js
const Footer = () => {
return (
<footer>
<h1>footer</h1>
</footer>
);
};
export default Footer;
위와 같이 하나의 파일에 하나의 컴포넌트를 저장한 후 App.js에 위 컴포넌트를 자식 컴포넌트로 배치해야 한다.
App.js
import "./App.css";
import Body from "./components/Body";
import Footer from "./components/Footer";
import Header from "./components/Header";
function App() {
return (
<div className="App">
<Header></Header>
<Body></Body>
<Footer></Footer>
</div>
);
}
export default App;
3. 컴포넌트에 값 전달
1) Props로 값 전달
리액트에서는 컴포넌트가 다른 컴포넌트에 값을 전달할 수 있다. 리액트에서는 부모가 자식 컴포넌트에 단일 객체 형태로 값을 전달할 수 있으며 이 객체를 Props라 한다. 보통 리액트에서는 게시판의 리스트 출력에서 구조는 같지만 내용은 다른 것을 컴포넌트로 만든다. 이 컴포넌트를 반복해서 렌더링하고, 각각의 내용을 Props로 전달한다.
App.js
import "./App.css";
import Body from "./components/Body";
import Footer from "./components/Footer";
import Header from "./components/Header";
function App() {
const name = "홍길동";
return (
<div className="App">
<Header></Header>
<Body name={name}></Body>
<Footer></Footer>
</div>
);
}
export default App;
Body 컴포넌트에 있는 변수 name을 props로 전달한다. 주의할 점은 부모만이 자식 컴포넌트에 전달할 수 있다. 따라서 Body 컴포넌트에 props를 전달하려면 부모인 app 컴포넌트에서 전달해야 한다.
2) 여러 개의 값 전달
App.js
import "./App.css";
import Body from "./components/Body";
import Footer from "./components/Footer";
import Header from "./components/Header";
function App() {
const name = "홍길동";
return (
<div className="App">
<Header></Header>
<Body name={name} location="서울시"></Body>
<Footer></Footer>
</div>
);
}
export default App;
Body.js
import "./Body.css";
function Body(props) {
console.log(props);
return (
<div className="body">
<h1>
{props.name}는 {props.location}에 거주합니다.
</h1>
</div>
);
}
export default Body;
Body.js
import "./Body.css";
function Body(props) {
const { name, location } = props;
return (
<div className="body">
<h1>
{name}는 {location}에 거주합니다.
</h1>
</div>
);
}
export default Body;
props로 전달된 값이 많으면, 이 값을 사용할 때마다 객체의 dot(.) 표기법을 사용하기에는 불편하다. 그런데 props는 객체이므로 구조 분해 할당하면 간편하게 사용할 수 있다.
App.js
import "./App.css";
import Body from "./components/Body";
import Footer from "./components/Footer";
import Header from "./components/Header";
function App() {
const BodyProps = { name: "제우스", location: "경기도" };
return (
<div className="App">
<Header></Header>
<Body {...BodyProps} />
<Footer></Footer>
</div>
);
}
export default App;
스프레드(spread) 연산자는 ‘…’ 기호로 표기하는데, 전개 연산자라고도 한다. 스프레드 연산자를 이용하면 배열, 문자열, 객체 등과 같이 반복이 가능한 객체의 값을 개별 요소로 분리할 수 있다. 부모 컴포넌트에서 props로 전달할 값이 많으면, 값을 일일이 명시해야 하므로 불편하고 가독성이 떨어 진다. 이 때 props로 값을 하나의 객체로 만든 다음, 스프레드 연산자를 활용해 전달하면 훨씬 간결하게 코드를 작성할 수 있다. 다음과 같이 App에서 Body 컴포넌트로 전달할 값을 객체로 만든 다음, 스프레드 연산자를 이용해 객체 의 프로퍼티를 각각 props 값으로 전달한다.
3) Children
리액트에서는 자식 컴포넌트에 또 다른 컴포넌트를 배치하면, 배치된 컴포넌트는 자동으로 props의 children 프로퍼티에 저장되어 전달된다.
App.js
import "./App.css";
import Body from "./components/Body";
import Footer from "./components/Footer";
import Header from "./components/Header";
function ChildComp() {
return <div>자식 컴포넌트에 전달</div>;
}
function App() {
return (
<div className="App">
<Header></Header>
<Body>
<ChildComp />
</Body>
<Footer></Footer>
</div>
);
}
export default App;
Body.js
import "./Body.css";
function Body({ children }) {
return <div className="body"> {children} </div>;
}
export default Body;
props의 children 프로퍼티로 전달되는 자식 컴포넌트는 값으로 취급하므로 JSX의 자바스크립트 표현식으 로 사용할 수 있다. children에는 컴포넌트 ChilComp가 저장되어 있기 때문에 해당 컴포넌트를 렌더링한 다.