React/타입스크립트로 배우는 리액트(React.js) : 기초부터 최신 기술까지

섹션 4. 컴포넌트와 Props

favor 2026. 3. 26. 18:50

조상, 부모, 자식, 자손 

자식 : 바로 하위의 컴포넌트

자손 : 자식 컴포넌트의 자식 컴포넌트

부모 : 바로 상위의 컴포넌트 

조상 : 부모 컴포넌트의 부모 컴포넌트 

형제 : 같은 부모를 가진 컴포넌트

 

기본 데이터 출력하기

{ 변수명 or 표현식 }

 

export default function App() {
  // 기본 자료형
  const primitiveString = "Hello, World!";
  const primitiveNumber = 42;
  const primitiveBoolean = false;
  const primitiveUndefined = undefined;
  const primitiveNull = null;
  const primitiveSymbol = Symbol("mySymbol");
  const primitiveBigInt = 9007199254740991n;

  return (
    <>
      <h2>기본 자료형 출력</h2>
      <p>문자열: {primitiveString}</p>
      <p>숫자: {primitiveNumber}</p>
      <p>논리형: {primitiveBoolean.toString()}</p>
      <p>undefined: {String(primitiveUndefined)}</p>
      <p>null: {String(primitiveNull)}</p>
      <p>symbol: {String(primitiveSymbol)}</p>
      <p>bigInt: {primitiveBigInt}</p>
      
    </>
  );
}

 

React는 논리형 값, undefined, null, symbol은 렌더링 가능한 요소로 취급 X

  •  논리형 값을 화면에 출력하기 위해서는 wrapper 객체를 사용해 문자열로 변경 후에  출력해야 함
  • undefined, null, symbol 값을 화면에 출력하기 위해서는 자바스크립트 내장 함수인 String()을 사용해 문자열로 변경 후에 출력해야 함  

 

참조 데이터 출력하기

export default function App() {
  const referenceArray = [1, 2, 3, 4];
  const referenceObject = { name: "John", age: 30 };
  const referenceFunction = () => "함수의 리턴 값";
  const referenceDate = new Date();
  const referenceRegExp = /react/i;
  const referenceMap = new Map([
    ["key1", "value1"],
    ["key2", "value2"],
  ]);
  const referenceSet = new Set([1, 2, 3, 4]);

  return (
    <>
      <h2>참조 자료형 출력</h2>
      <p>배열: {referenceArray}</p>
      <p>객체: {JSON.stringify(referenceObject)}</p>
      <p>함수: {referenceFunction.toString()}</p>
      <p>Date 객체: {referenceDate.toString()}</p>
      <p>정규식: {referenceRegExp.toString()}</p>
      <p>Map: {JSON.stringify(Array.from(referenceMap))}</p>
      <p>Set: {JSON.stringify(Array.from(referenceSet))}</p>
    </>
  );
}

  • { 배열 }
    • 각 요소만이 평가되어 출력됨 
  • { 객체 }   
    • React는 객체를 표현식으로 출력하지 못함
    • 객체를 화면에 렌더링하기 위해서는 JSON.stringify() 메소드를 사용해 문자열로 변경 후에 출력해야 함 
  • { 함수 }
    • React는 함수를 표현식으로 출력하지 못함
    • 함수를 화면에 렌더링하기 위해서는 wrapper 객체를 사용해 문자열로 변경 후에 출력해야 함 
  • { Date 객체 }
    • React는 Date 객체를 표현식으로 출력하지 못함
    • 객체를 화면에 렌더링하기 위해서는 wrapper 객체를 사용해 문자열로 변경 후에 출력해야 함 
  • { 정규식 }
    • React는 정규식을 표현식으로 출력하지 못함
    • 정규식을 화면에 렌더링하기 위해서는 wrapper 객체를 사용해 문자열로 변경 후에 출력해야 함 
  • { Map }
    • 결국 배열로 여겨져서 각 요소만이 평가되어 출력됨 
    • Map 형식대로 화면에 렌더링하기 위해서는 JSON.stringify() 메소드와 Array.from() 메소드를 사용해 문자열로 변경 후에 출력해야 함 
  • { Set }
    • 결국 배열로 여겨져서 각 요소만이 평가되어 출력됨 
    • Set 형식대로 화면에 렌더링하기 위해서는 JSON.stringify() 메소드와 Array.from() 메소드를 사용해 문자열로 변경 후에 출력해야 함

 

