React Component
함수와 컴포넌트
다른 언어를 포함해서 자바스크립트의 함수는 코드를 명확하고 재사용 가능하도록 만든다. 그리고 함수의 또 하나의 가치는 함수 안에서 다른 함수를 호출할 수 있다는 것이다. 이 점을 생각하고 전의 내용의 render메소드 살펴보자.
<div id="container"></div>
<script type="text/babel">
var destination = document.querySelector("#container");
ReactDOM.render(
<h1>Pocket Monster</h1>,
destination
);
</script>
container내용 안에 다른 내용도 보여주려고 할 때, 아래와 같이 추가할 것이다. (h1태그들을 div태그로 감싼 것은 리액트에서는 인접한 여러 엘리먼트를 출력할 수 없기 때문이다.)
<div id="container"></div>
<script type="text/babel">
var destination = document.querySelector("#container");
ReactDOM.render(
<div>
<h1>Pocket Monster</h1>
<h1>Larva</h1>
<h1>Digital Monster</h1>
</div>,
destination
);
</script>
그리고 여기서 h1태그가 아닌 h3태그로, 그리고 h3태그 안 내용을 이탤릭체로 변경하고 싶을 때마다, 일일이 변경해주어야 할 것이다. 위와 같이 일일이 해야하는 비효율적인 작업을 함수와 같이 보다 쉽게 해줄수 있는 것이 컴포넌트라고 생각하면 될 것이다.
리액트 컴포넌트 시작하기
리액트의 컴포넌트는 JSX를 통해서 HTML 엘리먼트를 출력하고 재사용 가능한 자바스크립트 덩어리이다. 좀 더 알기쉽게 아래의 간단한 render메소트를 컴포넌트로 작성해보자.
ReactDOM.render(
<div>
<p>Hello, React</p>
</div>,
document.querySelector("#container")
)
컴포넌트로 만드는 방법 중 하나인 React.Component를 사용한다.(책에서는 React.createClass를 사용했는데, 이 방법은 16버전부터 사라졌다.)
class Hello extends React.Component {
render() {
return (
<p>Hello, Component</p>
);
}
};
먼저 Hello라는 컴포넌트를 생성하고 이를 동작하게 할 속성중 하나인 render를 추가한다. 컴포넌트 안의 render메소드도 ReactDOM.render메소드와 똑같이 JSX처리하기 때문에 Hello, Component 텍스트를 리턴하게 만든다. 그리고 만들어진 컴포넌트를 render메소드에서 사용하면 된다.
ReactDOM.render(
<Hello/>,
document.querySelector("#container")
)
지금까지는 텍스트를 출력만 했다면, 속성(함수에서는 파라미터라고 지칭)을 전달해서 그에 맞게 동작하도록 해보자. 먼저 컴포넌트에서 속성을 정의(여기서는 target)하고, 호출하는 곳에서 속성을 추가하도록 하자.
class Hello extends React.Component {
render() {
return (
<p>Hello, {this.props.target}</p>
);
}
};
ReactDOM.render(
<div>
<Hello target="world!"/>
<Hello target="PocketMon"/>
<Hello target="Larva"/>
</div>,
document.querySelector("#container")
)
자식 속성 전달
끝으로 컴포넌트에서도 자식을 가질 수 있다.
아래와 같이 Hello의 컴포넌트는 p태그를 자식으로 가지고 있다.
그리고 컴포넌트 안 자식들은 this.props.children을 통해서 접근이 가능하다.
<Hello target="world!">
<p>Charmander</p>
</Hello>
예시)
class Button extends React.Component {
render() {
return (
<div>
<button>{this.props.children}</button>
</div>
);
}
};
ReactDOM.render(
<Button>
<p>push</p>
</Button>,
document.querySelector("#container")
)
this.pros.children 속성은 자식이 여러 개라면 배열로, 하나라면 단일 컴포넌트로 전달해준다.
속성 기본값 정의 및 타입 정의
속성의 기본값과 타입을 지정하는 방법은 두 가지가 있다.
하나는 외부에 속성 기본값을 지정하는 전통적인 방법입니다.
그리고 두번째 방법은 클래스 내부에 정의하는 방법입니다.
두 방법 모두 바벨을 통해서 ES5문법으로 변경되면 동일한 결과를 보입니다.
Class MyComponent extends Component {
static defaultProps = {
// 클래스 내부에 지정하는 방식입니다.
name: 'react',
}
static propTypes = {
name: propTypes.string
// 만약 필수적으로 존재해야하는 값이면 isReuired를 지정합니다.
// name: propTypes.string.isRequired
}
render() {
return(
<p>Hello, {this.props.name}</p>
)
}
}
/* 외부에서 지정하는 방식입니다.
MyComponent.defaultProps = {
name: 'react',
}
MyComponent.propTypes = {
name: propTypes.string
}
*/
prop type 종류
- array: 배열
- bool: 참, 거짓
- func: 함수
- number: 숫자
- object: 객체
- string: 문자열
- symbol: ES6심벌 개체
- node: 렌더링 할 수 있는 모든 것(숫자, 문자열, element 또는 이들로 구성된 배열)
- elemen: 리액트 요소
- instanceOf(MyClass): 특정 클래스의 인스턴스
- oneOf([‘Male’], [‘Female’]): 주어진 배열 요소 중 값 하나
- oneOfType([React.PropTypes.string, React.PropTypes.number]): 주어진 배열 안의 종류 중 하나
- arrayOf(React.PropTypes.number): 주어진 종류로 구성된 배열
- objectOf(React.PropTypes.number): 주어진 종류의 값을 가진 객체
- shape({name: React.PropTypes.string, age: React.PropTypes.number}): 주어진 스키마를 가지 ㄴ객체
- any: 아무 종류
지금까지 작성된 전체 예제
<!DOCTYPE html>
<html>
<head>
<title>React! React! React!</title>
<script src="https://unpkg.com/react@16.12.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.12.0/umd/react-dom.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script>
</head>
<body>
<div id="container"></div>
<script type="text/babel">
class Button extends React.Component {
render() {
return (
<div>
<button>{this.props.children}</button>
</div>
);
}
};
class Hello extends React.Component {
render() {
return (
<p>Hello, {this.props.target}</p>
);
}
};
ReactDOM.render(
<div>
<Hello target="world!"/>
<Hello target="PocketMon"/>
<Hello target="Larva"/>
<Button>
<p>push</p>
</Button>
</div>,
document.querySelector("#container")
)
</script>
</body>
</html>