본문 바로가기

FrontEnd/React

[React] key와 children 속성 이해하기

 Key 속성 설정하기

  모든 리액트 컴포넌트는 key와 ref라는 속성을 포함하고 있다.  그리고 children이라는 속성을 선택적으로 포함한다.  리액트 프레임워크는 <p>와 같은 리액트 컴포넌트뿐만 아니라 사용자 컴포넌트에도 key 속성을 제공한다.  Key 속성은 같은 이름의 컴포넌트가 여러 개일 때 이들을 구분하려고 리액트 프레임워크가 만든 속성이다.

export default function App() {
  const texts = [<p>hello</p>, <p>world</p>]
  return <div>{texts}</div>
}

key 속성이 없을경우 개발자 도구에서는 경고 메시지를 확인할 수 있다.

 

  해당 경고 메시지는 각각의 요소 2개에 중복되지 않는 키 값을 설정해주면 해결할 수 있다. 

export default function App() {
  const texts = [<p key="1">hello</p>, <p key="2">world</p>]
  return <div>{texts}</div>
}

 

 

   또한 key 속성은 반드시 설정하지 않아도 되는 선택 속성이다.  그리고 key 타입은 문자열과 숫자 둘 다 설정이 가능하다.

/** key 속성 정의 */
interface Attributes {
    key? : Key | null | undefined;
}

/** key 타입의 선언문 */
type Key = string | number;

 

  리액트 프레임워크는 고유한 값의 key 속성값을 요구하기에 map의 index값을 통해 고유한 식별값을 설정할 수 있다.

 

export default function App() {
  const texts = ['hello', 'world'].map((text, index) => <p key={index}>{text}</p>)
  return <div>{texts}</div>
}

 

 Children 속성 설정하기

children?: ReactNode | undefined;

 

  모든 리액트 컴포넌트와 사용자 컴포넌트는 children 속성을 사용할 수 있다.  children 속성의 타입은 값을 설정하지 않아도 되는 선택 속성이다.  다만 <div>처럼 자식 요소를 포함할 수 있는 컴포넌트에만 사용할 수 있다.  <img>, <input> 처럼 자식요소를 포함할 수없는 컴포넌트에서는 children을 사용할 수 없다.

export default function App() {
  const texts = ['hello', 'world'].map((text, index) => 
    <p key={index} children={text}></p>)
  return <div>{texts}</div>
}

 

컴포넌트 내부에서 children 속성 사용하기

// P.tsx : P 컴포넌트
import type {FC, ReactNode} from 'react'
export type PProps = {
  children?: ReactNode  // children의 타입은 ReactNode이다
}
const P: FC<PProps> = props => {
  const {children} = props
  return <p children={children} />
}
export default P

// App.tsx
import P from './P'
export default function App() {
  const texts = ['hello', 'world'].map((text, index) => <P key={index} children={text} />)
  return <div children={texts} />
}

 

 JSX {...props} 구문

const P : FC<PProps> = props => {
    return <p {...props} />
}

 

   JSX는 위의 코드처럼 {...props}구문을 제공한다.  이 구문은 props에 담긴 다양한 속성을 마치 타입스크립트의 전개 연산자(spread operator)처럼 <p>에 하번에 전달하는 역할을 한다.

 

 PropsWithChildren 속성과 children 속성

import type {FC, PropsWithChildren, ReactNode} from 'react'

export type PProps = {}
const P: FC<PropsWithChildren> = props => {
  return <p {...props} />
}
export default P

 

  리액트 17버전까지는 children 속성을 FC타입에 포함했지만 18버전부터는 FC타입에서 children속성을 제거했다.  그리고 PropsWithChildren이라는 제네릭 타입을 새롭게 제공하여 Children?: ReactNode를 PropsWithChildren타입으로 대체 했다.