[React] 02) 리액트(React) 설치 방법 및 구조
위 링크에서 리액트를 설치했다면, 아래와 같은 src 폴더를 볼 수 있다.
기본적으로 루트 컴포넌트는 <App /> 이며, 파일 경로는 src/App.js이다.
이 컴포넌트에 다른 컴포넌트를 불러와서 사용하게 된다.
불러오는 방법은 다음과 같다. 먼저 코드를 확인하자.
App.js
import React, { Component } from 'react';
import Basic from './components/Basic';
class App extends Component {
render() {
return (
<div className="App">
<Basic />
</div>
);
}
}
export default App;
두 줄만 추가하면 된다.
1. import Basic from './components/Basic';
2. <Basic />
import Basic from './components/Basic';
위 문장은 App.js에서 다른 컴포넌트를 불러와서 사용한다고 선언한 것이다.
Basic 컴포넌트를 보여줄 것이므로 이 컴포넌트가 어디에 위치한 컴포넌트인지 정의하는 것이다.
이 과정을 생략하면, 어디서 불러오는 컴포넌트인지 알지 못하기 떄문에 에러가 발생한다.
불러온 컴포넌트를 화면에 보여주는 코드가 바로
<Basic /> 이다.
마치 HTML 같아보이지만 JSX 문법이다.
저렇게 쓰면, Basic 컴포넌트가 화면에 렌더링된다.
참고로 Basic.js는 다음과 같다.
Basic.js
import React, { Component, PropTypes } from "react";
class Basic extends Component {
render() {
return (
<div>
<h1>나의 이름은 {this.props.name} 라고 한다!</h1>
</div>
);
}
}
export default Basic;
결과는 아래와 같다.
나의 이름은 라고 한다!
<h1> 태그를 사용했기 때문에, 굵은 제목의 텍스트가 정상적으로 출력된 것을 볼 수 있다. 근데 뭔가 이상하다.
{this.props.name} 부분이 나오지 않았다.
왜냐하면, {this.props.name}는 텍스트가 아니기 때문이다.
JSX에서 중괄호 { }는 이용해서 변수, 함수 등 문자열이 아닌 여러 표현식(자바스크립트)을 사용하기 위해 사용된다.
그렇다면 this.props.name은 어디서 나온 것이며, 왜 아무것도 나오지 않는 것인가?
props는 properties를 줄인 표현으로 부모 컴포넌트로부터 물려받는 속성이다.
클래스 컴포넌트에서 props에 접근하기 위해서는 this 키워드를 사용하면 된다.
이 props값은 해당 컴포넌트를 불러와서 사용하는 부모 컴포넌트에서만 설정할 수 있다.
이 props라는 개념을 통해 부모 컴포넌트와 소통할 수 있다. 여기서 부모 컴포넌트는 App.js이다.
(해당 컴포넌트를 사용하는 컴포넌트를 부모라 부른다.)
부모 컴포넌트에서 전달하는 props가 바뀌면 자동으로 업데이트된다.
이것이 리액트가 동적으로 컴포넌트 값을 변경할 수 있게 해주는 핵심 개념이다.
하지만, 자식 컴포넌트 자신은 해당 props를 읽기 전용으로만 사용할 수 있으므로 제한적이라고 할 수 있다.
따라서, App.js 에서 <Basic /> 부분을 다음과 같이 추가한다.
<Basic name="Gil-Dong Jang"/>
이렇게 HTML 태그 속성 작성하듯 해주면, Basic에서는 props 값이 전달되고 값을 읽어들여 다음과 같이 출력된다.
(참고)
문자열 이외 다른 종류의 값을 컴포넌트에 전달할때는 반드시 { } 중괄호로 감싸야한다. 그렇지 않으면 에러가 발생한다.
나의 이름은 Gil-Dong Jang라고 한다!
[defaultProps]
또는, 자식 컴포넌트에서 props의 기본값을 설정 해놓을 수 있다.
만약, 부모인 App.js에서 실수로 props 를 빠트리거나 특정 상황에서 props를 일부러 비워두어야 할 때 유용하게 사용할 수 있다.
이것을 사용하면, 부모에서 name 값을 보내주지 않아도 정상적으로 기본값이 나오므로 이상한 문장( = 나의 이름은 라고 한다!) 을 방지할 수 있다.
import React, { Component, PropTypes } from "react";
class Basic extends Component {
render() {
return (
<div>
<h1>나의 이름은 {this.props.name} 라고 한다!</h1>
</div>
);
}
}
Basic.defaultProps = {
name :"Jang"
}
export default Basic;
위는 동일하고, 아래와 같이 class 밖에 하단에 다음과 같이 defaultProps를 정의해주면 된다.
Basic.defaultProps = {
name :"Jang"
}
이러고,
으로 name 속성을 빼게 되면,
나의 이름은 Jang라고 한다!
과 같이 정상적으로 출력된다. 이외에도 클래스 내부에서 정의하는 방법이 있다.
class 밑에
static defaultProps = {
name : 'Jang',
}
이렇게 하더라도, 동일한 결과가 나온다.
static을 붙이지 않으면 보이지 않는다는 점 명심하자.
[propsTypes]
컴포넌트의 필수 props를 지정하거나,
원하는 props 타입을 지정하고자한다면 propsTypes를 사용한다.
사용법은 defaultProps와 동일하다.
먼저,
import PropTypes from 'prop-types';
을 선언한다.
그 다음 defaultProps와 동일한 위치에 사용한다.
Test.propTypes = {
name: PropTypes.string.isRequired
};
이렇게 작성하거나,
클래스 아래,
static propTypes = {
name: PropTypes.string
}
와 같이 작성하면 된다.
name은 props의 이름이며,
PropTypes.string의 경우 props의 타입을 의미한다.
PropTypes.string의 경우 props의 타입을 문자열로 설정하겠다는 의미이다.
만약 숫자를 입력하려고하면 에러가 발생한다.
자세히 말하면, 화면에 성공적으로 결과는 출력된다.
하지만, 콘솔창을 열어보면 에러가 발생한 것을 볼 수 있다.
index.js:1452 Warning: Failed prop type: Invalid prop `name` of type `number` supplied to `Test`, expected `string`.
in Test (at App.js:9)
in App (at src/index.js:7)
isRequired 의 경우, props를 지정하지 않았을 경우 발생하는 것이다.
즉, 필수적으로 props를 보내야하는 것을 isRequired 로 선언한다.