3.1 클래스형 컴포넌트
컴포넌트를 선언하는 방식은 두 가지 있다.
1) 함수 컴포넌트
2) 클래스형 컴포넌트
1) 클래스형 컴포넌트
클래스형 컴포넌트와 함수 컴포넌트의 차이점은 클래스형 컴포넌트의 경우 state 기능 및 라이프사이클 기능을 사용할 수 있고, 임의의 메서드를 정의 할 수 있다.
ES6의 클래스 문법
ES6 이전에는 JS에 클래스가 없었다. 개념 자체는 있었지만, class 대신 prototype이라는 문법을 사용 했아.
function Dog(name) { this.name = name; } Dog.prototype.say = function() { console.log(this.name + ': 멍멍'); } var dog = new Dog('검둥이'); dog.say(); // 검둥이: 멍멍 // ES6 문법부터 class를 사용 할 수있게 됬다. class Dog { constructor(name) { this.name = name; } say() { console.log(this.name + ':멍멍'); } } const dog = new Dog('흰둥이'); dog.say(); // 흰둥이: 멍멍
클래스형 컴포넌트에서는 render 함수가 꼭 있어야 하고 JSX를 반환해야한다.
3.2 컴포넌트 생성
3.2.1 모듈 불러오기(import) 및 내보내기(export)
1) import
2) export
3.3 props
1) props 는 컴포넌트 속성을 설정할 때 사용하는 요소이다.
2) props 값은 해당 컴포넌트를 불러와 사용하는 부모 컴포넌트에서 사용가능.
3.3.1 JSX내부에서 props 렌더링
props 선언
3.3.2 props 기본값 설정: defaultProps
props를 default값으로 설정
3.3.3 태그 사이의 내용을 보여 주는 children
리액트 컴포넌트를 사용 할 때 컴포넌트 태그 사이의 내용을 보여준다.
3.3.4 비구조화 할당 문법을 통해 props 내부 값 추출
3.3.5 propTypes를 통한 props 검증
컴포넌트의 필수 props를 지정하거나 props의 타입을 지정할 때는 propTypes를 사용한다. 컴포넌트의 propTypes를 지정하는 방법은 defaultProp을 설정하는 것과 비슷하다.
컴포넌트에 설정한 props가 propTypes에서 지정한 형태와 일치하지 않는다면 개발자 도구의 console 탭에 경고가 나온다.
name 의 값을 string 으로 바꿔주면 오류가 사라진다.
3.3.5.1 isRequired를 사용하여 필수 propTypes 설정
propTypes를 지정하지 않았을 때 경고 메세지 띄우기
3.3.6 클래스형 컴포넌트에서 props 사용하기
클래스형 컴포넌트에서 props를 사용할 때는 render 함수에서 this.props를 조회하면 된다.
첫번째 방법.
두번째 방법.
3.4 state
리액트에서 state는 컴포넌트 내부에서 바뀔 수 있는 값을 의미한다.
props는 컴포넌트가 사용되는 과정에서 부모 컴포넌트가 설정하는 값이고 컴포넌트 자신은 해당 props를 읽기 전용으로만 사용할 수 있다.
리액트에는 2가지 state가 존재함.
1) 클래스형 컴포넌트가 가지고 있는 state
2) 함수 컴포넌트에서 useState라는 함수를 통해 사용하는 state
3.4.1 클래스형 컴포넌트의 state
컴포넌트에 state를 설정할 때는 constructor 메서드를 설정한다.
class Counter extends Component {
constructor(props) {
super(props);
//state의 초기값 설정
this.state = {
number: 0,
};
}
컴포넌트의 생성자 메서드이다. 클래스형 컴포넌트에서 constructor를 작성할 때는 반드시 super(props)를 호출해야 한다. 이 함수가 호출되면 현재 클래스형 컴포넌트가 상속받ㄷ고 있는 리액트의 Component 클래스가 지닌 생성자 함수를 호출한다.
render() {
const { number } = this.state; // state를 조회할 때는 this.state로 조회.
return (
<div>
<h1>{number}</h1>
<button
// onClick을 통해 버튼이 클릭되었을 때 호출할 함수를 지정한다.
onClick={() => {
// this.setState를 사용하여 state에 새로운 값을 넣을 수 있다.
this.setState({ number: number + 1 });
}}
>
+1
</button>
</div>
);
}
3.4.1.1 state 객체 안에 여러 값이 있을 때
3.4.1.2 state를 constructor에서 꺼내기
3.4.1.3 this.setState에 객체 대신 함수 인자 전달
this.setState를 사용하여 state값을 업데이트 할 때 상태가 비동기적으로 업데이트된다. 만약 onClick에 설정한 함수 내부에서 this.setState를 두 번 호출한다면??
onClick={() => {
this.setState({ number: number + 1 });
this.setState({ number: this.state.number + 1 });
}}
this.setState를 사용한다고 해서 state값이 바로 바뀌지 않는다.
해결책은 this.setState를 사용할 때 객체 대신에 함수를 인자로 넣어 준다.
this.setState의 인자로 함수를 넣어 줄 때는 다음과 같은 형식으로 작성.
this.setState((prevState, props) => {
return {
// 업데이트 하고 싶은 내용
}
})
여기서도 prevState는 기존 상태이고, props는 현재 지니고 있는 props를 가르킨다.
3.4.1.4 this.setState가 끝난 후 특정 작업 실행
setState를 사용하여 값을 업데이트 하고 두 번째 파라미터로 콜백(callback)함수를 등록하여 작업을 처리한다.
<button
onClick={() => {
this.setState(
{
number: number + 1,
},
() => {
console.log('방금 setState가 호출 되었습니다.');
console.log(this.state);
}
);
}}
>
+1
</button>
3.4.2 함수 컴포넌트에서 useState 사용
함수 컴포넌트에서는 state를 사용할 수 없다. 하지만 useState라는 함수를 사용하여 함수 컴포넌트에서도 state를 사용할 수 있다.
3.4.2.1 배열 비구조화 할당
배열 비구조화 할당은 객체 비구조화 할당과 비슷하다.
즉, 배열 안에 들어 있는 값을 쉽게 추출할 수 있도록 해주는 문법이다.
const array = [1,2];
const one = array[0];
const two = array[1];
// 배열 비구조화 할당 사용
const array = [1,2];
const [one, two] = array;
3.4.2.2 useState 사용
setState 함수의 인자에는 상태의 초기값을 넣어준다.
함수를 호출하면 배열이 반환된다.
배열의 첫 번째 원소는 현재 상태, 두 번째 원소는 상태를 바꿔주는 함수이다.
3.4.2.3 한 컴포넌트에서 useState 여러 번 사용하기
정리 !
1) props 와 state는 둘 다 컴포넌트에서 사용하거나 렌더링 할 데이터를 담고 있지만 역할은 다르다.
2) props는 부모 컴포넌트가 설정, state는 컴포넌트 자체적으로 지닌 값으로 컴포넌트 내부에서 값을 업데이트 한다.