[React] Hooks 파헤치기 시작

[React] Hooks 파헤치기 시작

Hooks 사용법

Hooks 는 React에서 Component를 함수형으로 개발 하도록하기위해 새로 만들어 졌다.

Hooks를 사용하면 함수형 컴포넌트를 사용하면서도 State 제어가 가능하다.

또한 Class형 Component에 비해 획기적으로 코드량이 확연하게 줄어든다.

React에서는 기존 Class 방식의 Component가 아닌 Hooks를 권장한다.

useState

hooks에서 state를 다룰때 사용된다.

import React, { useState } from 'react'; const App = () => { const [check, setCheck] = useState(0); const onClickEvent = () => setCheck(check + 1); return ( <> Hooks! {check} ) } export default App;

위와 같이 구조분해 문법을 통해 변수를 선언하고. useState 에 기본 값을 넣어준다.

배열의 첫번째 값 check 는 현재 state 를 의미한다.

배열의 두번째 값 setCheck 는 state 가 변경될때 사용된다.

위 컴포넌트는 click 할 때 마다 setCheck() 를 불러와서 기존 check 값에 1씩더하는 동작을 한다.

useRef

useRef 는 hooks에서 노드에 접근하고 싶을때 사용된다.

즉, 기존에 document.querySelector('id') 나 Class형 Component에서 사용되던 DOM 접근 방식이 아니라 useRef 를 사용하여 DOM 노드에 접근한다.

import React, { useRef } from 'react'; const App = () => { const inputRef = useRef(null); const onClickEvent = () => inputRef.current.focus(); return ( <> input Focus ) } export default App;

위와 같이 useRef 를 불러온 뒤, 제어하고 싶은 Node의 ref 속성에 넣어주고

하고싶은 event 처리를 진행하면 된다.

단 useRef 를 사용할 때에는 타겟을 해당 ref 의 current 로 바라봐 주어야 한다.

// example const onClickEvent = () => inputRef.current.focus();

useEffect

hooks에서 useEffect 는 클래스형 component에서 사용되던 componentDidMount() , compnentDidUpdate() , componentWillUnmount() ... 등과같이

컴포넌트의 라이프 사이클을 이용하여 제어할때 이용된다.

보통 저런 라이프사이클 메소드를 사용하는 부분을,

hooks에서는 useEffect 이용하여 처리한다고 보면 된다.

import React, { useState, useEffect } from 'react'; const App = () => { const [check, setCheck] = useState(0); const onClickEvent = () => setCheck(check + 1); useEffect(() => { console.log('componentDidMount, componentDidUpdate 역할(1:1 대응은 아님)'); // step 1 return () => { console.log('componentWillMount 역할'); // step 2 } }, [check]); // step 3 return ( <> Hooks! {check} ) } export default App;

useEffect 를 사용하면 컴포넌트 업데이트의 감지가 가능해진다. 위 코드를 자세히 보면,

step1 부분이 componentDidMount , componentDidUpdate -> 두가지가 합쳐졌다 보면되며,

컴포넌트가 첫 랜더링 되었을때나 컴포넌트가 리랜더링 되었을때를 감지할 수 있다.

step2 부분을 보면 함수를 리턴한다. 이부분은, componentWillMount 의 역할을 하며, 컴포넌트가 제거되기 직전을 감지 할 수 있다.

step3 부분을 보면 배열에 값이 들어가 있다. 이 값은 useState 를 통해 선언된 state 값을 의미하며, 해당 state 가 변경 되었을때 useEffect 가 실행 된다.

만약 값이 없는 빈배열이라면 componentDidMount 역할을 수행하며 컴포넌트가 첫 랜더링 되었을 때 실행된다.

정리 해보면, useEffect 는 component 의 리랜더링 랜더링을 감지하여 동작할 수 있고,

이곳에서 비동기 요청 및 정리, 등의 처리를 할 수 있다.

state 마다 다른 useEffect 를 주고싶다면, useEffect 를 여러번 중복해도 무관하다.

useLayoutEffect

useEffect 와 비슷한 역할을한다. useEffect 는 보통 화면이 랜더링 된 후 실행된다. 그러나, useLayoutEffect 는 화면의 리사이징 즉, 레이아웃에 변화를 감지하는 Effect이다.

useEffect -> 화면이 완전히 바뀌고 난 후 발생

-> 화면이 완전히 바뀌고 난 후 발생 useLayoutEffect -> 화면이 바뀌기 전 발생

React.memo

React에서 컴포넌트는 state가 변경 되었을때 리랜더링된다.

React.memo 를 사용한다면 관계없는 컴포넌트의 state가 변경되어도 전체가 리랜더링되는 낭비를 방지하여 성능개선을 할 수 있다.

이전 React class 형 컴포넌트에서는 shouldComponentUpdate 메소드를 사용하여 state,props의 변화를 감지 하였다.

더욱나아가 React.PureComponent 는 class 형 컴포넌트에서 shouldComponentUpdate 를 사용할 필요없이

자동으로 shouldComponentUpdate 기능을 지원해주는 컴포넌트를 만들어주어 편하게 성능 개선을 지원하였다.

Hooks 에서 비슷한기능을 지원하는것이 바로 React.memo 이다.

// App.jsx import React, { useState } from 'react'; import Hello from './Hello'; const App = () => { const [hello, setHello] = useState(0); const onChangeEvent = e => { const makeArray = Array(e.target.value.length).fill({}); setHello(makeArray.map((item, i) => ())); } return ( <> {!hello ? '' : hello} ) } export default App;

// Hello.jsx import React, { memo } from 'react'; const Hello = memo(({ num }) => { return ( Hello {num} ) }); export default Hello;

위 코드의 실행결과는 input 테그에 text 를 입력하면 아래 input value length 만큼의 hello 텍스트가 출력된다.

ex) input.value가 test 라면 4개의 자식 hello 컴포넌트가 생성됨

App.jsx 파일에서 input value의 length만큼 즉, 4개의 child 컴포넌트 Hello.jsx 를 불러오는데 여기서 기본적인 성능이슈가 생긴다.

App.jsx 의 state 가 변경되기 때문에 그 child 요소인 4개의 Hello 컴포넌트 전부 리랜더링 되버리는 것이다.

이를 방지하기 위해 React.memo 를 사용한다.

shouldComponentUpdate 나 React.PureComponent 를 이용하여 불필요한 랜더링을 방지하던것과 마찬가지로

Hooks 에서는 React.memo 를 사용하여 불필요한 랜더링을 막는다.

React-dev-tools 로 확인가능하나 현재 v4로 버전이 상승하여 highlight update 기능이 사라져버림

기타

JSX 내에, class 는 className 으로 선언해야 한다.

JSX 내에, label 테그의 for 은 htmlFor 을 사용해야 한다.

from http://ryulog.tistory.com/156 by ccl(A) rewrite - 2020-03-07 08:55:04

댓글

이 블로그의 인기 게시물

[React] - 18) 프로젝트 빌드하기(+코드 스플리팅)

입트영(2020.03.23) - Iced Drinks / 아이스 음료

Redux + React