본문 바로가기
프로그래밍/react

1-5) [리액트 기초] 컴포넌트 값 전달하기

by 플로어코딩 2024. 1. 24.

 

https://jframework.tistory.com/23

 

1-4) [리액트 기초] JSX란? JSX 문법

// src/components/Body.js import './Body.css'; const Body = () => { const numA = 1; const numB = 2; const strA = 'Hello'; const strB = 'World'; const boolA = true; const boolB = false; const objA = { a: 1, b: 2, c: 3 }; return ( Body {numA} + {numB} = {num

jframework.tistory.com

 

 

이어서..

 

리액트 앱을 만들다 보면 컴포넌트 간의 값을 전달해야 하는 상황이 발생한다.

 

리액트에서는 부모가 자식 컴포넌트에 단일 객체 형태로 값을 전달할 수 있다.

이 객체를 리액트에서는 Props(Properties) 라고 커뮤니케이션 용어로 사용한다.

 

예제로 변수 name에 값을 전달해보도록 하자

여기서 한 가지 주의할 부분은 Props는 부모가 자식에게만 전달 할 수 있다. 

자식이 부모에게 값을 전달하는 것은 불가능하다는 뜻이다.

 

위 예시로 보면 Body 컴포넌트에 Porps를 전달하려면 부모인 App 컴포넌트에서만 전달이 가능하다.

 

App.js를 수정해보자

 

// src/App.js

import './App.css';
import Header from './components/Header';
import Body from './components/Body';
import Footer from './components/Footer';

function App() {
  const name = "리액트앱";
  return (
    <div className="App">
      <Header />		
      {/* //Header 렌더링 추가 */}
      <Body name={name}/>
      <Footer />
    </div>
  );
}

export default App;

 

 

// src/components/Body.js

import './Body.css';

const Body = (props) => {
  const numA = 1;
  const numB = 2;
  const strA = 'Hello';
  const strB = 'World';
  const boolA = true;
  const boolB = false;
  const objA = { a: 1, b: 2, c: 3 };

  console.log('프로퍼티: ', props);

  return (
    <div className="body">
      <h1>Body props => {props.name}</h1>
      <h2>{numA} + {numB} = {numA + numB}</h2>
      <h2>{strA} + {strB} = {strA + strB}</h2>
      <h2>{ (boolA || boolB) ? '참입니다.' : '거짓입니다.'}</h2>
      <h2> {objA.a} :: {JSON.stringify(objA)} </h2>
    </div>
  );
}

export default Body;

 

 

 

 

 

 

값이 잘 전달되는 모습을 볼 수 있다.

전달되는 객체는  props 가 default 값인 부분도 확인 할 수 있다.

 

그럼 Props에 여러 개의 값을 전달해보자

 

// src/App.js

import './App.css';
import Header from './components/Header';
import Body from './components/Body';
import Footer from './components/Footer';

function App() {
  const name = "리액트앱";
  return (
    <div className="App">
      <Header />		
      {/* //Header 렌더링 추가 */}
      <Body name={name} addr={"평택"}/>
      <Footer />
    </div>
  );
}

export default App;

 

 

// src/components/Body.js

import './Body.css';

const Body = (props) => {
  const numA = 1;
  const numB = 2;
  const strA = 'Hello';
  const strB = 'World';
  const boolA = true;
  const boolB = false;
  const objA = { a: 1, b: 2, c: 3 };

  console.log('프로퍼티: ', props);

  return (
    <div className="body">
      <h1>Body props => {props.name} {props.addr}</h1>
      <h2>{numA} + {numB} = {numA + numB}</h2>
      <h2>{strA} + {strB} = {strA + strB}</h2>
      <h2>{ (boolA || boolB) ? '참입니다.' : '거짓입니다.'}</h2>
      <h2> {objA.a} :: {JSON.stringify(objA)} </h2>
    </div>
  );
}

export default Body;

 

 

 

 

스프레드 연산자로 여러 개의 값 전달하기

 

부모 컴포넌트에서 Props로 전달할 값이 많아지면, 값을 모두 태그에 명시해야하는 불편함이 생기며,

가독성도 좋아지지 않는다.

 

어떻게하면 해결할 수 있을까?

 

이때 자바스크립트에서 제공하는 스프레드 연산자를 활용하여 전달 가능하다.

 

