컴포넌트 정의
NOTE!
컴포넌트: 스스로 상태를 관리하는 캡슐화된 코드 조각으로, 하나의 JSX를 반환하는 함수이다.
컴포넌트는 기본적으로 함수이기 때문에, 자신만의 고유한 로직이 들어갈 수 있다. 그리고 컴포넌트는 스스로 상태를 가질 수 있으며 상태가 변하면 자동으로 반영된다.`import`와 `export` 문법을 사용하여 컴포넌트를 모듈 방식으로 분리하고 관리한다.
import Hello from './components/Hello';
import World from './components/World';
export default function App() {
return (
<div>
<Hello />
<World />
</div>
);
}
컴포넌트의 이름은 반드시 PascalCase로 작성해야 한다. 즉, 컴포넌트의 이름의 시작은 반드시 대문자여야 한다. (Ex: MyComponent, ArticlePage)
컴포넌트는 의미 단위로 쪼개어 파일을 분리한다. 이때, 컴포넌트는 트리 구조를 가지며 최상위 컴포넌트 이름은 일반적으로 App이다.
- `index.js`: entry point, 최종 컴포넌트를 DOM에 렌더링한다. (`ReactDOM.render()`)
- `App.js`: 모든 컴포넌트들의 root 컴포넌트이다.
Props
React의 컴포넌트에는 `Props`라는 개념이 있다. Props를 통해 컴포넌트 간 데이터 전달을 효율적으로 할 수 있다.
NOTE!
Props: Properties의 줄임말로, 상위 컴포넌트에서 하위 컴포넌트로 내려주는 데이터를 의미한다.
Props는 읽기 전용(immutable)이기에 자식 컴포넌트에서 props 값을 직접 변경할 수 없다. 부모 컴포넌트에서 속성(Attribute) 형태로 값을 전달하면, 자식 컴포넌트에서 props 객체를 통해 접근할 수 있다
Props.children
컴포넌트로 감싼 값은 `props.children`으로 전달된다. 이때, `props.children`으로 JSX를 그대로 내려줄 수 있다. 또한 특정 props에 기본 값을 줄 수 있다. 이를 defaultProps라고 한다.
// Heading.jsx
function Heading(props) {
if (props.type === "h1") {
return <h1>{props.children}</h1>;
}
return <h2>{props.children}</h2>;
}
export default Heading;
// App.js
import Heading from "./components/Heading";
// Heading 이라는 컴포넌트를 만들고 Hello, World 컴포넌트를 통합하기
export default function App() {
return (
<div>
<Heading type="h1">Hello,</Heading>
<Heading type="h2">World</Heading>
</div>
);
}
State
NOTE!
State: 컴포넌트 내부에서 사용되는 일종의 변수이다.
컴포넌트 안에서 `useState()`라는 함수를 호출하면 `useState()` 함수는 Destructuring 문법을 사용하여 하나의 State와 그에 대한 setter 함수를 호출한다. State는 일반 변수와 차이점이 존재한다.
- State의 값이 변하면 컴포넌트가 리렌더링(Re-Rendering) 된다.
- 렌더링 사이클에서 값이 보존된다. (컴포넌트가 리렌더링 되어도 State는 값이 초기화되지 않고 유지된다.)
function App() {
const [value, setValue] = useState(0);
return (
<div>>{value}</div>
);
state 변경 함수는 렌더링이 모두 끝난 이후, state 변경 함수 내용을 실행한다.
클래스형 컴포넌트 VS 함수형 컴포넌트
현재 React에서 사용되는 컴포넌트는 함수형 컴포넌트이다. 함수형 컴포넌트가 나타난 것은 React v16.8이다. 그 전까지는 클래스형 컴포넌트를 사용했고 상태(State) 관리도 클래스형 컴포넌트를 통해 이루어졌다.
클래스형 컴포넌트
클래스형 컴포넌트는 말 그대로 클래스 문법으로 구현한 컴포넌트이다. 클래스의 멤버 변수로 State를 정의했고 `render()` 메소드를 통해 멤버 변수 안에서 반환하는 값(JSX)이 화면에 그려졌다.
import React, { Component } from 'react';
export default class App extends Component {
state = {
value: 0
};
constructor(props) {
super(props);
this.state = {
value: 1
};
}
resetValue() {
this.setState({ value: 0 });
}
render() {
return (
<div>
<h1>value: {this.state.value}</h1>
<button
onClick={() => {
this.setState((state) => ({
value: state.value + 1
}));
}}
>
Increase value
</button>
<button
onClick={this.resetValue.bind(this)}
>
Reset value
</button>
</div>
);
}
}
그러나 함수형 컴포넌트가 나타나고 Hooks가 생긴 이후로는 클래스형 컴포넌트는 래거시가 되었다. 현재는 클래스형 컴포넌트를 거의 사용하지 않으며 React의 공식문서도 Hooks 기반의 함수형 컴포넌트를 중심으로 설명하며 대부분의 프로젝트들도 함수형 컴포넌트를 사용하여 이루어진다.