안 쓰던 블로그
React-컴포넌트(컴포넌트 생성, props, state) 본문
리액트를 사용하여 애플리케이션 인터페이스를 설계할 때, 사용자가 볼 수 있는 요소를 여러 가지 컴포넌트로 분리한다
각 기능을 맡은 컴포넌트를 만들고 파일을 따로따로 저장하여 모든 뷰를 다른 파일로 분리하는 식이다
이렇게 컴포넌트를 쓴다면 단순한 템플릿 이상의 효율을 갖을 수 있다
예를 들어 데이터가 주어졌을 때 이에 맞추어 UI를 만들어주거나, LifeCycle API를 이용하여 컴포넌트가 화면에서 나타나고 사라질 때 주어진 작업을 처리할 수 있고, 메서드를 만들어 특별한 기능 붙이기도 가능하다
컴포넌트 생성
생성하기
vscode에서 scr디렉토리 마우스 오른쪽 클릭-새 파일-MyComponent.js 입력
그리고 코드 작성
import React, { Component } from 'react';
class MyComponent extends Component {
render() {
return (
<div>
나의 새롭고 짱멋진 컴포넌트
</div>
);
}
}
export default MyComponent;
모듈 내보내기
맨 아래쪽 코드를 보면
export default MyComponent;
이런 게 있음
이 코드는 다른 파일에서 이 파일을 import할 때, 위쪽에서 선언한 MyComponent 클래스를 불러오도록 설정한다
모듈 불러오기
App.js에서 MyComponent 모듈을 불러온다
import React, {Component, Fragment} from 'react';
import MyComponent from './MyComponent';
class App extends Component {
render(){
return(
<MyComponent/>
);
}
}
export default App;
렌더링 결과
props
properties의 줄임말로 컴포넌트 속성을 설정할 때 사용하는 요소
props값은 해당 컴포넌트를 불러와 사용하는 부모 컴포넌트에서만 설정할 수 있다(여기서는 App.js)
1. JSX 내부에서 props 렌더링
import React, { Component } from 'react';
class MyComponent extends Component {
render() {
return (
<div>
{this.props.name}의 새롭고 짱멋진 컴포넌트
</div>
);
}
}
export default MyComponent;
MyCompoenet.js 파일을 수정해서 name이라는 props를 렌더링하도록 설정했다
props를 렌더링 할 때는 JSX 내부에서 {}안에 감싸주면 된다
접근할 때는 this 키워드를 사용한다
2. 컴포넌트 사용할 때 props 값 설정
import React, {Component} from 'react';
import MyComponent from './MyComponent';
class App extends Component {
render(){
return(
<MyComponent name="proqk" />
);
}
}
export default App;
HTML태그에 속성을 설정하는 것과 비슷하다
결과
+. 디폴트 값 지정하기
값이 없을 때 그냥 출력하지 않고 디폴트 값을 넣는다
import React, { Component } from 'react';
class MyComponent extends Component {
render() {
return (
<div>
{this.props.name} 의 새롭고 짱멋진 컴포넌트
</div>
);
}
}
MyComponent.defaultProps={
name: '기본이름'
}
export default MyComponent;
MyComponent.js 수정
import React, {Component} from 'react';
import MyComponent from './MyComponent';
class App extends Component {
render(){
return(
//<MyComponent name="proqk" />
<MyComponent />
);
}
}
export default App;
App.js 수정
아니면 이렇게도 된다
차이점은 없다
import React, { Component } from 'react';
class MyComponent extends Component {
static defaultProps={
name: '기본이름'
}
render() {
return (
<div>
{this.props.name} 의 새롭고 짱멋진 컴포넌트
</div>
);
}
}
export default MyComponent;
props 검증: propTypes
컴포넌트 필수 props 지정이나 props의 타입을 지정할 때 propTypes를 사용한다
import PropTypes from 'prop-types';
MyComponent.js에서 불러온다
import React, { Component } from 'react';
import PropTypes from 'prop-types';
class MyComponent extends Component {
static defaultProps={
name: '기본이름'
}
static propTypes={
name: PropTypes.string
}
render() {
return (
<div>
{this.props.name} 의 새롭고 짱멋진 컴포넌트
</div>
);
}
}
export default MyComponent;
기본 타입을 string으로 설정한다
이것도 아까처럼 클래스 밖에다가 선언할 수 있다
App.js의 MyComponent 사용 부분을 다음과 같이 바꾼다
<MyComponent name="proqk" />
참고로 문자열 종류 외의 값을 컴포넌트에 전달할 때는 {}로 감싸야 한다
숫자면 {3} 이런 식
필수 propTypes 설정
import React, { Component } from 'react';
import PropTypes from 'prop-types';
class MyComponent extends Component {
static defaultProps={
name: '기본이름'
}
static propTypes={
name: PropTypes.string,
age: PropTypes.number.isRequired
}
render() {
return (
<div>
{this.props.name}의 새롭고 짱멋진 컴포넌트
저는 {this.props.age}살 입니다
</div>
);
}
}
export default MyComponent;
MyComponent.js를 이렇게 수정한다
age는 숫자 타입으로 필수로 지정한다는 의미다
import React, {Component} from 'react';
import MyComponent from './MyComponent';
class App extends Component {
render(){
return(
<MyComponent name="proqk" age={19}/>
);
}
}
export default App;
App.js를 수정
19살 여고생쟝 proqk입니다
여기서 이상한 에러가 난다면? 참고- https://foxtrotin.tistory.com/215
propTypes 종류
array 배열
bool 참거짓
func 함수
number 숫자
object 객체
string 문자열
symbol 심볼 객체
node 렌더링할 수 있는 모든 것(숫자, 문자열, element등)
element 리액트 요소
instanceOf 특정 클래스의 인스턴스
any 아무거나
등등
state
props는 부모 컴포넌트가 설정하고, 컴포넌트 자신은 해당 props를 읽기 전용으로만 사용할 수 있다
컴포넌트 내부에서 읽고 업데이트할 수 있는 값을 사용하려면 state를 써야 한다
기본 값을 미리 설정해야만 사용 가능하고, this.setState() 메서드로만 값을 얻을 수 있다
1. 컴포넌트 생성자 메서드 constructor()
import React, { Component } from 'react';
import PropTypes from 'prop-types';
class MyComponent extends Component {
static defaultProps={
name: '기본이름'
}
static propTypes={
name: PropTypes.string,
age: PropTypes.number.isRequired
}
constructor(props){
super(props);
}
render() {
return (
<div>
<p>{this.props.name}의 새롭고 짱멋진 컴포넌트</p>
<p>저는 {this.props.age}살 입니다</p>
</div>
);
}
}
export default MyComponent;
메서드 내부에서 부모 클래스인 Component의 constructor메서드를 먼저 호출해야하므로 super 키워드 사용
컴포넌트를 만들 때 props 값들을 사용해야 해서 props를 메서드 파라미터로 전달한다
2. 초깃값 설정
constructor(props){
super(props);
this.state={
number: 0
}
}
3. JSX내부에서 state 렌더링
render() {
return (
<div>
<p>{this.props.name}의 새롭고 짱멋진 컴포넌트</p>
<p>저는 {this.props.age}살 입니다</p>
<p>숫자: {this.state.number}</p>
</div>
);
}
MyComponent.js에서 여기까지 수정한다
그러면 값 0을 렌더링한다
4. state값 업데이트: setState()
render() {
return (
<div>
<p>{this.props.name}의 새롭고 짱멋진 컴포넌트</p>
<p>저는 {this.props.age}살 입니다</p>
<p>숫자: {this.state.number}</p>
<button onClick={()=>{
this.setState({
number: this.state.number+1
})
}
}>더하기</button>
</div>
);
}
버튼을 누를 때마다 숫자가 1씩 증가한다
여기서 사용한 이벤트 시스템은 다음 글에서 자세하게 다뤄보았다
*ES6의 화살표 함수-함수를 파라미터로 전달할 때 사용한다
5. state를 constructor에서 꺼내기
import React, { Component } from 'react';
import PropTypes from 'prop-types';
class MyComponent extends Component {
static defaultProps={
name: '기본이름'
}
static propTypes={
name: PropTypes.string,
age: PropTypes.number.isRequired
}
state={
number:0
}
render() {
return (
<div>
<p>{this.props.name}의 새롭고 짱멋진 컴포넌트</p>
<p>저는 {this.props.age}살 입니다</p>
<p>숫자: {this.state.number}</p>
<button onClick={()=>{
this.setState({
number: this.state.number+1
})
}
}>더하기</button>
</div>
);
}
}
export default MyComponent;
원래 초기 state는 constructor 메서드에서 정의해야 하지만,
defaultProps와 propTypes를 정의할 때 사용한 transform-class-properties 문법으로 constructor바깥에서 정의할 수 있다
위에 state={}가 그렇게 정의한 형태이다
값 업데이트 시 주의할 점
this.state.number = this.state.number + 1;
this.state.someObject.value = 3;
this.state.someArray.push(3);
state값을 업데이트 할 때는 무조건 .setState()를 사용해야 한다
위의 코드처럼 직접 접근하면 안 된다
왜냐하면 이렇게 직접 접근하면 컴포넌트를 자동으로 리렌더링하지 않기 때문이다
(물론 this.forceUpdate()로 강제 렌더링을 할 수 있지만 비효율적이다)
그래서 배열이나 객체를 업데이트할 때는 배열/객체 사본을 만들고 그 사본에 값을 업데이트해서 다시 사본을 넘기는 방식으로 한다
'Web > React' 카테고리의 다른 글
React-ref (DOM에 이름 달기) (0) | 2020.07.07 |
---|---|
React-이벤트 핸들링(onChange, onClick, input 여러 개, onKeyPress) (0) | 2020.07.06 |
Typo in static class property declaration react/no-typos 에러 해결 방법 (0) | 2020.07.06 |
React-App.js 코드 살펴보기, JSX (0) | 2020.07.06 |
React-리액트 기본 개념, 기본 프로젝트 생성 (0) | 2020.07.06 |