아래 예시를 살펴보자

 

// src/App.js

import './App.css';
import Header from './components/Header';
import Body from './components/Body';
import Footer from './components/Footer';

function App() {
  const name = "리액트앱";
  const addr = "평택";
  const arrayNum = [1, 2, 3, 4, 5];
  const BodyPorps = {
    name: name,
    addr: addr,
    arr : arrayNum
  }

  return (
    <div className="App">
      <Header />		
      {/* //Header 렌더링 추가 */}
      <Body {...BodyPorps}/>
      <Footer />
    </div>
  );
}

export default App;

 

App 컴포넌트에서 Body 컴포넌트로 Props를 전달할 값을 객체 BodyPorps로 생성하고, 이를 스프레드 연산자를 통하여 Body 속성으로 Props를 전달하였다.

 

 

 

아래와 같이 새로운 BodyProps 를 선언 후 객체안에 여러 obj 타입을 넣어서 자식 컴포넌트에게 객체를 전달되는지를 확인하자

// src/App.js

import './App.css';
import Header from './components/Header';
import Body from './components/Body';
import Footer from './components/Footer';

function App() {
  const name = "리액트앱";
  const addr = "평택";
  const arrayNum = [1, 2, 3, 4, 5];
  const BodyProps = {
    name: name,
    addr: addr,
    arr : arrayNum,
    favorList: [
      { id: 1, name: '사과', price: 1000 },
      { id: 2, name: '바나나', price: 2000 },
      { id: 3, name: '포도', price: 3000 },
      { id: 4, name: '귤', price: 4000 },
      { id: 5, name: '배', price: 5000 },
    ]
  }

  return (
    <div className="App">
      <Header />		
      {/* //Header 렌더링 추가 */}
      <Body {...BodyProps}/>
      <Footer />
    </div>
  );
}

export default App;

 

 

 

 

// src/components/Body.js

import './Body.css';

// const Body = (props) => {
const Body = ({name, addr, arr, favorList}) => {
  const numA = 1;
  const numB = 2;
  const strA = 'Hello';
  const strB = 'World';
  const boolA = true;
  const boolB = false;
  const objA = { a: 1, b: 2, c: 3 };

  
  return (
    <div className="body">
      <h1>Body props</h1>
      <h5>{numA} + {numB} = {numA + numB}</h5>
      <h5>{strA} + {strB} = {strA + strB}</h5>
      <h5>{ (boolA || boolB) ? '참입니다.' : '거짓입니다.'}</h5>
      <h5> {objA.a} :: {JSON.stringify(objA)} </h5>
      <h5> {name} :: {addr}  :: {arr} :: {arr.length}</h5>
      <h5>{favorList.length} :: {favorList.map(i => i.name + ', ')}</h5>
    </div>
  );
}

Body.defaultProps = {
  arr: [],
  favorList:[{id:'1', name:'사과', price:'1000'},]
}


export default Body;

 

위와 같이 구조분해 할당을 이용하여 {name, addr, arr, favorList} 를 변수로 받아서 값을 가져왔다.

혹시 App 컴포넌트에서 Props 값 중 값이 null 이거나 전달되지 않으면 어떻게 될까?

 

당연히 properties 속성에 해당 변수가 없다고 뜰 것이다.

 

이런 경우에 대비하여 defaultProps를 사용한다.

 

defaultProps를 통하여 디폴트 값을 설정할 수 있기 때문에 방어코드를 통한 오류를 방지할 수 있을 뿐만 아니라

좀 더 유연한 코드를 작성할 수도 있다.

 

 

//자식 컴포넌트가 데이터를 전달받지 못하였을 때를 대비한 defaultProps

Body.defaultProps = {
  arr: [],
  favorList:[{id:'1', name:'사과', price:'1000'},]
}

 

 

 

여기까지 하다보면 따라오다보면 데이터 만의 값 전달이 아닌 컴포넌트 전달할 수 있으면 얼마나 좋을까?

라는 생각을 하는 사람도 있을 것이다.

 

물론 가능하다.

 

지금까지는 컴포넌트 간에 문자나 숫자, object 등의 값을 전달해보았지만 리액트는 컴포넌트를 전달할 수도 있다.

 

댓글