컴포넌트 선언 방식
- 클래스형 컴포넌트
- 함수 컴포넌트
클래스형 컴포넌트
- ES6 이전 버전에는 클래스가 없었고 이를 구현하려면 prototype이라는 문법을 사용
- ES6 문법부터는 class를 사용하여 다음과 같이 작성
class Dog {
constructor(name) {
this.name = name;
}
say() {
console.log(this.name + ": 멍멍");
}
}
const dog = new Dog("흰둥이");
dog.say(); // 흰둥이: 멍멍
- 클래스형 컴포넌트에는 render 함수가 꼭 필요 -> 그 안에서 보여줄 JSX를 반환해야함
그렇다면 함수형, 클래스형 어떤걸 사용해야할까?
함수형 장점 | 함수형 단점 |
클래스형 컴포넌트보다 선언하기 편함 | state 사용 불가 |
클래스형 컴포넌트보다 메모리 자원을 덜 사용함 | 라이프사이클 API 사용 불가 |
=> 리액트 v16.8 업데이트 이후 Hooks 기능 도입 후 해결 |
→ 리액트 공식 매뉴얼에서는 함수 컴포넌트와 Hooks을 사용하도록 권장
화살표 함수 (arrow function)
- ES6 문법에서 함수를 표현하는 새로운 방식
- 주로 함수를 파라미터로 전달할 때 유용
- 값을 연산하여 바로 반환해야할 때 사용하면 가독성을 높일 수 있음
function twice(value) {
return value * 2;
}
const triple = (value) => value * 3;
// 따로 {}를 열어 주지 않으면 연산한 값을 그대로 반환
props
1. JSX 내부에서 props 렌더링
- props 값은 컴포넌트 함수의 파라미터로 받아와서 사용
- props를 렌더링 할 때는 JSX 내부에서 { } 기호로 감싼다
const MyComponent = props => {
return <div>안녕하세요, 제 이름은 {props.name} 입니다.</div>;
};
MyComponent.defaultProps = {
name: "기본 이름"
};
export default MyComponent;
- defaultProps : props를 따로 지정하지 않은 경우 보여주는 기본 값
2. 컴포넌트를 사용할 때 props 값 지정
import MyComponent from './MyComponent';
const App = () => {
return <MyComponent name = "이예은" />;
};
export default App;
// 안녕하세요, 제 이름은 이예은입니다.
3. 태그 사이의 내용을 보여 주는 childeren
- children : 컴포넌트 태그 사이의 내용을 보여 주는 props
import MyComponent from './MyComponent';
const App = () => {
return <MyComponent>리액트</MyComponent>;
};
export default App;
const MyComponent = props => {
return (
<div>
안녕하세요, 제 이름은 {props.name} 입니다. <br/>
children 값은 {props.children} 입니다.
</div>;
)
};
MyComponent.defaultProps = {
name: "기본 이름"
};
export default MyComponent;
/* output */
안녕하세요 제 이름은 기본 이름입니다.
children 값은 리액트 입니다.
4. 비구조화 할당 문법을 통해 props 내부 값 추출
- 비구조화 할당 : 객체에서 값을 추출하는 문법
- 파라미터 부분에 비구조화 할당 문법을 사용
const MyComponent = ({name, children}) => {
return (
<div>
안녕하세요, 제 이름은 {name}입니다. <br/>
children 값은 {children}입니다.
</div>
);
};
MyComponent.defaultProps = {
name : "기본 이름"
};
export default MyComponent;
5. propTypes를 통한 props 검증
- 컴포넌트의 필수 props를 지정할 때 사용
- props의 타입(type)을 지정할 때 사용
- propTypes을 사용할 때는 import구문을 사용하여 불러옴
import PropTypes from 'prop-types';
MyComponent.propTypes = {
name = PropTypes.string
};
- name 값은 무조건 문자열(string) 형태로 전달해야 된다는 것을 의미함
- 만약 컴포넌트에 설정한 props가 propTypes에서 지정한 형태와 일치하지 않는다면 개발자 도구에는
와 같은 경고 메시지를 출력하여 propTypes이 잘못되었다는 것을 알려줌
- isRequired : 필수로 지정한 props
MyComponent.propTypes = {
name : PropTypes.string,
favoriteNumber : PropTypes.number.isRequired
};
※ 클래스형 컴포넌트에서 props 사용
- render 함수에서 this.props를 조회한다
- defaultProps와 propTypes은 똑같은 방식으로 설정
- defaultProps와 propTypes를 설정할 때 외부 뿐만 아니라 내부에도 지정 가능
import {Component} from 'react';
import PropsTypes from 'prop-types';
class MyComponent extends Component {
static defaultProps = {
name: "기본 이름"
};
static PropTypes = {
name : PropTypes.string,
favoriteNumber : PropTypes.number.isRequired
};
render() {
const { name, favoriteNumber, children} = this.props; // 비구조화 할당
return (
<div>
안녕하세요, 제 이름은 {props.name} 입니다. <br/>
children 값은 {props.children} 입니다.<br/>
제가 좋아하는 숫자는 {favoriteNumber}입니다.
</div>;
);
}
};
MyComponent.defaultProps = {
name: "기본 이름"
};
export default MyComponent;
state
props : 컴포넌트가 사용되는 과정에서 부모 컴포넌트가 설정하는 값
state : 컴포넌트 내부에서 바뀔 수 있는 값
1. 클래스형 컴포넌트가 지니고 있는 state
2. 함수형 컴포넌트에서 useState 함수를 통해 사용하는 state
1. 클래스형 컴포넌트의 state
//Counter.js
import {Component} from 'react'
class Counter extends Component {
//컴포넌트에서 state를 설정할 때는 다음과 같이
//constructor 메서드를 작성하여 설정
//constructor : 클래스형 컴포넌트의 생성자 메서드
constructor(props) {
//반드시 super(props)를 호출해 주어야 한다.
super(props);
//state의 초깃값 설정하기
this.state = {
number : 0
};
}
render(){
// state를 조회할 때는 this.state로 조회한다.
const {number} = this.state;
return(
<div>
<h1>{number}</h1>
<button
// onClick을 통해 버튼이 클릭되었을 때 호출할 함수 지정
onClick={()=>{
// this.setState를 사용하여 state 값을 바꿀 수 있게함
this.setState({number : number + 1});
});
}}
>
</button>
</div>
);
}
}
export default Counter;
//App.js
import Counter from './Counter';
const App = () => {
return <Counter />;
}
export default App;
- state의 초깃값을 지정해주는 또 다른 방법
- 아래와 같이 construct 메서드를 선언하지 않고도 state 초깃값 설정
import {Component} from 'react'
class Counter extends Component {
state = {
number : 0,
fixedNumber : 0
};
render() {
const { number, fixedNumber } = this.state;
return (...);
}
}
this.setState로 값을 업데이트 한 후 특정 작업을 하고 싶을 때는 setState의 두번째 파라미터로 콜백 함수를 등록
<button
// onClick을 통해 버튼이 클릭되었을 때 호출할 함수 지정
onClick={()=>{
// this.setState를 사용하여 state 값을 바꿀 수 있게함
this.setState(
{
number : number + 1
},
() => {
console.log("호출됨");
}
);
}}
>
</button>
2. 함수 컴포넌트에서 useState 사용
배열 비구조화 할당
const array = [1, 2]
const [one, two] = array;
// one = array[0]
// two = array[1]
import {useState} from 'react'
const Info = () => {
// useState 함수 : 인자에 상태의 초깃값을 넣어줌
const [name, setName] = useState("");
// message : 현재 상태, setMessage : 상태를 바꾸어주는 함수(setter 함수)
const onClickFull = () => setMessage("이예은");
const onClickName = () => setMessage("예은");
return (
<div>
<button onClick={onClickFull}>성+이름</button>
<button onClick={onClickName}>이름</button>
<h1>{message}</h1>
</div>
);
};
export default Say;
state 사용 주의 사항
- 배열이나 객체를 업데이트 할 때 객체 사본을 만들고 그 사본 값을 업데이트시킴
- const nextObject = {...object, b : 2}
- 사본을 만들어 b값만 덮어씀
- 객체 사본을 만들 때는 spread 연산자 ...을 사용하여 처리
- const nextObject = {...object, b : 2}
→ 새로운 컴포넌트를 만들 때는 state함수 보다는 useState를 사용하는 것을 권장
'React' 카테고리의 다른 글
[React] 컴포넌트의 라이프사이클 메서드 (0) | 2023.03.23 |
---|---|
[React] 컴포넌트 반복 (0) | 2023.03.21 |
[React] ref : DOM에 이름 달기 (0) | 2023.03.16 |
[React] 이벤트 핸들링 (0) | 2023.03.16 |
[React] Virtual DOM (0) | 2023.01.16 |