React.org - Hook
해당글은 React공식문서를 바탕으로 쓰여진 것이며 그외에 참고한 문서는 따로 Reference를 쓰도록하겠다.
Hook
Hook이란?
정의
함수 컴포넌트에서 React state와 lifecycle features을 "연동(hook into)"할 수 있게 해주는 함수
- class안에서는 작동 안한다.
- React 16.8버젼에 새로 추가 되었다.(이후 모든 패키지를 업그레이드해야한다.)
built-in Hooks
State Hook
예제코드
state 변수 선언
클래스에서는 constructor안에서 this.state를 설정하고 초기화 했지만 함수 컴포넌트에서는 이게 불가능하기 때문에 useState
를 컴포넌트에 호출하여 State를 설정하고 초기화한다.
useState
- function component에서 state를 사용할 수 있게 해준다.
- state값을 업데이트 해주는 함수는 이벤트 핸들러나 다른 컴포넌트에서도 사용될 수있다.
- class의 this.state가 제공하는 기능과 같다.
- 인자값으로 state의 초기값을 넘겨준다.
- state변수와 state변수를 업데이트하는 함수를 반환한다. 이는
this.state.count
와this.setState
와 유사하다.
import React, { useState } from 'react';
function ExampleWithManyStates() {
// 상태 변수를 여러 개 선언했습니다!
const [age, setAge] = useState(42);
const [fruit, setFruit] = useState('banana');
const [todos, setTodos] = useState([{ text: 'Learn Hooks' }]);
// ...
/* 배열구조분해를 하지 않는다면 */
var fruitStateVariable = useState('banana');
var fruit = fruitStateVariable[0];
var setFruit = fruitStateVariable[1];
}
this.setState와 setState(setAge...)가 다른점
this.setState와 setState는 많은 부분이 같지만 state 갱신하는 방법이 다르다.
this.setState는 state를 병합하는 것이지만 setState는 대체하는 것이다.
Effect Hook
- React 16.8버전에 새로 추가
- Effect Hook을 사용하면 함수 컴포넌트에서 side effect를 수행 가능하다.
- React의 class 생명주기의 componentDidMount와 componentDidUpdate, componentWillUnmount가 합쳐진 것이
useEffect
이다.
정리(Clean-up)를 이용하지 않는 Effects
- React가 DOM을 업데이트한 뒤 추가로 코드를 실행해야 하는 경우에 실행이후에 정리가 필요없을 수 있다.
- EX) 네트워크 리퀘스트, DOM 수동 조작, 로깅 등
Class 컴포넌트를 이용한 예시
class Example extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0
};
}
componentDidMount() {
document.title = `You clicked ${this.state.count} times`;
}
componentDidUpdate() {
document.title = `You clicked ${this.state.count} times`;
}
render() {
return (
<div>
<p>You clicked {this.state.count} times</p>
<button onClick={() => this.setState({ count: this.state.count + 1 })}>
Click me
</button>
</div>
);
}
}
- class 컴포넌트는
render
메서드 자체로는 side effect를 발생시키지 않고 Dom을 업데이트하고 난 후에 effect를 수행한다.
그래서 componentDidMount와 componentDidUpdate를 모두 사용한다. - 위 코드 class 안의 componentDidMount와 componentDidUpdate에 같은 코드가 중복된다. 개념적으로 렌더링 이후에 같은 코드가 수행되어야하지만 이를 감지하는 메서드는 React에 없다.
Hook을 사용한 예시
import React, { useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `You clicked ${count} times`;
});
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
- useEffect가 하는 일
- 컴포넌트가 렌더링 이후에 수행해야하는 일을 지시하는 일을 한다.
- React는 넘긴 함수(‘effect’)를 기억했다가 DOM 업데이트를 수행한 이후에 불러낸다.
- useEffect를 컴포넌트 안에서 불러내는 이유
- 컴포넌트 안에 state변수와 props에 접근 가능하다.
- 함수 범위 안에 존재하기 때문에 특별한 API 없이도 값을 얻을 수 있다.
- 자바스크립트의 클로저를 이용하여 자바스크립트가 이미 가지고 있는 방법을 이용하여 문제를 해결한다.
- useEffect는 effect를 렌더링 이후에 발생하는 것으로 effect가 수행되는 시점에 이미 DOM이 업데이트되었음을 보장한다.
- useEffect에 전달된 함수가 모든 렌더링에서 다르다. 이는 리렌더링마다 모두 이전과 다른 effect로 교체하여 전달되기 때문이다. 이 점이 렌더링의 결과의 한 부분이 되게 만드는 점인데, 각각의 effect는 특정한 렌더링에 속한다.
정리(clean-up)를 이용하는 Effects
- 외부 데이터에 구독(subscription)을 설정해야 하는 경우 메모리 누수가 발생하지 않도록 정리(clean-up)해야한다.
Class 컴포넌트를 사용하는 예시
- 아래 코드는 class를 이용하여 상태를 구독(subscribe)하고 보여주는 코드이다.( ChatAPI 모듈의 예)
class FriendStatus extends React.Component {
constructor(props) {
super(props);
this.state = { isOnline: null };
this.handleStatusChange = this.handleStatusChange.bind(this);
}
componentDidMount() {
ChatAPI.subscribeToFriendStatus(
this.props.friend.id,
this.handleStatusChange
);
}
componentWillUnmount() {
ChatAPI.unsubscribeFromFriendStatus(
this.props.friend.id,
this.handleStatusChange
);
}
handleStatusChange(status) {
this.setState({
isOnline: status.isOnline
});
}
render() {
if (this.state.isOnline === null) {
return 'Loading...';
}
return this.state.isOnline ? 'Online' : 'Offline';
}
}
Hook을 사용하는 예시
import React, { useState, useEffect } from 'react';
function FriendStatus(props) {
const [isOnline, setIsOnline] = useState(null);
useEffect(() => {
function handleStatusChange(status) {
setIsOnline(status.isOnline);
}
ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
// effect 이후에 어떻게 정리(clean-up)할 것인지 표시한다.
return function cleanup() {
ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
};
});
if (isOnline === null) {
return 'Loading...';
}
return isOnline ? 'Online' : 'Offline';
}
- effect에서 함수를 반환하는 이유 :
- 추가적인 정리(clean-up) 메커니즘으로 모든 effect는 정리를 위한 함수를 반환할 수 있다.
- 구독(subscription)의 추가와 제거를 위한 로직을 가까이 묶어두어 모두 하나의 effect를 구성하는 것한다.
- effect를 정리(clean-up)하는 시점
- 컴포넌트가 마운트 해제되는 때에 정리(clean-up)를 실행
- effect는 렌더링 될때마다 실행되기 때문에 다음 렌더링이 실행되기전에 이전 effect는 정리된다. 이는 버그 방지에 도움이 된다.
Author And Source
이 문제에 관하여(React.org - Hook), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@ella-front-dev/React.org-Hook저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)