태그의 속성 값에 바인딩하기 

데이터 바인딩을 위해 중괄호 {}를 사용하여 자바스크립트 값을 속성에 전달 가능

 

1. 동적으로 src 속성 값 설정하기 (이미지)

export default function App() {
  const imageUrl = "https://example.com/image.jpg";
  return (
    <div>
      <img src={imageUrl} alt="Example" />
    </div>
  );
}

^ 이미지 태그에서 src 속성에 동적으로 값을 전달하는 예시

imageUrl 변수를 src 속성 값으로 전달 

 

2. 동적으로 href 속성 값 설정하기 (링크)

export default function App() {
  const url = "https://www.example.com";

  return (
    <div>
      <a href={url} target="_blank" rel="noopener noreferrer">
        Visit Example
      </a>
    </div>
  );
}

^ 링크 태그에서 href 속성에 동적으로 값을 설정하는 예시

href 속성에 url 변수를 사용하여 링크를 동적으로 설정

 

컴포넌트에 데이터 전달하기 1

부모 컴포넌트가 자식 컴포넌트에게 데이터를 전달 가능 

부모 --> 자식 (O)

부모 --> 자손 (X)

자식 --> 부모 (X)

자식 --> 조상 (X)

형제 --> 형제 (X)

 

// App.tsx

import User from "./components/User";

export default function App() {
  return (
    <>
      <User name="Jack" age={20} />
      <User name="Mike" age={30} />
    </>
  );
}
// User.tsx

// 부모가 보낸 속성 값 전체를 props라는 이름으로 넘겨받음
export default function User (props: { name: string; age: number }) { // 자료형을 지정해주어야 에러 X
  return (
    <>
      <div> 
        <p>name: {props.name}</p>
        <p>age: {props.age}</p>
      </div>
    </>
  );
}

 

데이터를 전달하기 위해서는 컴포넌트의 속성으로 값을 넘겨주기

== Props를 전달

 

컴포넌트에 데이터 전달하기 2

// App.tsx

import PrintValue from "./components/PrintValue";

export default function App() {
  const numberValue = 42;
  const stringValue = "Hello World";
  const booleanValue = true;
  const arrayValue = [1, 2, 3, 4];
  const objectValue = { name: "John Doe", age: 30 };
  const handleClick = () => alert("버튼이 클릭되었습니다!");

  return (
    <>
      <PrintValue
        numberValue={numberValue}
        stringValue={stringValue}
        booleanValue={booleanValue}
        arrayValue={arrayValue}
        objectValue={objectValue}
        handleClick={handleClick} />
    </>
  );

}
// PrintValue.tsx

export default function PrintValue (props: {
  numberValue: number;
  stringValue: string;
  booleanValue: true | false;
  arrayValue: number[];
  objectValue: { name: string, age: number };
  handleClick: () => void;
}) {
  return (
    <>
      <p>number: {props.numberValue}</p>
      <p>string: {props.stringValue}</p>
      <p>boolean: {props.booleanValue.toString()}</p>
      <p>arrayValue: {props.arrayValue}</p>
      <p>object: {JSON.stringify(props.objectValue)}</p>
      <p>function: {props.handleClick.toString()}</p>
    </>
  );
}

 

부모로부터 넘겨받는 props는 객체 형태

각각의 타입을 선언해주어야 타입 에러가 나지 않음 

 

비구조화 할당하기

비구조화 할당 : props로 넘겨받는 것이 아니라 각각의 변수 이름으로 넘겨받는 것

 

// PrintValue.tsx

