컴포넌트에 대해 알아볼 것이다.
컴포넌트는 클래형 컴포넌트와 함수형 컴포넌트가 있다.
💙함수형 컴포넌트를 사용하는 것이 더욱 편리하고 깔끔해 보여서 리액트 개발자들도 사용을 추천한다.💙
하지만, 함수형만 알면 안될거 같아 클래스형 컴포넌트도 정리하겠다.
3.1 클래스형 커포넌트
컴포넌트 선언 방식 중 클래스형 컴포넌트이다.
import { Component } from 'react';
class MyComponent extends Component{
render() {
const name = react;
return (
<div className="react">{name}</div>
);
}
}
export default MyComponent;
클래스형 컴포넌트에서는 render함수가 꼭 있어야 하며, 유저에게 보여주고자 하는 JSX를 return을 통해 반환해야한다.
클래스형 컴포넌트는 state기능과 라이프 사이클 기능을 사용, 임의의 메서드 정의를 할 수 있다.
3.2 컴포넌트 생성
파일생성 ➡ 코드작성 ➡ 모듈 내보내기, 불러오기 과정으로 진행된다.
3.3.1 src 디렉터리에 컴포넌트이름.js 로 생성
컴포넌트 생성을 위해 컴포넌트 코드를 작성
3.3.2 코드 작성하기
import { Component } from 'react';
class MyComponent extends Component{
render() {
const name = react;
return (
<div className="react">{name}</div>
);
}
}
export default MyComponent;
3.2.3 모듈 내보내기, 불러오기
3.2.3.1 모듈 내보내기(export)
다른 파일에서 이 파일을 import할 때, 불러올 수 있도록 설정한 것(코드의 맨 마지막에 선언함으로 동작함)
export default MyComponent;
3.2.3.2 모듈 불러오기(import)
다른 파일을 불러올 때 사용(코드 맨 윗부분에 선언함)
import { Component } from 'react';
3.3 Props
props는 properties를 줄인 표현으로 컴포넌트 속성을 설정할 때 사용하는 요소이다.
3.3.1 JSX 내부에서 렌더링
props 값은 컴포넌트 함수의 파라미터로 받아와서 사용할 수 있다.
import PropTypes from 'prop-types'; // propTypes를 설정하기 위한 import
// const MyComponent = props => {
//
// //비구조화 할당 문법 사용 X
// // return <div>{props.name}</div>
// //비구조화 할당 문법 사용O
// const { name } = props;
// return <div>{name}</div>
// };
// //함수의 파라미터가 객체일 때(props를 파라미터로 전달)
const MyComponent = ({ name, favoriteNumber }) => {
return <div> {name}, {children} </div>
}
3.3.2 컴포넌트를 사용할 때 props 값 지정하기
상위 컴포넌트에서 값을 지정할 수 있다.(해당 코드에서는 App.js 라는 파일에서 진행한다)
import MyComponent from '../MyComponent';
const App = () => {
return <MyComponent name='리액트' favoriteNumber={7}>리액트</MyComponent>
};
export default App;
3.3.3 props 기본값 설정 defaultProps
props 값을 지정하지 않았을 경우 설정되는 초깃값(하위 컴포넌트에 작성)
MyComponent.defaultProps = {
name: "기본이름",
};
3.3.4 태그 사이의 내용을 보여주는 children
컴포넌트 태그 사이의 내용을 보여주는 props이다.
import MyComponent from '../MyComponent';
const App = () => {
return <MyComponent>리액트</MyComponent>
}; //이때 태그 사이의 값을 보여주는 props를 children이라 한다
export default App;
const MyComponent = ({ children }) => {
return <div> {children} </div>
}
3.3.5 비구조화 할당 문법을 통해 props 내부 값 추출하기
//이 방법을 추천
//함수의 파라미터가 객체일 때(props를 파라미터로 전달)
const MyComponent = ({ name, favoriteNumber }) => {
return <div> {name}, {children} </div>
}
//상대적으로 비추하는 방법
// const MyComponent = props => {
//
// //비구조화 할당 문법 사용 X
// // return <div>{props.name}</div>
// //비구조화 할당 문법 사용O
// const { name } = props;
// return <div>{name}</div>
// };
3.3.6 proptype를 통한 props 검증
컴포넌트의 필수 props 지정, props의 타입을 지정할 때는 PropTypes를 사용한다.
key의 값은 무조건 PropTypes로 설정한 타입으로 전달되야 한다.
//propTypes설정
MyComponent.propTypes = {
name: PropTypes.string, // name값은 무조건 string 타입으로 전달해야 한다
favoriteNumber: PropTypes.number.isRequired,
};
3.3.6.1 is.Required를 사용한 PropTypes 설정
PropTypes를 설정하지 않았을때 경고를 보낼 수 있다.
MyComponent.propTypes = {
name: PropTypes.string,
favoriteNumber: PropTypes.number.isRequired, //PropTypes.number.isRequired 로 경고 출력
};
3.3.6.2 더 많은 PropTypes 종류
propTypes설정 가능한 타입
3.3.7 클래스형 컴포넌트에 props사용
render 함수에 this.props를 조회
import { Component } from 'react';
import PropTypes from 'prop-type';
class MyComponent extends Component{
render() {
const { name, favoriteNumber, children } = this.props; // 비구조화 할당
return (
<div>
안녕하세요, 제 이름은 {name}입니다. 컴포넌트 사용시 props 값 지정<br />
children값은 {children}입니다.<br />
제가 좋아하는 숫자는 {favoriteNumber}입니다.
</div>
);
}
}
//변경될 부분 시작
MyComponent.defaultProps = {
name: "기본이름",
};
MyComponent.propTypes = {
name: PropTypes.string, // name값은 무조건 string 타입으로 전달해야 한다
favoriteNumber: PropTypes.number.isRequired,
};
//변경될 부분 끝
import { Component } from 'react';
import PropTypes from 'prop-type';
class MyComponent extends Component{
//변경된 부분 시작
static defaultProps = {
name: "기본이름",
};
static propTypes = {
name: PropTypes.string, // name값은 무조건 string 타입으로 전달해야 한다
favoriteNumber: PropTypes.number.isRequired,
};
//변경된 부분 끝
render() {
const { name, favoriteNumber, children } = this.props; // 비구조화 할당
return (
<div>
안녕하세요, 제 이름은 {name}입니다. 컴포넌트 사용시 props 값 지정<br />
children값은 {children}입니다.<br />
제가 좋아하는 숫자는 {favoriteNumber}입니다.
</div>
);
}
}
3.4 state
리액트에서 state는 컴포넌트 내부에서 바뀔수 있는 값을 의미한다.
props는 컴포넌트 사용 과정에서 부모컴포넌트가 설정하는 값
컴포넌트 자신은 해당 props를 릭기 전용으로만 사용 가능하다.
state의 종류
1️⃣ 클래스형 커포넌트를 갖는 state
2️⃣ 함수형 컴포넌트에서 useState사용 하는 state
3.4.1 클래스형 컴포넌트의 state
컴포넌트에 state 설정시 constructor 메서드 작성
constructor(props){
super(props);
//state의 초깃값 설정
this.state = {number: 0};
}
렌더 함수를 보자
render(){
const { number } = this.state;
return (
<div>
<h1>{number}</h1>
<button onClick= {
() => {this.setState({number: number + 1})
}}
>
+ 1 </button>
</div>
);
}
3.4.1.1 state 객체 안에 여러값이 있을 경우
constructor(props) {
super(props);
//state의 초깃값 설정
this.state = {
number: 0,
fixedNumber:0,
};
}
render() {
const { number, fixedNumber } = this.state; // state를 조회할 때는 this.state로 조회한다.
return (
<div>
<h1>{number}</h1>
<h2>바뀌지 않는 값 : { fixedNumber }</h2>
<button onClick={() => {
this.setState(
{
number: number + 1
},
//업데이트 이후 특정 잡업을 하고싶다면 setState의 두번째 파라미터로 콜백함수를 등록해 작업 처리가능
() => {
console.log('방금 setState가 호출되었습니다');
console.log(this.state);
}
);
}}> +1 </button>
</div>
)
}
}
3.4.1.2 state를 constructor 에서 꺼내기
constructor 메서드 없이 state 초깃값 설정 가능하다.
class Counter extends Component {
state = {
number: 0,
fixedNumber: 0,
};
(...)
3.4.1.3 this.setState 에 객체 대신 함수 인자 전달
this.setState를 사용하여 state 값을 업데이트 할때 상태가 비동기적으로 업데이트된다.
동기적으로 업데이트 하려면 this.setState 사용시 객체에서 함수를 인자로 사용하면 된다.
<button onClick={() => {
this.setState(prevState => {
//업데이트 과정에 props가 필요하면 함수의 인자로 props를 추가로 사용
return {
number: prevState.number + 1,
};
});
//위 코드와 아래 코드는 같은 기능을 함
//아래코드는 함수에서 객체를 반환한다는 의미
this.setState(prevState => ({
number: prevState.number + 1
}));
}}>
+1
</button>
3.4.1.4 this.setState가 끝나고 특정작업 실행
setState의 두번째 파라미터로 콜백 함수를 등록하여 작업을 처리할 수 있다.
<button onClick={() => {
this.setState(
{
number: number + 1
},
//업데이트 이후 특정 잡업을 하고싶다면 setState의 두번째 파라미터로 콜백함수를 등록해 작업 처리가능
() => {
console.log('방금 setState가 호출되었습니다');
console.log(this.state);
}
);
}}> +1 </button>
🔰🔰🔰이제 함수형을 시작할 것이다 주의하자🔰🔰🔰
3.4.2 함수 컴포넌트에서 useState 사용하기
리액트 16.8 이후 부터 useState 함수를 사용하여 컴포넌트에서 state를 사용할 수 있다.
이때 Hooks 사용이 가능해 졌다.
3.4.2.1 배열 비구조화 할당
배열 비구조화 할당은 이전에 배운 객체 비구조화 할당과 비슷하다.
즉, 배열안에 들어있는 값을 쉽게 추출할 수 있도록 해주는 문법이다.
// //배열 비구조화 할당(배열 안에 들어 있는 값을 쉽게 추출할 수 있도록 해주는 문법)
const arry = [1, 2];
const one = arry[0];
const two = arry[1];
// //배열 비구조화 할당을 사용하면 다음과 같다
const array = [1, 2];
const [onee, twoo] = array;
3.4.2.2 useState 사용하기
const Say = () => {
const [message, setMessage] = useState('');
//배열의 첫번째 원소는 현재상태이고, 두번째 원소는 상태를 바꾸는 세터(setter)함수이다.
//이름은 배열 비구조화 할당으로 자유롭게 설정가능하다.
const onClickEnter = () => setMessage('안녕하세요!');
const onClickLeave = () => setMessage('안녕히가세요!');
return (
<div>
<button onClick={onClickEnter}>입장</button>
<button onClick={onClickLeave}>퇴장</button>
<h1 style={{color}}>{message}</h1>
</div>
);
};
export default Say;
3.4.2.3 한 컴포넌트에서 useState 여러번 사용하기
useState는 한 컴포넌트에서 여러번 사용해도 무관하다.
const Say = () => {
const [message, setMessage] = useState('');
const onClickEnter = () => setMessage('안녕하세요!');
const onClickLeave = () => setMessage('안녕히가세요!');
//useState는 여러번 사용해도 문제 없다.
const [color, setColor] = useState('black');
(...)
3.5 state 사용시 주의점
state값을 바꾸어야 할 때는 setState 혹은 useState를 통해 전달받은 세터 함수를 사용해야 한다.
❗배열과 객체 업데이트 시 사본을 만들고 업데이트 후 ,
그 사본의 상태를 setState 혹은 세터 함수를 통해 업데이트 한다.
(객체는 펼침연산자, 배열은 내장함수를 이용해 사본 생성)
3.6 정리!
props와 state는 컴포넌트에서 사용하거나 렌더링한 데이터를 담고 있으므로 비슷해 보일 수 있지만,
props는 부모 컴포넌트가 설정하고, state는 컴포넌트 자체적으로 지닌 값으로 컴포넌트 내부에서 값을 변경 가능하다.
앞으로는 useState사용이 권장되며, 코드가 간결해질 뿐만 아니라
React개발팀이 함수 컴포넌트와 Hooks 사용을 권장한다.
'React' 카테고리의 다른 글
React) 4장 이벤트 핸들링 (0) | 2022.04.12 |
---|---|
React) 7장 컴포넌트의 라이프사이클 메서드 (0) | 2022.04.09 |
React) 2장 JSX문 (0) | 2022.03.25 |
React) 1장 리액트 시작 (0) | 2022.03.20 |
React) 1장 리액트 시작 (0) | 2022.03.20 |