
컴포넌트에 직접 주입하는 값을 props라고 한다.
children도 props의 일부이다.props로 className이나 여러 handler를 줄 수도 있다.컴포넌트 합성
function App() {
return (
<div>
<Welcome name="Sara" />
<Welcome name="Cahal" />
<Welcome name="Edite" />
</div>
);
}
컴포넌트 추출

공식 문서에 나와있는 클래스 컴포넌트로 구현된 시계 예제를 함수형 컴포넌트로 똑같이 구현할 수 있다.
| 클래스 컴포넌트 | 함수형 컴포넌트 |
|---|---|
DidMount() | useEffect(...,[]) |
WillUnmount() | useEffect에서 return으로 cleanup |
this.state로 초기화, tick()에서 업데이트 | usetState에서 set할 때 초기화, tick()에서 업데이트 |
🤔 함수형 vs 클래스
현재는 함수형 컴포넌트에 훅이 추가되면서 클래스 컴포넌트보다 함수형 컴포넌트가 주로 사용된다.
this.setState~, ❌: this.state~import React, { Component } from 'react'
export default class ClassComponent extends Component {
constructor(props) {
super(props);
this.state = {date: new Date()};
}
componentDidMount() {
this.timerID = setInterval(
() => this.tick(),
1000
);
}
componentWillUnmount() {
clearInterval(this.timerID);
}
tick() {
this.setState({
date: new Date()
});
}
render() {
return (
<div>
<h1>Hello, world! It's Class</h1>
<h2>It is {this.state.date.toLocaleTimeString()}.</h2>
</div>
);
}
}
import React, { useState, useEffect } from 'react'
export default function FunctionalComponent() {
const [date, setDate] = useState(new Date());
const tick = () => {
setDate(new Date());
}
useEffect(() => {
const interval = setInterval(() => tick(), 1000);
return () => {
clearInterval(interval);
};
}, []);
return (
<div>
<h1>Hello, world! It's Functional</h1>
<h2>It is {date.toLocaleTimeString()}.</h2>
</div>
)
}
this로 관리, 함수형 컴포넌트에서는 useState라는 Hook으로 관리한다.
공식문서 - React.Component
공식문서 - 생명주기 도표

공식문서 - 합성 이벤트(SynthenticEvent)
공식문서 - 이벤트 처리하기
SynthenticEvent 객체를 전달받는다.false를 반환해도 기본 동작을 방지할 수 없다. 반드시 preventDefault를 명시적으로 호출해야 한다.🤔 Bubbling? Capturing?
- Bubbling: 자식으로부터 부모로 올라가는 것.
- Capturing: 부모로부터 자식이 언제 이벤트가 있는지 체크하는 것.
- Event 순서:
다음과 같은 구조에서 버튼을 클릭했을 때 이벤트 발생 순서는handleClickCapture→handleClickCapture2→handleButtonClick→handleClickBubble이다.<div onClickCapture={handleClickCapture}> <div onClickCapture={handleClickCapture2} onClick={handleClickBubble}> <button onClick={handleButtonClick}>Button</button> </div> </div>

공식문서 - 조건부 렌더링(Conditional Rendering)
true && A는 항상 A로 평가되고 false && A는 항상 false로 평가된다. 이때, falsy한 값인 0(false는 아님! falsy!!)이 들어오면 false로 평가되는 것이다.🤔 falsy한 값(0) 처리
1.Boolean(){Boolean(props.count) && `It's ${props.count} times`}
- 삼항연산자
{props.count ? `It's ${props.count} times` : null}
import React from 'react'
function UserGreeting(props) {
return <h1>{props.name && props.name + ',' } Welcome {props.count ? `It's ${props.count} times` : null}</h1>
}
function GuestGreeting(props) {
return <h1>Please sign up.</h1>
}
function Greeting(props) {
// if(props.isLoggedIn) {
// return <UserGreeting name="doyoung" count={0} />
// }
// return <GuestGreeting />;
return props.isLoggedIn ? <UserGreeting name="Doyoung" count={1} /> : <GuestGreeting />;
}
export default function Condition() {
const isLoggedIn = true;
return (
<div>
<Greeting isLoggedIn={isLoggedIn} />
</div>
)
}

key는 엘리먼트의 고유성을 부여하기 위해서(식별하기 위해서) 사용되는 것일 뿐, 값을 가져다가 사용할 수는 없다.key는 props가 아니다.key는 컴포넌트 전체에서 고유해야 하는 것이 아니라 map()으로 묶여있는 list 내부에서만 고유하면 된다.key값을 index를 넣어줄 수도 있지만, 항상 고유한 값은 아니다.
import React, { useState } from 'react'
export default function ControlledComponent() {
const [name, setName] = useState("");
const [essay, setEssay] = useState("Please write an essay about your favorite DOM element.");
function handleChange(event) {
const name = event.target.name;
if (name === 'name') {
setName(event.target.value);
}
if (name === 'essay') {
setEssay(event.target.value);
}
}
// function handleEssayChange(event) {
// setEssay(event.target.value);
// }
function handleSubmit(event) {
alert(`name: ${name}, essay: ${essay}`);
event.preventDefault();
}
return (
<form onSubmit={handleSubmit}>
<label>
Name:
<input name="name" type="text" value={name} onChange={handleChange} />
</label>
<br />
<br />
<label>
Essay:
<textarea name="essay" value={essay} onChange={handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
)
}
import React, { useRef } from 'react'
export default function UncontrolledComponent() {
const fileInputRef = useRef(null);
function handleSubmit(event) {
event.preventDefault();
alert(`Selected file - ${fileInputRef.current.files[0].name}`);
}
return (
<div>
<form onSubmit={handleSubmit}>
<br />
<label>
Upload file:
<input type="file" ref={fileInputRef} />
</label>
<br />
<button type="submit">Submit</button>
</form>
</div>
)
}
useState를 통해 관리하며, 하나의 핸들러만을 가지고 다중 입력을 제어할 수 있다.useRef를 사용한다. (~.current.value, ~.files[n].name)
🤔 VSCode 추천 확장 프로그램
- Rainbow Brackets
- indent-rainbow
- ESLint
- npm
🤔 VSCode 단축어
rfc: reactFunctionalComponent
rcc: reactClassComponent