React를 처음 시작할 때 라이프 사이클에 대한 이해도를 높히려고 class형 컴포넌트 부터
시작하였고, 드디어 함수형 컴포넌트를 써보기 시작했다.
함수형 컴포넌트는 class 없이도 React를 사용할 수 있게 해준다.
import React, { Component } from 'react';
class Hello extends React.Component {
render() {
return (
<div>Hello</div>
);
}
} // class형 컴포넌트
import React from 'react';
function Hello() {
return (
<div>Hello</div>
);
} // 함수형 컴포넌트
export default Hello;
함수형 컴포넌트는 render 메소드를 사용하지 않으며 기존에 사용하였던 class형 함수보다 더 간단하고 직관적으로 코드를 짤 수 있다.
Hooks가 등장하기 전에는 함수형 컴포넌트는 state를 통한 상태값을 사용할 일이 없을 경우 사용하였다.
하지만 Hooks가 등장하면서 함수형 컴포넌트도 state 관리 및 라이프 사이클을 이용하여 코드를 짤 수 있게 되면서 요즘은 거의 함수형 컴포넌트를 사용하는 추세이다.
Hook은 함수 컴포넌트에서 React state와 생명주기 기능(lifecycle features)을 "연동(hook into)" 할 수 있게 해주는 함수.
최상위(at the top level)에서만 Hook을 호출해야 한다. 그리고 반복문, 조건문, 중첩된 함수 내에서 Hook을 실행하면 안된다.
함수형 컴포넌트에서만 사용이 가능하다.
useState
const [state, setState] = useState(initialState);
함수형 컴포넌트에서 state를 사용할 때 쓰는 react 내장 hook이다.
useState는 상태 유지값과 그 값을 갱신하는 함수를 반환한다.
class형 컴포넌트에서 자주 사용했던 구조분해 할당!
배열도 구조분해 할당이 가능하여 배열안에 state와 state를 갱신할 때 사용하는 setState를 작성한다.
만약 state가 islogin 이라면 setState의 자리에도 setLogin이라 작성한다.
기존 setState와 마찬가지로 비동기 함수이다.
함수는 실행이 완료되면 함수 내에서 사용했던 모든 메모리들을 정리한다.
실행이 끝나고도 메모리에 스스로를 남겨둘 수 있는 방법이 있다. 바로 클로저
다.
클로져란 함수와 렉시컬 환경의 조합을 의미한다.
함수가 생성될 당시의 외부 변수를 기억하고 생성 이후에도 계속 접근이 가능하다.
const useState = (init = undefined) => {
let value = init
const getter = () => value // 클로저
const setter = next => (value = next) // 클로저
return [getter, setter]
}
const [state, setState] = useState('클로저')
useState의 내부구조를 간략하게 설명하는 코드이다.
초기값을 받아 내부의 지역변수 value
에 할당한다. 내부 함수 getter()
는 지역변수 init을 바라보고 있다. 또 다른 내부 함수 setter()
는 next라는 인자를 받아 value의 값을 수정한다. 이후 다시 getter()
를 호출하게 되면 변경된 value의 값을 호출하게 된다.
두 함수는 배열 형태로 리턴되고 useState
를 사용할 때는 배열 구조분해 할당 형태로 많이 사용하게 된다.
일반적인 함수라면 return과 함께 실행이 종료되고 나서 내부의 데이터들이 가비지 컬렉팅 되어야 하겠지만, 이 경우 내부 함수가 지역 변수를 참조하고 있으므로 사라지지 않는다.
또한 외부로 노출된 getter, setter 함수를 통해 내부 변수에 지속적으로 접근하며 호출/재할당을 할 수 있다. 이는 클래스형 컴포넌트에서 state가 해온 역할과 동일하다.
자세히보면 이전 class형에서 사용했던 것과 비슷하다.
다만 [ ]
로 감싸주어야한다는거!
요약: 클로저가 있기 때문에 hooks를 통한 상태관리가 가능하다.