컴포넌트를 선언하는 방식은 함수형 컴포넌트와 클래스형 컴포넌트로 나뉩니다.
import React, {Component} from 'react';
class App extends Component{
render() {
const name = "react";
return <div className="react">{name}</div>
}
}
export default App;
클래스형 컴포넌트의 특징은
① state 기능
② 라이프사이클 기능
③ 임의 메서드 정의
클래스형 컴포넌트에는 render함수가 반드시 있어야 하고, JSX를 반환해주어야 합니다.
import React from 'react';
import './App.css';
function App() {
const name = "리액트";
return <div className="react">{react}</div>
}
export default App;
함수형 컴포넌트의 장점은
① 클래스형 컴포넌트보다 선언하기 편하고
② 클래스형 컴포넌트보다 메모리 자원도 덜 사용하고
③ 프로젝트 완성 후 배포할 때도 결과물의 파일 크기가 더 작습니다.
함수형 컴포넌트의 단점은
state 기능과 라이프 사이클 API 사용 불가능
⇨ Hooks 기능의 도입으로 해결되었습니다.
리액트 공식 매뉴얼에서는 함수형 컴포넌트와 Hooks를 사용하도록 권장하고 있음
//MyComponent.js
import React form 'react';
const MyComponent = () => {
return <div>나의 새롭고 멋진 컴포넌트</div>
};
export default MyComponent;
⭐화살표 함수
: function 키워드 대신 () => {} 를 사용하여 함수를 표현하는 방식
- 함수를 파라미터로 전달할 때 유용. 간결성이 큰 장점
// 일반 함수로 표현
setTimeout(function() {
console.log("hellow world");
}, 1000);
// 화살표 함수를 사용하여 표현
setTimeout(() => {
console.log("hello world")
}), 1000);
// {}없으면 값을 바로 반환
const triple = (value) => value*3;
- 일반 함수는 자신이 종속된 객체를 this로 가리키며, 화살표 함수는 자신이 종속된 인스턴스를 가리킵니다.
3. 모듈 내보내기 및 불러오기
export default MyComponent;
다른 파일에서 이 파일을 import 할 때, 위에서 선언한 MyComponent 클래스를 불러오도록 설정합니다.
//App.js
import React from 'react';
import MyComponent from './MyComponent';
const App = () => {
return <MyComponent />;
};
export default App;
import문을 이용해 MyComponent 컴포넌트를 불러와서 사용할 수 있습니다.
props : 컴포넌트 속성 설정 시 사용하는 요소
- 부모 컴포넌트에서 설정 가능하고, 컴포넌트 자신은 읽기 전용으로만 사용 가능
- props 값은 컴포넌트 함수의 파라미터로 받아와 사용 가능
(JSX 내부에서 { } 기호로 감싸주면 된다)
//MyComponent.js
import React from 'react';
const MyComponent = props => {
return <div>안녕하세요, 제 이름은 {props.name}입니다.</div>;
};
export default MyComponent;
//App.js
import React from 'react';
import MyComponent from './MyComponent';
const App = () => {
return <MyComponent name="React" />;
};
export default App;
MyComponent 컴포넌트의 props 값을 지정하기 위해서는 부모 컴포넌트인 App 컴포넌트에서 지정해줘야 합니다.
클래스형 컴포넌트에서 props를 사용할 때는 render 함수에서 this.props를 조회하면 됩니다.
props 값을 따로 지정하지 않았을 때 보여줄 기본 값을 설정해줄 수 있습니다.
//MyComponent.js
import React from 'react';
const MyComponent = props => {
return <div>안녕하세요, 제 이름은 {props.name} 입니다. </div>;
};
MyComponent.defaultProps = {
name: '기본 이름'
};
export default MyComponent;
//App.js
import React from 'react';
import MyComponent from './MyComponent';
const App = () => {
return <MyComponent>리액트</MyComponent>;
};
export default App;
//MyComponent.js
import React from 'react';
const MyComponent = props => {
return (
<div>
안녕하세요, 제 이름은 {props.name}입니다.<br />
children 값은 {props.children}
입니다.
</div>
);
};
MyComponent.defaultProps = {
name: '기본 이름'
};
export default MyComponent;
비구조화 할당 문법 : 객체에서 값을 추출하는 문법 (= 구조 분해 문법)
- 함수의 파라미터 부분에서도 사용 가능
//MyComponent.js
const MyComponent = props => {
const { name, children } = props;
return (
<div>
안녕하세요, 제 이름은 {name}입니다. <br />
children 값은 {children}
입니다.
</div>
);
};
위와 같이 props 값을 조회할 때마다 props.name, props.children처럼 props라는 키워드를 앞에 붙이지 않고도 바로 사용할 수 있게 해 줍니다.
//MyComponent.js
const MyComponent = ({ name, children }) => {
return (
<div>
안녕하세요, 제 이름은 {name}입니다. <br />
children 값은 {children}
입니다.
</div>
);
};
다음과 같이 더 간결하게도 나타낼 수 있습니다.
컴포넌트의 필수 props를 지정하거나 props의 타입을 지정할 때는 propTypes를 사용합니다.
//MyComponent.js
import React from 'react';
import PropTypes from 'prop-types';
MyComponent.propTypes = {
name : PropTypes.string,
favoriteNumber: PropTypes.number.isRequired
};
name 값은 무조건 string 형태로 전달해야 하고, favoriteNumber 값은 number 형태로 전달해야 합니다.
isRequired를 사용하면 필수 propTypes를 설정할 수 있고, 만약 propTypes를 지정하지 않으면 Console창에 경고 메시지가 나타납니다.
▶ 더 많은 PropTypes 종류
array : 배열
arrayOf(다른 PropType) : 특정 PropType으로 이루어진 배열
bool : ture 혹은 false 값
func : 함수
number : 숫자
object : 객체
string : 문자열
symbol : ES6의 Symbol
node : 렌더링 할 수 있는 모든 것(숫자, 문자열, 혹은 JSX 코드
instanceOf(클래스) : 특정 클래스의 인스턴스
oneOf([‘dog’, ‘cat’]) : 주어진 배열 요소 중 값 하나
oneOfType([React.PropTypes.string, PropTypes.number]) : 주어진 배열 안의 종류 중 하나 objectOf(React.PropTypes.number) : 객체의 모든 키 값이 인자로 주어진 PropTypes인 객체
shape({ name : PropTypes.string, num:PropTypes.number}) : 주어진 스키마를 가진 객체
any : 아무 종류
더 자세한 정보 : https://github.com/facebook/prop-types
state : 컴포넌트 내부에서 바뀔 수 있는 값
props를 바꾸려면 부모 컴포넌트에서 바꿔주어야 하지만, state는 컴포넌트 내부에서 직접 바꿀 수 있음
리액트는 클래스형 컴포넌트의 state와 함수형 컴포넌트에서 useState 함수를 통해 사용하는 state입니다.
class Counter extends Component {
constructor(props) {
super(props);
this.state = {number:0, fixedNumber: 0};
}
render() {
const {number} = this.state;
return (
<div>
<h1>{number}</h1>
<button onClick={() => {
this.setState({number: number+1});
}}> +1
</button>
</div>
);
}
}
◇ constructor 메서드
: 컴포넌트의 생성자 메서드
- super(props) 호출 필수
컴포넌트의 생성자 메서드 없이도 초깃값 설정은 가능하다
state = { number: 0, fixedNumber: 0};
◇ this.setState
: state 값을 변경하는 함수
- state 객체 안에 여러 값이 있더라도, 인자로 전달된 객체 안의 값만 바꾸어준다.
- this.setState를 사용하여 업데이트를 하면 상태가 비동기적으로 업데이트됩니다.
≫해결) 객체 대신 함수를 인자로 넣어주는 것
this.setState((prevState, props) => { return { ... } })
prevState : 기존 상태
props : 현재 지니고 있는 props. 필요하지 않다면 생략 가능
- this.setState로 값 업데이트 후 특정 작업 실행 : setState의 두 번째 파라미터에 콜백 함수 등록
처음에 말했던 것처럼 함수형 컴포넌트에서는 state기능을 사용할 수 없었는데, 리액트 16.8부터는 Hooks 기능이 도입되어 useState함수를 사용하여 state를 사용할 수 있게 되었습니다.
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>
};
};
◇ useState
- 함수의 인자에 상태의 초깃값을 지정한다. (반드시 객체가 아니어도 상관 X)
- 함수 호출 시 배열을 반환
첫 번째 원소: 현재 상태
두 번째 원소: 상태를 바꾸어주는 함수(세터 함수)
- 3번째 줄을 보면 배열 비구조화 할당을 통해 이름을 정의해준 것을 볼 수 있다.
- 한 컴포넌트에서 useState 여러 번 사용 가능
배열 비구조화 할당
객체 비구조화 할당과 비슷하게 배열 안에 들어있는 값을 쉽게 추출할 수 있도록 해주는 문법
❗❗ state 값 변경 시 setState 혹은 세터 함수를 사용해야 합니다.
- 배열과 객체의 경우 : 사본에 값을 업데이트 후 setState 혹은 세터 함수를 이용
객체에 대한 사본 - spread연산자 (...) 사용
배열에 대한 사본 - 배열의 내장 함수 활용
Q1) 화살표 함수에서 this는 자신이 종속된 ( )를 가리킨다.
Q2) Props는 ( )에서 설정 가능하고, state는 ( )에서 설정할 수 있는 값이다.
Q3) 객체에서 내부 값을 바로 추출하는 문법으로 함수의 파라미터 부분에서도 사용 가능한 문법은?
답: ( )
Q4) 리액트 16.8 이후부터는 함수형 컴포넌트에서 ( )라는 함수를 사용하여 state기능을 사용할 수 있다.
Q5) State 값 변경 시 ( ) 혹은 ( )를 사용해야 함
<정답 확인>
A1) 인스턴스
A2) 부모 컴포넌트, 컴포넌트 내부
A3) 비구조화 할당 문법
A4) useState
A5) setState, 세터 함수
[리액트를 다루는 기술]5장 ref:DOM에 이름달기 (0) | 2021.11.01 |
---|---|
[리액트를 다루는 기술]6장 컴포넌트 반복 (0) | 2021.11.01 |
[리액트를다루는기술]4장 이벤트 (0) | 2021.10.11 |
[리액트를다루는기술]2장 JSX (0) | 2021.10.04 |
[리액트를다루는기술]1장 리액트 시작 (0) | 2021.10.04 |