728x90
반응형
3장 컴포넌트
컴포넌트 기능은 단순한 템플릿 이상
- 데이터 O -> 이에 맞춰 UI 만듦
- 라이프사이클 API 이용 -> 컴포넌트가 화면에서 나타날 때, 사라질 때, 변화가 일어날 때 주어진 작업 처
- 임의 메서드 만들어 특별한 기능 붙이기
1. 컴포넌트
클래스형 컴포넌트
- state 기능 및 라이프사이클 기능 사용 O
- 임의 메서드 정의
- render 함수 필요 + JSX 반환
// App.js
import React, { Component } from 'react';
class App extends Component {
render()
const name="react";
return <div className="react">{name}</div>
}
}
export default App;
함수 컴포넌트
- (+) 선언하기 편함
- 메모리 자원 사용 ↓
- 플젝 완성하여 빌드 후 배포 -> 결과물 파일 크기 ↓
- (-) state와 라이프사이클 API 사용 X
- (해결) 리액트 v16.8 업데이트 -> Hooks 도입
// App.js
import './App.css';
function App() {
const name = '리액트';
return <div className="react">{name}</div>;
}
export default App;
=> 컴포넌트 새로 작성 시 함수 컴포넌트 + Hooks 사용 (권장)
ES6 화살표 함수
- function 키워드 대신 () => {}
- 함수를 파라미터로 전달할 때 유용
- 일반 함수) 자신이 종속된 객체를 this로 가리킴
- 화살표 함수) 자신이 종속된 인스턴를 가리킴
=> 값을 연산하여 바로 반환해야 할 때 사용 -> 가독성 ↑
// MyComponent.js
// 함수형 컴포넌트
const MyComponent = () => {
return <div>My new Component</div>;
};
export default MyComponent;
- 모듈 내보내기(export)
- ex. export default MyComponent;
- 모듈 불러오기(import)
- import MyComponent from './MyComponent';
2. props(= properties)
- 컴포넌트 속성 설정할 때 사용하는 요소
- 값: 해당 컴포넌트를 불러와 사용하는 부모 컴포넌트에서 설정
- 함수의 파라미터로 받아와서 사용 가능
JSX내부에서 props 렌더링
MyComponent 컴포넌트 수정 -> name이라는 props를 렌더링
-> JSX 내부에서 {} 기호로 감싸 주면 됨
import React from 'react';
const MyComponent = props => {
return <div>안녕하세요, 제 이름은 {props.name}입니다.</div>;
};
export default MyComponent;
컴포넌트를 사용할 때 props 값 지정
// App.js
import MyComponent from './MyComponent';
const App = () => {
return <MyComponent name="React" />;
};
export default App;
props 기본값 설정: defaultProps
defaultProps: props 값을 따로 지정 X 보여 줄 기본값
// MyComponent.js
const MyComponent = props => {
return <div>안녕하세요, 제 이름은 {props.name}입니다.</div>;
};
MyComponent.defaultProps = {
name: '기본 이름'
};
export default MyComponent;
태그 사이의 내용을 보여 주는 children
MyComponent 태그 사이에 작성한 '리액트' 문자열 MyComponent 내부에서 보여주기
-> props.children 값 보여줘야 함
// App.js
import MyComponent from './MyComponent';
const App = () => {
return <MyComponent>리액트</MyComponent>;
};
export default App;
// MyComponent.js
const MyComponent = props => {
return (
<div>
안녕하세요, 제 이름은 {props.name}입니다. <br />
children 값은 {props.children}
입니다.
</div>;
);
};
MyComponent.defaultProps = {
name: '기본 이름'
};
export default MyComponent;
비구조화 할당 문법(destructuring assignment) = 구조 분해 문법
- 객체에서 props 내부 값을 추출하는 문법
- IF. 함수의 파라미터: 객체 -> 값을 바로 비구조화해서 사용
// MyComponent.js
// const MyComponent = ({ name, children }) =>
const MyComponent = props => {
const { name, children } = props;
return (
<div>
안녕하세요, 제 이름은 {name}입니다. <br />
children 값은 {children}
입니다.
</div>
);
};
MyComponent.defaultProps = {
name: '기본 이름'
};
export default MyComponent;
propType ~> props 검증
- 컴포넌트의 필수 props 지정/ props 타입 지정 -> propTypes 사용
- propTypes 지정 X -> 경고 메시지 띄우기 => isRequired
// MyComponent.js
import PropTypes from 'prop-types';
const MyComponent = ({ name, favoriteNumber, children }) => {
return (
<div>
안녕하세요, 제 이름은 {name}입니다. <br />
children 값은 {children}
입니다.
<br />
제가 좋아하는 숫자는 {favoriteNumber}입니다.
</div>
);
};
MyComponent.defaultProps = {
name: '기본 이름';
};
// name 값: 무조건 문자열(string) 형태로 전달
MyComponent.propTypes = {
name: PropTypes.string,
favoriteNumber: PropTypes.number.isRequired
};
export default MyComponent;
PropTypes 종류
- array: 배열
- arrayOf(다른 PropType): 특정 PropType으로 이루어진 배열
ex. arrayOf(PropType.number): 숫자로 이루어진 배열 - bool: true OR false 값
- func: 함수
- number: 숫자
- object: 객체
- string: 문자열
- symbol: ES6의 Symbol
- node: 렌더링할 수 있는 모든 것
ㄴ숫자, 문자열, 혹은 JSX 코드/ children도 node PropType - instanceOf(클래스): 특정 클래스의 인스턴스
ex. 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 사용
클래스형 컴포넌트) props 사용 -> render 함수에서 this.prop 조회
// MyComponent.js
class MyComponent extends Component {
render() {
const { name, favoriteNumber, children } = this.props // 비구조화 할당
return (
<div>
안녕하세요, 제 이름은 {name}입니다. <br />
children 값은 {children}
입니다.
<br />
제가 좋아하는 숫자는 {favoriteNumber}입니다.
</div>
);
}
}
MyComponent.defaultProps = {
name: '기본 이름'
};
MyComponent.propTypes = {
name: PropTypes.string,
favoriteNumber: PropTypes.number.isRequired
};
// class 내부에서 지정
class MyComponent extends Component {
static defaultProps = {
name: '기본 이름'
};
static propTypes = {
name: PropTypes.string,
favoriteNumber: PropTypes.number.isRequired
};
render() {
const { name, favoriteNumber, children } = this.props; // 비구조화 할당
return (...);
}
}
3. state
컴포넌트 내부에서 바뀔 수 있는 값
- 클래스형 컴포넌트가 지닌 state
- 함수 컴포넌트에서 useState 함수 ~> 사용 state
컴포넌트) props -> 읽기 전용으로만 사용
컴포넌트가 사용되는 과정에서 부모 컴포넌트가 설정하는 값
=> props 변경 -> 부모 컴포넌트에서 변경 해야함
클래스형 컴포넌트의 state
컴포넌트에 state 설정 -> constructor 메서드 작성(: 컴포넌트의 생성자 메서드)
- super(props) 반드시 호출
-> 현재 클래스형 컴포넌트가 상속받고 있는 리액트의 Component 클래스가 지닌 생성자 함수 호출 - this.state 값에 초깃값 설정
- 객체 형식
// state 초깃값 지정
// ver1
constructor(props) {
super(props);
// state의 초깃값 설정하기
this.state = {
number: 0,
fixedNumber: 0
};
}
// ver2
state = {
number: 0,
fixedNumber: 0
};
render() {
const { number, fixedNumber } = this.state; // state를 조회할 때는 this.state로 조회
return (
<div>
<h1>{number}</h1>
<h2>바뀌지 않는 값: {fixedNumber}</h2>
</div>
);
}
추가
<button
// onClick ~> 버튼 클릭 -> 호출할 함수를 지정
onClick={() => {
// this.setState ~> state에 새로운 값 넣을 수 있음
// 버튼 클릭할 때 숫자 1씩 더함 -> this.setState가 state 값 바로 바꾸지 X
this.setState({ number: number + 1 });
this.setState({ number: this.state.number + 1 });
// 숫자 2씩 올라감 -> 객체 대신 함수로 인자 넣어줌
// ver1
this.setState(prevState => {
return {
number: prevState.number + 1
};
});
// ver2
// 값 바로 반환 -> 코드 블록 {} 생략
this.setState(prevState => ({
number: prevState.number + 1
}));
// this.setState 끝난 후 특정 작업 실행 -> 콜백(callback) 함수 등록
this.setState(
{
number: number + 1
},
() => {
console.log('방금 setState 호출');
console.log(this.state);
}
);
}}
>
+1
</button>
함수 컴포넌트에서 useState 사용
react v16.8 이후 함수 컴포넌트에서 useState ~> state 사용 O => Hooks 사용
배열 비구조화 할당
~= 객체 비구조화 할당
: 배열 안에 들어 있는 값을 쉽게 추출할 수 있도록 해 주는 문법
const array = [1, 2];
const one = array[0];
const two = array[1];
// 배열 비구조화 할당 사용
const array = [1, 2];
const [one, two] = array;
useState 함수(인자: 상태의 초깃값)
- 클래스형 컴포넌트) state 초깃값 -> 객체 형태
- useState) 반드시 객체 아니여도 O 값의 형태 자유 (숫자, 문자, 객체, 배열)
- 한 컴포넌트에서 여러 번 사용 O
함수 호출 -> 배열 반환 => 원소 1: 현재 상태/ 원소 2: Setter 함수
Setter 함수: 상태 바꾸어 주는 함수
배열 비구조화 할당 ~> 이름 자유롭게 지
// Say.js
import React, { useState } from 'react';
const Say = () => {
const [message, setMessage] = useState('');
const OnClickEnter = () => setMessage('안녕하세요');
const OnClickLeave = () => setMessage('안녕히가세요');
const [color, setColor] = useState('black');
return (
<div>
<button onClick={onClickEnter}>입장</button>
<button onClick={onClickLeave}>퇴장</button>
<h1 style={{ color }}>{message}</h1>
<button style={{ color: 'red' }}onClick={() => setColor('red')}]>빨간색</button>
<button style={{ color: 'green' }}onClick={() => setColor('green')}]>초록색</button>
<button style={{ color: 'blue' }}onClick={() => setColor('blue')}]>파란색</button>
</div>
};
};
export default Say;
4. state를 사용할 때 주의 사항
- state 값을 바꾸는 경우
- setState/ useState ~> 전달 받은 세터 함수 사용
- 배열/ 객체 업데이트 해야 할 경우
- 배열/ 객체 사본 만듦 -> 사본에 값 업데이트 -> 사본의 상태를 setState/ Setter 함수 ~> 업데이트
- 배열에 대한 사본) 배열의 내장 연산자
- 객체에 대한 사본) spread 연산자: ...
- 배열/ 객체 사본 만듦 -> 사본에 값 업데이트 -> 사본의 상태를 setState/ Setter 함수 ~> 업데이트
// 잘못된 코드
// 클래스형 컴포넌트에서
this.state.number = this.state.number + 1;
this.state.array = this.array.push(2);
this.state.object.value = 5;
// 함수형 컴포넌트에서
const [object, setObject] = useState({ a: 1, b: 1 });
object.b = 2;
// 사본 만들어서 업데이트하는 예시
// 객체 다루기
const object = { a: 1, b: 2, c: 3 };
const nextObject = { ...object, b: 2}; // 사본 만들어서 b 값만 덮어 쓰기
// 배열 다루기
const array = [{ id: 1, value: true }, { id: 2, value: true }, { id: 3, value: false }];
let nextArray = array.concat({ id: 4 }); // 새 항목 추가
nextArray.filter(item => item.id != = 2); // id가 2인 항목 제거
nextArray.map(item => (item.id === 1 ? { ...item, value: false } : item)); //id가 1인 항목의 value를 false로 설정
정리
- 컴포넌트를 만들어서 내보내고 불러오는 방법
- props 및 state를 사용하는 방법
props와 state
- props) 부모 컴포넌트가 설정
- 값이 무조건 고정적 X
- 부모 컴포넌트의 state -> 자식 컴포넌트의 props로 전달
자식 컴포넌트에서 특정 이벤트 발생할 때 부모 컴포넌트의 메서드 호출
=> 유동적 사용O
- state) 컴포넌트 자체적으로 지닌 값으로 컴포넌트 내부에서 값 업데이트 가능
- 클래스형 컴포넌트의 state
- 함수 컴포넌트의 useState -> 사용하면 코드 간결
공통점
- 컴포넌트에서 사용
- 렌더링할 데이터 담고 있음
출처
728x90
반응형
'Programming Language > React' 카테고리의 다른 글
[리액트를 다루는 기술] 6장 컴포넌트 반복 (0) | 2023.01.15 |
---|---|
[리액트를 다루는 기술] 5장 ref: DOM에 이름 달기 (0) | 2023.01.15 |
[리액트를 다루는 기술] 4장 이벤트 핸들링 (0) | 2023.01.15 |
[리액트를 다루는 기술] 1장 리액트 시작/ 2장 JSX (0) | 2023.01.15 |