export default function PrintValue({
  numberValue,
  stringValue,
  booleanValue,
  arrayValue,
  objectValue,
  handleClick,
}: {
  numberValue: number;
  stringValue: string;
  booleanValue: true | false;
  arrayValue: number[];
  objectValue: { name: string; age: number };
  handleClick: () => void;
}) {
  return (
    <>
      <p>number: {numberValue}</p>
      <p>string: {stringValue}</p>
      <p>boolean: {booleanValue.toString()}</p>
      <p>arrayValue: {arrayValue}</p>
      <p>object: {JSON.stringify(objectValue)}</p>
      <p>function: {handleClick.toString()}</p>
    </>
  );
}

 

타입 정의 하는 방법

// PrintValue.tsx

interface PrintValueProps {
  numberValue: number;
  stringValue: string;
  booleanValue: boolean;
  arrayValue: number[];
  objectValue: { name: string; age: number };
  handleClick: () => void;
};

export default function PrintValue(props: PrintValueProps) {
  return (
    <>
      <p>number: {props.numberValue}</p>
      <p>string: {props.stringValue}</p>
      <p>boolean: {props.booleanValue.toString()}</p>
      <p>arrayValue: {props.arrayValue}</p>
      <p>object: {JSON.stringify(props.objectValue)}</p>
      <p>function: {props.handleClick.toString()}</p>
    </>
  );
}

 

* interface를 통해 타입 정의를 할 때에는 컴포넌트 이름 뒤에 'Props'를 덧붙이는 것이 관례 

 

스프레드 연산자 활용하기

// App.tsx

import User from "./components/User";
import User2 from "./components/User2";

export default function App() {
  const userObj = {
    name: "jack",
    age: 20,
    gender: "male",
  };

  return (
    <>
      <User userObj={userObj} />
      <User2 {...userObj} /> // == <User2 name={"Jack"} age={20} gender={"male"} />
      
    </>
  );

}
// User2.tsx

export default function User2({
  name,
  age,
  gender,
}: {
  name: string;
  age: number;
  gender: string;
}) {
  return (
    <>
      <p>name: {name}</p>
      <p>age: {age}</p>
      <p>gender: {gender}</p>
    </>
  );
}

 

...userObj == 객체 내부의 요소들을 모두 넘기겠다는 의미

 

children

HTML 문법

  • 콘텐츠가 있는 문법
    • <p>Hello, World!</p>
  • 콘텐츠가 없는 문법
    • <br />

 

// App.tsx

import Button from "./components/Button";

export default function App() {
  return (
    <>
      <Button>Login</Button>
      <Button>Logout</Button>
    </>
  );

}

 

* 시작 태그와 종료 태그 사이의 콘텐츠를 'children'으로서 자식 태그에게 넘겨줄 수 있음 

 

// Button.tsx

export default function Button ({ children }: {children: React.ReactNode}) {
  return (
    <>
      <button>{children}</button>
    </>
  );
}

 

children의 타입 정의 방법

  • children: React.ReactElement
    • 콘텐츠가 JSX 요소만 허용
    • 단순 문자열, 숫자, null, undefined는 허용되지 않음
  • children: React.ReactNode
    • ReactElement 타입보다 범용적 
    • JSX 요소뿐만 아니라 문자열, 숫자, null, undefined 역시 허용됨 

 

Props vs Children

컴포넌트에 데이터를 전달하는 방법

  • 컴포넌트의 props로 전달하기
  • 컴포넌트의 children으로 전달하기

 

✔️ JSX 요소의 속성에 사용되는 경우

JSX 요소의 속성에 사용되는 값은 props로 전달 

ex) id, className

function Button({ id, className }: { id: string; className: string }) {
  return (
    <button id={id} className={className}>
      버튼
    </button>
  );
}

export default function App() {
  return (
    <>
      <Button id="btn" className="btn btn-primary" />
    </>
  );
}

 

✔️ JSX 요소의 콘텐츠에 사용되는 경우

JSX 요소의 콘텐츠에 사용되는 경우는 children으로 전달

function Button({ children }: { children: React.ReactNode }) {
  return <button>{children}</button>;
}

export default function App() {
  return (
    <>
      <Button>
        <span>✅</span> 성공
      </Button>
    </>
  );
}