State와 생명주기
Class Component
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!</h1>
<h2>It is {this.state.date.toLocaleTimeString()}.</h2>
</div>
);
}
}
Functional Component
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>
);
}
함수형 컴포넌트가 생긴 지 얼마 안 되었는데 이전에는 첫 번째 코드인 클래스 컴포넌트로 많이 사용했습니다.
왜냐하면 당시에는 Hook이 없기 때문에 Functional Component에서 상태 관리를 할 수 없었습니다.
하지만 Hook이라는 게 나오면서 함수형 컴포넌트에서 상태 관리가 되었고, 재사용 가능한 기능들이 많이 사용하게 되면서 현재는 대부분 함수형 컴포넌트를 많이 쓴다고 합니다.
클래스 컴포넌트를 보면 Mount, unMount 같은 생명주기(lifecycle) 함수형 컴포넌트에서는 useEffect Hook을 통해 구현되었고, 클래스 컴포넌트에 constructor, tick()에서 상태 관리를 했다면, 함수형 컴포넌트에서는 useState라는 Hook으로 상태 관리와 업데이트를 동시에 할 수 있습니다.
https://ko.reactjs.org/docs/state-and-lifecycle.html
Event Handling ( 이벤트 처리하기 )
React 요소에서 이벤트를 처리하는 방식은 DOM 요소에서 이벤트를 처리하는 방식과 매우 유사합니다.
- React의 이벤트는 소문자 대신 캐멀 케이스를 사용합니다.
- JSX를 사용하여 문자열이 아닌 함수로 이벤트 핸들러를 전달합니다.
// HTML에서 EventHandling
<button onclick="activateLasers()">
Activate Lasers
</button>
// React안 JSX에서의 EventHandling
<button onClick={activateLasers}>
Activate Lasers
</button>
- false를 반환해도 기본 동작을 방지할 수 없습니다.
// submit button 클릭시 return false를 반환하게되어 기본 동작이 수행되지 않음
<form onsubmit="console.log('You clicked submit.'); return false">
<button type="submit">Submit</button>
</form>
// React JSX에서는 return false를 반환해도 기본동작이 실행되기때문에
// 기본동작을 방지하기 위해, 해당 이벤트 핸들링 함수시작에 preventDefault()를
// 넣어줌으로써 동작을 방지합니다.
function Form() {
function handleSubmit(e) {
e.preventDefault();
console.log('You clicked submit.');
}
return (
<form onSubmit={handleSubmit}>
<button type="submit">Submit</button>
</form>
);
}
이벤트 핸들러에 인자 전달하기
루프 내부에서는 이벤트 핸들러에 추가적인 매개변수를 전달하는 것이 일반적입니다. 따로 매개변수가 없으면 이벤트 함수에 event만 반환하겠지만, 아래 두 줄의 코드는 화살표 함수와 Function.prototype.bind 함수인데 둘 다 React 이벤트를 나타내는 e인자가 ID 뒤에 두 번째 인자로 전달됩니다.
SyntheticEvent ( 합성 이벤트 )
이벤트 핸들러는 모든 브라우저에서 이벤트를 동일하게 처리하기 위한 이벤트 래퍼 SyntheticEvent 객체를 전달받습니다.
브라우저의 고유 이벤트가 필요하다면 nativeEvent 어트리뷰트 참조하세요. 예를 들면 onMouseLeave에서 event.nativeEvent는 mouseout 이벤트를 가리킵니다.
이벤트 함수는 브라우저마다 동작이 조금씩 다를 수 있는데 React 사용자에게는 일관된 경험으로 개발을 할 수 있도록 환경을 제공하기 위해 합성 이벤트라는 게 있는 것이다.
지원하는 이벤트
React는 이벤트들을 다른 브라우저에서도 같은 속성을 가지도록 표준화해줍니다. 다음 이벤트 핸들러는 이벤트 버블링 단계에서 호출됩니다. 캡처 단계에 이벤트 핸들러를 등록하기 위해서는 이벤트 이름에 Capture를 덧붙이면 된다. ex) onClick -> onClickCapture
버블링이란 ? 컴포넌트, 요소 클릭 시 부모로 이벤트를 계속 전파시키는 것
캡쳐링이란? 부모가 자식들 중에 누가 클릭이 됐는지 확인하는 단계.
Clipboard 이벤트 , Composition 이벤트, Keyboard 이벤트, Focus 이벤트 , Form 이벤트, Generic 이벤트, Mouse 이벤트, Pointer 이벤트, Selection 이벤트, Touch 이벤트, UI 이벤트, Wheel 이벤트, Media 이벤트, Image 이벤트, Animation 이벤트, Transition 이벤트, 기타 이벤트
아래 코드는 button 요소 위에 부모 요소로 div를 두 개 덮어놓고 3개의 요소 다 onClick 이벤트를 할당해줬습니다. 과연 출력은 어떻게 나올까요?
<div onClick={handleClick3}>
<div onClick={handleClick2}>
<button onClick={handleClick1}>Button</button>
</div>
</div>
)
자식 요소부터 이벤트가 발생하고, 부모 요소로 하나씩 퍼지는 걸 볼 수 있네요. 이제 Capture 덧붙여줄게요.
<div onClickCapture={handleClick3}>
<div onClick={handleClick2}>
<button onClick={handleClick1}>Button</button>
</div>
</div>
최상위 부모에 onClickCapture를 넣어주니까 Capture 단계를 시작해주고 그다음에 최하위 자식 요소에서부터 다시 버블링을 하는 것을 확인할 수 있습니다.
이벤트 순서는 Capture -> Target -> Bubble라고 할 수 있습니다.
https://ko.reactjs.org/docs/handling-events.html
https://ko.reactjs.org/docs/events.html
'Study > React' 카테고리의 다른 글
React - 공식문서 읽어보기4 (0) | 2022.07.17 |
---|---|
React - 공식문서 읽어보기3 (0) | 2022.07.14 |
React - 공식문서 읽어보기 (0) | 2022.07.13 |
React { Fetch } (0) | 2022.07.13 |
React { Key } (0) | 2022.07.12 |