→ 현재는 함수형 컴포넌트를 사용하지만, 나중에 컴포넌트를 사용하는 프로젝트를 유지보수하거나, 함수형 컴포넌트+Hooks로 못하는 작업의 경우 등 클래스형 컴포넌트를 써야하는 상황 존재
<기본 형식>
import React, {Component} from 'react';
class App extends Component{//class키워드 필요, Component로 상속 받아야함
state={//constructor없이 바로 state초기값 설정 가능, 객체 형식monsters:[],
userInput:"",
};
onClick={()=>{//this.setState 함수로 state 값 변경 가능this.setState({number:number+1});
}}
render(){//render()메소드 필요const name='react';
return <div className="react">{name}</div>
}
}
<함수형 vs 클래스형>
- 함수형 코드
import React from 'react';
function Hello({ color, name, isSpecial }) {
return (
<div style={{ color }}>
{isSpecial && <b>*</b>}
안녕하세요 {name}
</div>
);
}
Hello.defaultProps = {
name: '이름없음'
};
export default Hello;
- 클래스형 코드
import React, { Component } from "react";
class Hello extends Component {
static defaultProps = {
name: "이름없음",
};
render() {
const { color, name, isSpecial } = this.props;
return (
<div style={{ color }}>
{isSpecial && <b>*</b>}
안녕하세요 {name}
</div>
);
}
}
export default Hello;
[클래스형 컴포넌트 특징]
- render() 메서드 꼭 존재해야함 (해당 메서드에서 렌더링하고 싶은 JSX 반환)
- props 조회 할 때, this.props 로 조회
- defaultProps를 설정하는 것은 함수형과 똑같이 하거나, 클래스 내부에 static 키워드와 함께 선언 가능
- 클래스형 컴포넌트에서 커스텀 메서드를 만들 때, render함수 내부에서 선언 가능하지만 일반적으로 클래스 안에 커스텀 메서드를 선언
- 클래스 내부에 종속된 함수 → “메서드”
- 클래스에서 커스텀 메서드 만들 때 보통 이름을 handle…이라고 지음(꼭 지킬 필요는 없음)
커스텀 메서드 만들기
import React, { Component } from "react";
class Counter extends Component {
handleIncrease() {
console.log("increase");
}
handleDecrease() {
console.log("decrease");
}
render() {
return (
<div>
<h1>0</h1>
<button onClick={this.handleIncrease}>+1</button>
<button onClick={this.handleDecrease}>-1</button>
</div>
);
}
}
export default Counter;
❗️this는 컴포넌트 인스턴스를 가르켜야 하는데, 현재 구현한 메서드에서 this를 조회하려고 하면 컴포넌트 인스턴스를 가르키지 않게됨
→ 우리가 만든 메서드들을 이벤트로 등록하게 되는 과정에서 각 메서드와 컴포넌트의 인스턴스의 관계가 끊겨버리기 때문
→ event handler함수가 호출될 때의 this는 컴포넌트 내부에서 선언한 메소드 객체를 가리키는 것이 아니라 전역객체(window)를 의미
#TIL19, React | this와 bind()
개인 공부를 위해 작성했습니다State & Event에 대해 공부하던 중, this와 bind의 개념을 정립하고자 기록해본다.객체지향 언어에서의 일반적인 this는 현재 객체를 지칭하지만, js의 this는 실행할 때의
velog.io
⭐️ 엘리먼트, 인스턴스
엘리먼트(Element): 실제로 화면에 렌더링 할 DOM 노드들의 정보를 React에게 알려주기 위한 수단(DOM 엘리먼트, 컴포넌트 엘리먼트)
- DOM 엘리먼트: 엘리먼트의 type의 태그 이름에 해당하는 문자열인 경우(소문자로 시작)
- → React가 실제로 화면에 렌더링 하는 대상
- 컴포넌트 엘리먼트: 엘리먼트의 type이 컴포넌트 클래스/함수인 경우(대문자로 시작)
- → 사용자가 직접 정의한 컴포넌트 표현, 입력으로 props를 받으면 렌더링 할 앨리먼트 트리 반환
- 한 컴포넌트를 정의하는데 있어 또 다른 컴포넌트 사용 가능
컴포넌트 인스턴스: 클래스로 선언된 컴포넌트들만 인스턴스를 가짐
- 컴포넌트 클래스 내부에서 this 키워드를 통해 참조하는 대상에 해당
- 함수형 컴포넌트는 인스턴스 갖지 않음
[React] 엘리먼트, 컴포넌트, 인스턴스 개념
1. 엘리먼트 (Element) 실제로 화면에 렌더링 할 DOM 노드들의 정보를 React에게 알려주기 위한 수단이다. DOM 노드 혹은 컴포넌트를 표현하는 JavaScript의 일반 불변 객체(Plain Immutable Object)에 해당한다.
it-eldorado.tistory.com
[해결 방법]
- 클래스의 생성자 메서드 constructor에서 bind 작업하기
constructor(props) { super(props); this.handleIncrease = this.handleIncrease.bind(this); this.handleDecrease = this.handleDecrease.bind(this); }
- super(props)를 호출하는 것은 클래스가 컴포넌트로서 작동할 수 있도록 해주는 Component쪽에 구현되어 있는 생성자 함수 먼저 실행해주고, 작업 하겠다는 의미
- 화살표 함수 문법 사용 → 화살표 함수 사용해서 메서드 구현하는 것은 클래스에 특정 속성을 선언 할 수 있게 해주는 class-properties 문법 사용(정식 문법 아님)
handleIncrease = () => {
console.log("increase");
};
handleDecrease = () => {
console.log("decrease");
};
3. onClick에서 새로운 함수를 만들어서 전달하는 것(비추천) → 렌더링 할 때마다 함수가 새로 만들어지기 때문에
return (
<div>
<h1>0</h1>
<button onClick={() => this.handleIncrease()}>+1</button>
<button onClick={() => this.handleDecrease()}>-1</button>
</div>
);
}
상태 선언
- 클래스형 컴포넌트에서 상태를 관리 할 때에는 state 사용
- → state는 무조건 객체 형태
- state조회하려면 this.state를 조회
import React, { Component } from "react";
class Counter extends Component {
constructor(props) {
super(props);
this.state = {
counter: 0,
};
}
handleIncrease = () => {
console.log("increase");
console.log(this);
};
handleDecrease = () => {
console.log("decrease");
};
render() {
return (
<div>
<h1>{this.state.counter}</h1>
<button onClick={this.handleIncrease}>+1</button>
<button onClick={this.handleDecrease}>-1</button>
</div>
);
}
}
export default Counter;
상태 업데이트
- 상태 업데이트 할 때에는 this.setState 함수 사용
handleIncrease = () => {
this.setState({
counter: this.state.counter + 1,
});
};
handleDecrease = () => {
this.setState({
counter: this.state.counter - 1,
});
};
→ 클래스형 컴포넌트의 state에서 객체 형태의 상태를 관리해야 한다면, 불변성을 관리해주면서 업데이트 해야함
handleIncrease = () => {
this.setState({
counter: this.state.counter + 1,
});
this.setState({
counter: this.state.counter + 1,
});
};
- 위 코드와 같이 setState를 두 번 사용하면서 1을 더해주는 작업을 두 번하지만, 실제로는 2가 더해지지 않음
- → setState를 한다고 상태가 바로 바뀌는것이 아님(비동기적으로 업데이트됨). setState는 단순히 상태를 바꾸는 함수가 아니라, 상태로 바꿔달라고 요청해주는 함수
[해결 방법] 콜백함수 넣어줌
handleIncrease = () => {
this.setState(
{
counter: this.state.counter + 1,
},
() => {
console.log(this.state.counter);
}
);
};
'프론트엔드 > React' 카테고리의 다른 글
리액트 개발 시 사용하면 편리한 도구 (0) | 2022.12.02 |
---|---|
LifeCycle Method (0) | 2022.12.02 |
Immer (0) | 2022.11.24 |
Context API (0) | 2022.11.24 |
커스텀 Hooks 만들기 (0) | 2022.11.24 |