프론트엔드/React

[React] 컴포넌트의 계층 구조와 프로퍼티(Props)로 값 전달하기

MINJIN's 2024. 1. 11. 09:24

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가 저장되어 있기 때문에 해당 컴포넌트를 렌더링한 다.