1. 클래스 / 함수형 컴포넌트
컴포넌트를 선언하는 방식은 두가지이다.
1. 함수 컴포넌트
2. 클래스형 컴포넌트
이렇게 두가지가 있다. 하지만 최근 클래스형 컴포넌트보단 함수 컴포넌트를 주로 사용한다.
다양한 이유가 있겠지만, 주요 이유는
1. 간단한 작성으로 가독성이 좋다.
2. 성능적인 부분에서 함수가 좀 더 효율적으로 사용할 수 있다.
3. 테스트 용이성
2. 컴포넌트 생성
생성 순서는 1. 파일 만들기 -> 2. 코드 작성하기 -> 3. 모듈 내보내기 및 불러오기
컴포넌트를 만들고자 할 때는 컴포넌트 코드를 선언해야 한다.
const My Component = () => {
return <div> 함수형 컴포넌트 </div>;
};
export default MyComponent;
3. 화살표 함수의 사용
function BlackDog() {
this.name = '흰둥이';
return {
name : '검둥이',
bark: function() {
console.log(this.name + ': 멍멍!')
}
}
}
const blackDog = new BlackDog();
blackDog.bark(); // 검둥이: 멍멍!
function WhiteDog(){
this.name = '흰둥이';
return {
name: '검둥이',
bark: () => {
console.log(this.name + ': 멍멍');
}
}
}
const whiteDog = new WhiteDog();
whiteDog.bark(); // 흰둥이: 멍멍!;
function()을 사용했을 때는 검둥이가 나타나고, () => 를 사용했을 때는 흰둥이가 나타납니다. 일반 함수는 자신이 종속된 객체를 this로 가리키며, 화살표 함수는 자식이 종속된 인스턴스를 가리킵니다.
화살표 함수는 값을 연산하여 바로 반환해야 할 때 사용하면 가독성을 높일 수 있다.
function twice(value) {
return value * 2;
}
이렇게 따로 {}를 열어 주지 않으면 연산한 값을 그대로 반환하다는 의미이다.
const triple = (value) => value * 3;
4. 모듈 내보내기 및 불러오기
모듈 내보내기
파일 맨 아래코드에 아래 코드를 입력하면 된다.
이 코드는 다른 파일에서 이 파일을 import할 때, 위에서 선언한 MyComponent 클래스를 불러오도록 설정한다.
export default MyComponent
모듈 불러오기
import MyComponent from './MyComponent'
const App = () => {
return <MyConponent;
};
export default App;
import 구문에서 사용하는 두 번째 줄은 우리가 만든 MyComponent 컴포넌트를 불러온다.
5. props
props는 properties를 줄인 표현으로 컴포넌트 속성을 설정할 때 사용하는 요소이다. props 값은 해당 컴포넌트를 불러와 사용하는 부모 컴포넌트(위에서는 App 컴포넌트가 부모 컴포넌트다)에서 설정 할 수 있다.
6. JSX 내부에서 props 렌더링
const MyComponent = props => {
return (
<div>
안녕하세요, 제이름은 {props.name}입니다. <br />
</div>
);
export default MyComponent;
7. 컴포넌트를 사용할 때 props 값 지정하기
import MyConponent from './MyComponent';
const App = () => {
return <MyConponent name="React" />'
};
export default App
8. props 기본값 설정: defaultProps
props 값을 따로 저장하지 않을 때 보여 줄 기본 값을 설정한다.
const MyComponent = props => {
return (
<div>
안녕하세요, 제이름은 {props.name}입니다. <br />
</div>
);
MyComponent.defaultProps = {
name: '기본 이름'
};
export default MyComponent;
9. 태그 사이의 내용을 보여주는 children
children : 리액트 컴포넌트를 사용 할 때 컴포넌트 태그 사이의 내용을 보여주는 props다
const MyComponent = props => {
return (
<div>
안녕하세요, 제이름은 {props.name}입니다. <br />
children 값은 {props.children} 입니다.
</div>
);
MyComponent.defaultProps = {
name: '기본이름'
};
export default MyComponent
10. 비구조화 할당 문법을 통해 props 내부 값 추출하기
혀재 컴포넌트에서 props 값을 조회할 때마다 props.name, props.children 과 같이 props이라는 키워드를 앞에 붙여 주고 있다.
이러한 작업을 편하게 하기 위해 비구조화 할당 문법을 사용하여 바로 추출 할 수 있다.
const MyComponent = props => {
return (
<div>
안녕하세요, 제이름은 {props.name}입니다. <br />
children 값은 {props.children} 입니다.
</div>
);
};
MyComponent.defaultProps = {
name: '기본이름'
}
export default MyComponent;
객체에서 값을 추출하는 문법을 비구조화 할당이라고 부른다. 이 문법은 구조 분해 문법이라고도 불리며, 함수의 파라미터 부분애서도 사용할 수 있다. 만약 함수의 파라미터가 객체라면 그 값을 바로 비구조화해서 사용하는 것이다.
이렇게 코드를 짜게 되면 props를 좀더 쉽게 사용할 수 있다. 함수 컴포넌트에서 props를 사용 할 때 이렇게 파라미터 부분에서 비구조화 할당 문법을 사용한다.
const MyComponent = ({ name, children }) => {
return (
<div>
안녕하세요, 제이름은 {props.name}입니다. <br />
children 값은 {props.children} 입니다.
</div>
);
};
MyComponent.defaultProps = {
name: '기본이름'
}
export default MyComponent;
11. propTypes를 통한 props 검증
컴포넌트의 필수 props를 지정하거나 props의 타입을 지정할 때는 propTypes를 사용한다.
impoty propTypes from 'pro-types';
const MyComponent = ({ name, children }) => {
(...)
아래와 같이 설정 해주면 name 값은 무조건 문자열(string)형태로 전달해야 된다는 것을 의미한다.
import PropTypes from 'prop-types';
const MyComponent =({ name, children }) => {
return (
<div>
안녕하세요, 제이름은 {name}입니다. <br />
children 값은 {children} 입니다.
</div>
);
};
MyComponent.defaultProps = {
name: '기본이름'
};
MyComponent.prototype = {
name: PropTypes.string,
};
export default MyComponent;
12. isRequired 를 사용하여 필수 propTypes 설정
propTypes를 지정하지 않았을 때 경고 ㅁ메세지를 띄어주는 것이 isRequired이다.
const MyComponent = ({name ,favoriteNumber, children}) => {
return (
<div>
안녕하세요, 제이름은 {name}입니다. <br />
children 값은 {children} 입니다.
<br />
제가 좋아하는 숫자는 {favoriteNumber}입니다.
</div>
);
}
MyComponent.defaultProps = {
name: '기본이름'
};
MyComponent.prototype = {
name: PropTypes.string,
favoriteNumber: PropTypes.number.isRequired
};
13. state
리액트에서 state는 컴포넌트 내부에서 바뀔 수 있는 값을 의미한다. props는 컴포넌트가 사용되는 과정에서 부모 컨포넌트가 설정하는 값이며, 컴포넌트 자신은 해당 props를 읽기 전용으로만 사용할 수 있다. props를 바꾸려면 부모 컴포넌트에서 바꿔 주어야 한다. 현재 상황에서 App 컴포넌트에서 MyComponent를 사용할 때 props를 바꿔 줘야 값이 변경 될 수 있다. 반면 MyComponent에서는 전달 받은 name값을 직접 바꿀 수 없다.
리액트에서는 두 가지 종류의 state가 있다. 하나는 클래스형 컴포넌트가 지니고 있는 state이고, 다른 하나는 함수 컴포너트에서 useState라는 함수를 통해 사용하는 state이다.
14. 배열 비구조화 할당
배열 비구조화 할당은 객체 비구조화 할당과 비슷하다. 즉 배열안에 들어가 있는 값을 쉽게 추출할 수 있도록 해주는 문법이다.
const array = [1, 2];
const one = array[0];
const two = array[1];
위 코드는 array 안에 있는 값을 one과 two에 담아주는 코드이다. 위 코드를 배열 비구조화 할당으로 사용하면 아래와 같다.
const array = [1, 2];
const [one, two] = array;
15. useState 사용하기
import { 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>{massage}</h1>
</div>
);
};
export default Say;
useState 함수의 인자에는 상태의 초깃값을 넣어준다. useState에서는 반드시 객체가 아니어도 상관없다. 값의 형태는 장이다.
문자, 숫자, 객체, 배열 일수도 있다.
함수를 호출하면 배열이 반환되는데, 배열의 첫 번째 원소는 현재 상태이고, 두 번째 원소는 상태를 바꾸어 주는 함수이다.
이 함수는 세터(setter) 함수라고 불린다. 그리고 배열 비구조화 할당을 통해 이름을 자유롭게 정해 줄 수 있다. 현재 massage 와 setMessage라고 이름을 설정 해주었는데, text와 setText라고 이름을 바꾸어도 상관 없다.
16. 한 컴포넌트에서 useState 여러번 사용하기
useState는 한 컴포넌트에서 여러 번 사용해도 상관 없다. 또 다른 상태의 useState를 사용했다.
import { 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 }}>{massage}</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;
17. state를 사용할 때 주의 사항
state를 사용할 때 주의해야 할 사항이 있다. state의 값을 바꾸어야 할 때는 setState 혹은 useState를 통해 전달 받은 세터 함수를 사용해야 한다. 그리고 배열 혹은 객체를 변경, 업데이트를 하고자 할 때는 배열이나 객체 사본을 만들고 그 사본에 값을 업데이트 한 후, 그 사본의 상태를 setState 혹은 useState 세터 함수를 통해 업데이트 한다.
// 객체 다루기
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: fasle} : item)); // id가 1인 항목의 value를 false로 설정
객체에 대한 사본을 만들 때는 spread 연산자라고 불리는 ..을 사용하여 처리하고, 배열에 대한 사본을 만들 때는 배열의 내장 함수들을 활용한다.
18. 정리
3장에서는 컴포넌트를 만들어서 내보내고 보내는 방법과 props 및 state를 사용하는 방법을 배워보았다. props와 state는 둘 다 컴포넌트에서 사용하거나 렌더링할 데이터를 담고 있으므로 비슷해보인다. 하지만 그 역할은 매우 다르다. props는 부모 컴포넌트가 설정하고, state는 컴포넌트 자체적으로 지닌 값으로 컴포넌트 내부에서 값을 업데이트 할 수 있다.
props를 사용한다고 해서 값이 무조건 고정적이지는 않다. 부모 컴포넌트의 state를 자식 컴포넌트의 props로 전달하고, 자식 컴포넌트에서 특정 이벤트가 발생할 때 부모 컴포넌트의 매서드를 호출하면 props도 유동적으로 사용할 수 있다.
함수 컴포넌트 useState 와 클래스 형 컴포넌트 state를 배웠는데, 최근에는 주로 함수 컴포넌트를 많이 사용한다. 이 점을 참고하자.
이미지 출처 : 리액트를 다루는 기술 3장 컴포넌트(p,117)
'React > 다시 공부하는 리액트' 카테고리의 다른 글
7장. 컴포넌트의 라이프사이클 메서드 (0) | 2023.06.22 |
---|---|
6장. 컴포넌트 반복 (0) | 2023.06.21 |
4장. 이벤트 핸들링 (0) | 2023.06.20 |
20230617 2장. JSX (0) | 2023.06.17 |
20230615 1장. 리액트의 시작 (0) | 2023.06.16 |