하루에 하나씩
[02] 컴포넌트 이해하기 본문
디렉터리를 하나 생성하고, 이전에 사용했던 data와 prettier를 복사해온다.
컴포넌트
- 객체지향 언어의 원조인 스몰토크에서 유래
- 화면 UI를 처리하는 클래스를 의미
- MVC 설계지침에 따라 구현되어야 함
- 리액트 16.8버전 이후, 리액트 훅이라는 새로운 메커니즘을 통해 객체지향만의 클래스가 아닌 단순한 함수 형태로도 구현이 가능하게 되었음
-> 가능한 함수컴포넌트와, 리액트 훅을 사용하라고 권장 됨
리액트 컴포넌트와 사용자 컴포넌트
- 리액트 컴포넌트
- 리액트 프레임워크가 제공하는 리액트 제공 컴포넌트
- div, h1 ...
- 사용자 컴포넌트
- 사용자가 직접 지정하는 컴포넌트
- MyChild, MyComponent...
- 처음 글자는 무조건 대문자(카멜 케이스)
리액트 컴포넌트
- 컴포넌트를 React.createElement로 생성할 때, 컴포넌트 타입에는 h1과 같이 문자열을 입력해야 함
const h1 = <h1>Hello world!</h1> //h1는 리액트 컴포넌트
const h1 = React.createElement('h1', null, 'Hello World')
- 이렇게 하면, HTML5 태그에 해당하는 컴포넌트 이름을 일일이 임포트 하지 않아도 됨
사용자 컴포넌트
- 리액트 컴포넌트로 구현하면 JSX 코드 때문에 내용이 복잡해보임
import React from 'react';
import logo from './logo.svg';
import './App.css';
function App() {
return (
<ul>
<li>
<a href='http://www.google.com'>
<p>go to Google</p>
</a>
</li>
</ul>
);
}
export default App;
- 기존 작성했던 index.tsx의 내용을 App.tsx에 옮기고 하면
import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
const root = ReactDOM.createRoot(
document.getElementById("root") as HTMLElement
);
root.render(<App />);
- index.tsx는 이렇게 간편해짐
- 사용자 컴포넌트의 용도는, React.createElement나 JSX문으로 생성하는 가상 DOM 생성 코드를 사용자 컴포넌트로 옮겨 코드를 간결하게 하는데에 목적
클래스 컴포넌트 만들기
- 리액트에는 클래스 기반 컴포넌트와 함수형 컴포넌트가 존재
- 클래스기반 컴포넌트는 항상 react패키지의 Component클래스를 상속
- 또한, render 메서드를 포함해야하며, 이때 null, createElement로 얻은 반환값 혹은 JSX문으로 가상 DOM 객체를 반환 해야 함
App.tsx를 클래스 컴포넌트 방식으로 바꾸기
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
export default class App extends Component{
render(): React.ReactNode {
return (
<ul>
<li>
<a href='http://www.google.com'>
<p>go to Google</p>
</a>
</li>
</ul>
);
}
}
- 컴포넌트 개념 도입시 render 메서드에 JSX구문 뿐 아니라 다양한 로직을 TypeScript코드로 구현 가능
컴포넌트 render 부분을 ClassComponent로 옮기기
- 먼저 src 폴더에 ClassComponent를 생성
- 그 이후 해당 코드 작성
import { Component, ReactNode } from "react";
export default class ClassComponent extends Component {
render(): ReactNode {
return (
<li>
<a href="http://www.google.com">
<p>go to Google</p>
</a>
</li>
);
}
}
- 그 다음 App.tsx에 가서, 해당 컴포넌트를 사용만 하면 됨
속성이란?
- 객체지향 관점에서 클래스의 멤버 변수를 의미
- 컴포넌트 또한, 화면 UI를 담당하므로 속성을 가질 수 있음
- 클래스의 속성은 값이 수시로 바뀔 수 있는데, 이를 가변이라고 하고, 바뀌지 않는 것을 불변 이라 함
리액트 프레임워크에서의 속성
- 부모 컴포넌트가 자식 컴포넌트 쪽에 정보를 전달하는 용도로 사용
- 위의 코드에서 부모 컴포넌트App은 자식 컴포넌트 ClassComponent 쪽에 href와 text 속성 전달
- 매개변수 props에서 타입제약({})이 걸려있으면, 이는 리액트 속성이 객체여야 하고 선택 속성이란 의미를 가짐
- 리액트에서 객체지향관점의 속성은 상태(State)라고 함
- 속성이 값이 변할 시, 재 렌더링도 된다.(재 렌더링 + 객체지향관점의 속성)
JSX 속성 설정 구문
- XML언어 이므로 모든 속성은 작은 따옴표(' ')로 감싸야 함
<Person name='Jack' />
- 다른 타입의 언어(정수 형 같은...)는 중괄호({})로 감싸주어야 함
<Person name='Jack' age={22} />
- 속성 설정값이 객체인 경우, 중괄호 두개를 사용하여 내부는 객체, 외부는 JSX 설정 구문을 의미한다.
<Person person={{name='Jack', age=22}} />
ClassComponent에 속성 구현하기
- 리액트 관점에서는 href와 text가 유효한 속성이름인지 알 수 없음
- 그래서 Component 타입에 속성 이름과 타입을 기입하여 Props와 같이 속성 타입을 만들어서 함께 보내주어야 함
import { Component } from 'react'
type ClassComponentProps = {
href: string
text: string
}
export default class ClassComponent extends Component<ClassComponentProps>{
render() {return null}
}
- type으로 지정을 해주면, 나중에 컴포넌트 내부에서 this.props의 형태로 사용이 가능하다
- (참고) 모든 타입의 부모인 Component는 props라는 이름의 속성을 제공함
import { Component, ReactNode } from "react";
export type ClassComponentProps = {
href: string;
text: string;
}
export default class ClassComponent extends Component<ClassComponentProps> {
render(){
const {href, text} = this.props;
return (
<li>
<a href={href}>
<p>{text}</p>
</a>
</li>
);
}
}
- 해당 코드를 작성 후 href 및 text에 알맞은 단어를 쓰면 됨
함수 컴포넌트 만들기
- 함수형 컴포넌트란
- render 부분을 간단하게 함수로 만든 것
- react는 render메서드를 구현할 수 있게 해주는 프로그래밍 언어의 코드와, render메서드로 구성됨
- 함수 컴포넌트는 상용구 코드가 없어 컴포넌트를 간결하게 구현이 가능
- 함수형 컴포넌트를 만드는 방식에는 Arrow와 function 방식이 존재
function 키워드 방식
- 클래스 컴포넌트의 역할
- render 메서드를 통해 리액트 프레임워크가 가상 DOM 객체를 생성해 전달
- 함수 컴포넌트는 자신의 반환 값으로 가상 DOM 객체를 생성하여 전달
function App() { return ... }
방식으로 사용한다.
Arrow 키워드 방식
- 이름을 가질 수 없는 익명 함수
- 따라서.. (App 기준) App이라는 변수에 익명 함수를 설정하는 방식으로 구현
- 이 때, export default 구문을 가지지 못하므로 함수가 끝난 뒤 export default (함수 명)구문이 필요함
import type과 import의 차이
- import type
- 자바스크립트로 컴파일할 때만 필요한 정보일 때, 사용
- 컴파일 한 후 데이터가 완전히 사라짐
- import
- 클래스는 물리적으로 동작하는 메서드와 속성이 있기 때문에, import를 사용
- 컴파일을 해도 데이터가 사라지지 않음
함수형 컴포넌트의 타입
- FC
- FunctionComponent
- CP
- ClassComponent
화살표 함수 방식 구현
import type { FC } from "react";
export type ArrowComponentProps = {
href: string;
text: string;
};
const ArrowComponent: FC<ArrowComponentProps> = (props) => {
const { href, text } = props;
return (
<li>
<a href={href}>
<p>{text}</p>
</a>
</li>
);
};
export default ArrowComponent;
- 이후 App.tsx에서, ClassComponent를 했던 때와 같이 값을 입력하면 똑같이 실행이 된다.
'React' 카테고리의 다른 글
[02] 이벤트 속성 이해하기 (1) | 2024.04.24 |
---|---|
[02] key와 children 속성 이해하기 (0) | 2024.04.16 |
[02] JSX 구문 이해하기 (0) | 2024.04.12 |
[02] 리액트 동작 원리 (0) | 2024.04.10 |
[01] 리액트로 웹앱 만들기 with TypeScript (0) | 2024.04.09 |