개념적으로 컴포넌트는 JavaScript 함수와 유사합니다. “props”라고 하는 임의의 입력을 받은 후, 화면에 어떻게 표시되는지를 기술하는 React 엘리먼트를 반환합니다.
React 문서
클래스형 컴포넌트
class Welcome extends React.Component {
render() { // Class형 컴포넌트에서는 render 함수가 꼭 있어야 하며, 그 안에서 보여 주어야 할 JSX를 반환해야 합니다.
return <h1>Hello, {this.props.name}</h1>; // JSX 반환
}
함수형 컴포넌트
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
React의 관점에서 봤을 때 위 예시의 컴포넌트는 동일합니다. 함수 컴포넌트는 클래스형 컴포넌트보다 선언하기가 편하고 메모리 자원도 덜 사용하며 빌드한 후 배포할 때도 파일 크기가 더 작다는 장점이 있으나 state와 라이프 사이클 API 사용이 불가능하다는 단점이 있습니다. (이 단점은 Hooks라는 기능이 도입되면서 해결되었습니다.)
리액트 공식 메뉴얼에서는 컴포넌트를 새로 작성할 때 함수 컴포넌트와 Hooks를 사용하는 걸 권장하고 있습니다.
Props는 properties를 줄인 표현으로 컴포넌트 속성을 설정할 때 사용하는 요소입니다. React가 사용자 정의 컴포넌트로 작성한 엘리먼트를 발견하면 JSX 어트리뷰트와 자식을 해당 컴포넌트에 단일 객체로 전달합니다. 이 객체를 “props”라고 합니다.
Mycomponent 컴포넌트에서 name 이라는 props를 렌더링 하도록 설정하는 예시입니다. props 값은 컴포넌트 함수의 파라미터로 받아 와서 사용할 수 있습니다. props를 렌더링할 때는 JSX 내부에서 { } 기호로 감싸주면 됩니다.
// MyComponent.js (자손컴포넌트)
const MyConponent = (props) => {
return <div>안녕하세요, 제 이름은 {props.name}입니다. </div>;
// return <요소>문자열{props.속성명} </요소>
};
export default MyConponent;
App 컴포넌트에서 Mycomponent의 props값을 지정합니다.
// App.js (부모컴포넌트)
import Mycomponent from "./MyComponent";
// import 자손컴포넌트명 from 자손컴포넌트경로
const App = () => {
return <Mycomponent name="hrimrim" />; // return <자손컴포넌트명 속성명 = "값" />
};
export default App;
App.js 파일에서 name="hrimrim"
값을 지우고 return <MyComponent />;
로 코드를 바꾸면 name 값을 지정하지 않았기 때문에 안녕하세요, 제 이름은 입니다
라는 내용이 보일 것입니다. defaultProps
를 사용해서 기본값을 설정해 줄 수 있습니다.
//MyComponent.js
const MyConponent = (props) => {
return <div>안녕하세요, 제 이름은 {props.name} 입니다. </div>;
};
MyConponent.defaultProps = {
name: " 기본 이름 "
};
export default MyConponent;
리액트 컴포넌트를 사용할 때 컴포넌트 태그 사이의 내용을 보여주는 props 입니다.
// App.js 수정
import Mycomponent from "./MyComponent";
const App = () => {
return <Mycomponent>짬뽕먹고싶다</Mycomponent>;
};
export default App;
const MyConponent = (props) => {
return (
<div>
안녕하세요, 제 이름은 {props.name} 입니다. children 값은 {props.children}
</div>
);
};
MyConponent.defaultProps = {
name: " 기본 이름 "
};
export default MyConponent;
비구조화 할당은 구조 분해 문법이라고도 하며, 자세한 내용은 https://ko.javascript.info/destructuring-assignment#ref-749 에서 확인해보세요!
const MyConponent = (props) => {
const { name, children } = props; // 비구조화 할당 문법을 사용해서 props 내부 값 추출
return (
<div>
안녕하세요, 제 이름은 {name} 입니다. children 값은 {children}
</div>
);
};
MyConponent.defaultProps = {
name: " 기본 이름 "
};
export default MyConponent;
함수의 파라미터 부분에서도 사용할 수 있습니다. 함수의 파라미터가 객체라면 그 값을 바로 비구조화해서 사용하는 방법입니다. 아주 편리한 방법입니다.
const MyConponent = ({ name, children }) => {
return (
<div>
안녕하세요, 제 이름은 {name} 입니다. children 값은 {children}
</div>
);
};
MyConponent.defaultProps = {
name: " 기본 이름 "
};
export default MyConponent;
컴포넌트의 필수 props를 지정하고나 props 의 타입(type)을 지정할 때 사용합니다.
// Myconponent.js
import PropsTypes from "prop-types"; //propsTypes를 사용하기 위해서 import 해야 합니다
const MyConponent = ({ name, children }) => {
return (
<div>
안녕하세요, 제 이름은 {name} 입니다. children 값은 {children}
</div>
);
};
MyConponent.defaultProps = {
name: " 기본 이름 "
};
MyConponent.prototype = {
name: PropsTypes.string // name 값은 반드시 string 형태여야 함을 의미합니다.
};
export default MyConponent;
// App.js
import Mycomponent from "./MyComponent";
const App = () => {
return <Mycomponent name={3}>짬뽕먹고싶다</Mycomponent>;
};
// name 값을 문자열이 아닌 숫자로 전달해 봅니다.
export default App;
값이 나타나기는 하지만 개발자 도구를 열어서 Console 탭을 확인해보면 Warning : Faild prop type 이라는 경고 메세지를 확인할 수 있습니다. 개발자에게 propTypes가 잘못되었음을 알려줍니다. 코드샌드박스를 사용하는 중인데 여기서는 경고 메세지가 나오지 않네요 ..
//Myconponent.js
import PropsTypes from "prop-types";
const MyConponent = ({ name, favoriteNumber, children }) => {
return (
<div>
안녕하세요, 제 이름은 {name} 입니다. children 값은 {children} <br />
좋아하는숫자는 {favoriteNumber}
</div>
);
};
MyConponent.defaultProps = {
name: " 기본 이름 "
};
MyConponent.prototype = {
name: PropsTypes.string,
favoriteNumber: PropsTypes.number.isRequired //isRequired 를 사용해서 필수 props로 지정
};
export default MyConponent;
위 코드는 favoriteNumber를 설정하지 않았기 때문에 console을 확인하면 역시 경고가 타나나게 됩니다.
클래스형 컴포넌트에서 props를 사용할 때는 render 함수에서 this.props를 조회하면 됩니다.
defaultProps와 propTypes는 똑같은 방식으로 사용할 수 있습니다.
import PropsTypes from "prop-types";
import { Component } from "react";
class MyConponent extends Component {
render() {
const { name, favoriteNumber, children } = this.props; // 비구조화 할당!
return (
<div>
안녕하세요, 제 이름은 {name} 입니다. <br />
children 값은 {children} 입니다. <br />
좋아하는 숫자는 {favoriteNumber} 입니다.
</div>
);
}
}
MyConponent.defaultProps = {
name: " 기본 이름 "
};
MyConponent.prototype = {
name: PropsTypes.string,
favoriteNumber: PropsTypes.number.isRequired
};
export default MyConponent;
리액트를 다루는 기술 (김민준 저자)
모던 자바스크립트 튜토리얼 https://ko.javascript.info/
리액트 문서 https://ko.reactjs.org/docs/components-and-props.html