함수형 컴포넌트
import React from 'react';
import './App.css';
function App() {
const name = '리액트';
return <div className="react">{name}</div>;
}
export default App;
클래스형 컴포넌트
import React, { Component } from 'react';
class App extends Component {
render() {
const name = 'react';
return <div className="react">{name}</div>;
}
}
export default App;
클래스형 컴포넌트와 함수형 컴포넌트의 차이점은 클래스형 컴포넌트의 경우 이후 배울 state 기능 및 라이프사이클 기능을 사용할 수 있다는 것과 임의 메서드를 정의할 수 있다는 것
함수형 컴포넌트의 장점
- 클래스 컴포넌트보다 선언하기가 쉽다.
- 메모리 자원도 덜 사용한다.
- 파일 크기가 더 작다.
그럼 단점은?
- state와 라이프사이클 API의 사용 불가( v16.8 이후부터 Hooks 기능이 도입으로 해결)
컴포넌트 만들기
- 파일 만들기
- 코드 작성
- 모듈 내보내기 및 불러오기
import React from 'react';
const MyComponent = () => {
return <div>나의 새롭고 멋진 컴포넌트</div>;
};
export default MyComponent;
해당 함수형 컴포넌트에서는 () ⇒ {} 인 화살표 함수 문법을 이용했다.
모듈 내보내기 및 불러오기
모듈 내보내기 export
export default MyComponent;
이 코드를 선언 하면 이 파일을 import하면 위에서 선언한 MyComponent 클래스를 불러온다.
모듈 불러오기 import
import MyComponent from './MyComponent';
이 코드를 선언 하면 MyComponent 컴포넌트를 불러온다.
props
properties를 줄인 표현으로 컴포넌트 속성을 설정할 때 사용하는 요소입니다. props 값은 해당 컴포넌트를 불러와 사용하는 부모 컴포넌트에서 설정 할 수 있다.
import React from 'react';
const MyComponent = props => {
return <div>hi {props.name} ~</div>;
}
import React from 'react';
const MyComponent = props => {
return <div>hi {props.name} ~</div>;
}
다음과 같이 props를 이용 할 때도 JSX 문법 {}을 이용하여 처리하며 해당 컴포넌트를 불러올 때 props를 사용 했던 정보를 속성으로 담아서 보내준다.
props 기본값 설정: defaultProps
MyComponent.defaultProps = {
name : '기본 이름'
}
export default MyComponent
기본 값으로 설정 하였을 시 속성으로 안 넣어도 default 값을 보여준다
태그 사이의 내용을 보여 주는 children
<MyComponent> react </MyComponent>
윗 처럼 태그 사이의 값을 넣을 시 {props.children} 을 이용하여 값을 보여준다.
props를 조금 더 편하게 쓰기
import React from 'react';
const MyComponent = props => {
const { name, children } = props;
return (
<div>
안녕하세요, {name}, {children}
</div>
);
};
이런 식으로 작성하면 props를 붙이지 않고 넣고싶은 구간에 편하게 작성 할 수 있다.
조금 더 간결하게 하면
import React from 'react';
const MyComponent = ({ name, children }) => {
return (
<div>
안녕하세요, {name}, {children}
</div>
);
};
파라미터로 받아와서 비구조화 할당 문법을 사용 할 수 있다
props 검증 : propTypes
props의 타입을 지정할 때는 propTypes를 사용하여 지정한다.
MyComponent.propTypes = {
name: PropTypes.string
};
isRequired를 사용하여 필수 propTypes 설정한다.
propTypes 지정하지 않았을 때 경고 띄워 주는 작업
MyComponent.propTypes = {
name: PropTypes.string,
favoriteNumber: PropTypes.number.isRequired
};
favoriteNumber가 설정을 하지 않을 시 경고가 나타남
더 많은 PropType 종류
- array : 배열
- arrayOf(다른 PropType): 특정 PropType으로 이루어진 배열을 의미합니다. ex) arrayOf(PropTypes.number)는 숫자로 이루어진 배열입니다
- bool: true 혹은 false 값
- func: 함수
- number: 숫자
- object: 객체
- string: 문자열
- symbol: ES6의 Symbol
- node: 렌더링할 수 있는 모든 것(숫자, 문자열, 혹은 JSX 코드. children도 node PropType입니다.)
- instanceOf(클래스): 특정 클래스의 인스턴스(예: instanceOf(MyClass))
- oneOf(['dog', 'cat']): 주어진 배열 요소 중 값 하나
- oneOfType([React.PropTypes.string, PropTypes.number]): 주어진 배열 안의 종류 중 하나
- objectOf(React.PropTypes.number): 객체의 모든 키 값이 인자로 주어진 PropType인 객체
- shape({ name: PropTypes.string, num: PropTypes.number }): 주어진 스키마를 가진 객체
- any: 아무 종류
클래스형 컴포넌트에서 props
import React, { Component } from 'react';
import PropTypes from 'prop-types';
class MyComponent extends Component {
render() {
const { name, favoriteNumber, children } = this.props; // 비구조화 할당
return (
<div>
안녕하세요, {name}, {children}, {favoriteNumber}
</div>
);
}
}
MyComponent.defaultProps = {
name: '기본 이름'
};
MyComponent.propTypes = {
name: PropTypes.string,
favoriteNumber: PropTypes.number.isRequired
};
export default MyComponent;
클래스형 컴포넌트에서 달라진 부분: this.props를 이용해서 데이터를 넣어주는 비구조화 할당
propType은 똑같이 사용할 수 있다.
하지만 class 내부에서 지정하는 다음과 같은 방법이 있다.
import React, { Component } from 'react';
import PropTypes 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 (...);
}
}
export default MyComponent;
static을 이용해서 propTypes, defaultProps를 정의한다.
State
컴포넌트 내부에서 바뀔 수 있는 값을 의미한다.
props는 컴포넌트가 사용되는 과정에서 부모 컴포넌트가 설정하는 값이라 컴포넌트에서 자신은 해당 props를 읽기 전용으로만 사용할 수 있다. props를 바꾸려면 부모 컴포넌트에서 바꿔준다.
2가지의 state가 있다
- 클래스형 컴포넌트가 지니는 state
- 함수형 컴포넌트에서 사용하는 useState
constructor(props) {
super(props);
// state의 초깃값 설정하기
this.state = {
number: 0
};
}
해당 코드는 컴포넌트의 생성자 메서드이며 반드시 super(props) 를 호출해 주어야 합니다.
함수를 호출하면 현재 클래스형 컴포넌트가 상속받고 있는 리액트의 Component 클래스가 지닌 생성자 함수를 호출해 줍니다.
그다음 this.state 값에 초기 값을 설정
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>
);
}
render 함수에서 현재 state를 조회할 때는 this.state를 조회하면 된다. button안에 onclick안에 props로 넣어 주었는데 버튼이 클릭할 때 호출시킬 함수를 설정할 수 있게 해 준다.
setState를 사용하면 state값을 업데이트 하는데 상태가 비동기적으로 업데이트 됩니다.
onClick={() => {
// this.setState를 사용하여 state에 새로운 값을 넣을 수 있습니다.
this.setState({ number: number + 1 });
this.setState({ number: this.state.number + 1 });
}
다음과 같은 코드가 있을 때 버튼을 클릭하면 2가 나와야 정상이지만 state는 값이 바로 바뀌지 않는다.
이를 해결 하기 위해 함수를 인자로 넣어 주는 방법을 이용
<button
// onClick을 통해 버튼이 클릭되었을 때 호출할 함수를 지정합니다.
onClick={() => {
this.setState(prevState => {
return {
number: prevState.number + 1
};
});
// 위 코드와 아래 코드는 완전히 똑같은 기능을 합니다.
// 아래 코드는 함수에서 바로 객체를 반환한다는 의미입니다.
this.setState(prevState => ({
number: prevState.number + 1
}));
}}
>ss </button>
setState가 끝난 후 특정 작업을 원할 때
onClick={() => {
this.setState(
{
number: number + 1
},
() => {
console.log('방금 setState가 호출되었습니다.');
console.log(this.state);
}
);
}}
콜백 함수를 등록하면 state동작이 끝난 후 특정 작업을 실행 할 수 있다.
함수형 컴포넌트에서 State
원래 함수형 컴포넌트에서는 state를 사용할 수 없었다. 하지만 16.8 이후로 hooks라는 것을 사용하게 되어서 useState를 이용하여 state를 사용할 수 있게 되었다.
비구조화 할당
배열이나 객체의 속성 혹은 값을 해체하여 그 값을 변수에 각각 담아 사용하는 자바스크립트 표현식이다.
즉 배열 안에 들어 있는 값을 쉽게 추출할 수 있도록 해 주는 문법이다.
// 비구조화 할당 사용 전
const array = [1, 2];
const one = array[0];
const two = array[1];
// 비구조화 할당 사용 후
const array = [1, 2];
const [one, two] = array;
useState 이용하기
import React, { useState } from 'react';
const Say = () => {
const [message, setMessage] = useState('');
const onClickEnter = () => setMessage('안녕하세요!');
const onClickLeave = () => setMessage('안녕히 가세요!');
return (
<div>
<button onClick={onClickEnter}>입장</button>
<button onClick={onClickLeave}>퇴장</button>
<h1>{message}</h1>
</div>
);
};
export default Say;
현제 useState를 반환된 message와 setMessage의 상태를 말하자면
message는 현재 상태 setMessage는 상태를 바꾸어 주는 함수이다.