본문 바로가기

Study/React

Function Component | memo, React Hooks

How to make Function component? 

+) 함수형 컴포넌트는 클래스 컴포넌트와 달리, state와 life chcle method를 직접 가질 수 없다. 따라서 간단한 static component를 만들 때 이용할 수 있다. 

 

함수 선언 이용하기

function Avatar(props) {
  return (
    <img className="Avatar"
      src={props.user.avatarUrl}
      alt={props.user.name}
    />
  );
}

 

arrow function 이용하기

const Avatar = props => {
  return (
    <img className="Avatar"
      src={props.user.avatarUrl}
      alt={props.user.name}
    />
  
  )
}

 

props에 있는 user 객체가 반복적으로 사용되고 있을 때에는 deconstructing 문법을 이용해서, 중복 작성을 피할 수 있다. ( props ) 대신 ( { user } ) 라고 작성하면 된다. user에서도 deconstructing이 가능한데, 그 때에는 ( { user: {contact} } )라고 작성할 수 있다. 

 

Memo vs. PureComponent 

함수형 컴포넌트에는 클래스 컴포넌트에서 사용하는 state나 life cycle method 뿐만 아니라 pureComponent를 이용할 수 없다. pureComponent를 상속하는 컴포넌트들은, 자신의 state나 props가 변경되지 않으면 render를 호출하지 않기 때문에 리액트 앱의 성능 개선에 도움을 줄 수 있는 유용한 API였다. 함수형 컴포넌트에서도 pureComponent와 비슷한 동작을 하도록 만들 수 있는 방법이 있는데, memo funciton을 이용하는 것이다.

 

memo function은 우리가 작성한 function component 자체를 인자로 받고, props가 변경되지 않았을 때 인자로 전달 된 함수가 호출되지 않는다. 즉, 렌더링이 일어나지 않는다.  

 

impore React, { memo } from 'react'; 

const test = memo(props => {
  // code ...
  // return jsx 
})

 

React Hook | 함수형 컴포넌트와 클래스 컴포넌트의 차이점 

 

memo가 function component가 class component의 PureComponent와 비슷한 역할을 했다면, React Hook은 function component에서도 class component의 state와 life cycle method를 이용할 수 있게 만들어 주는 역할을 한다. 

 

클래스와 함수로 만들어진 컴포넌트의 차이점은, 클래스와 함수의 차이라고도 할 수 있다. 클래스 컴포넌트 내부에 만들어지는 메서드나 멤버 변수들은, 클래스가 만들어지는 순간에, 딱 한 번만 생성된다. 반면 함수 컴포넌트 내부에 선언되는 메서드나, 변수들은 함수가 실행될 때 마다 매번 만들어진다. 자세한 내용은 useRef 파트에도 설명되어 있다. 

 

useState

??? The useState set method is not reflecting a change immediately

함수형 컴포넌트에서 state를 지정하고 싶을 때, useState라는 API를 이용할 수 있다.

 

import React, { useState } from 'react';

const count = props => {
  const [count, setCount] = useState(0); // here!
  
  const handleClick = () => {
    setCount(count + 1)
  }
  
  return (
  <>
    <h1>hello, { count }</h1>
    <button onClick={ handleClick }></button>
  </>
  ) ;

}

 

useState를 이용하려면 먼저 두 개 변수를 선언해야 한다. 첫번째는 실제 state의 값을, 두 번째는 state를 업데이트할 수 있는 함수를 저장한다. useState의 인자로 전달하는 값은 state의 초기값이 된다. 즉 초기값은 0이 된다.

위의 코드는 브라우저에서 0을 보여주다가 버튼이 클릭될 때 마다 1, 2, 3, 4... 를 출력할 것이다. 

 

+) 전체 코드가 매번 실행되는 것이기 때문에 매번 count에 0을 할당할 것 같지만, useState라는 API자체가 이전에 업데이트 된 state를 기억하기 때문에, 버튼이 클릭될 때 마다, 1, 2, 3 ...이 출력된다. | React will preserve this state between re-renders. 

 

useRef

 

count

 

클래스 컴포넌트가 만들어 질 때, 클래스 내부에 포함되어 있는 메서드와 변수가 함께 만들어진다. 그러면서 render 함수만 반복적으로 호출된다. render가 호출된다고 해서 이 메서드나 변수가 다시 만들어지는 것은 아니다. 이들은 클래스가 만들어질 때 딱 한번만 만들어진다. 

 

반면에 위의 count와 같은 함수형 컴포넌트는 props나 state가 변경될 때 마다 호출이 되고, rendering(return) 뿐만 아니라 전체 코드가 매번 실행되는 것이기 때문에 매번 멤버 변수를 선언하게 된다. 즉 count가 실행될 때 마다 내용은 똑같은데 새로운 handleClick이 만들어지고, handleClick을 props으로 받는 컴포넌트에는 계속 re-render가 일어날 것이다.   

또 다른 예로는, 함수 안에서 리액트가 제공하는 createRef()를 이용해 element 정보를 받아오는 변수가 선언되어 있을 때, 함수가 호출될 때 마다 매번 똑같은 element 정보를 새롭게 받아와야 한다는 것이 있다.

 

이 때 사용할 수 있는 것이 React Hook에서 제공하는 useCallback과 useRef이다. useRef는 매번 새로운 레퍼런스를 만드는 것이 아니라 한번만 만들고, 만들어진 레퍼런스를 메모리에 저장해서, 재사용한다. useCallback도 마찬가지로, 함수를 메모리에 저장해서 재사용한다.  

 

useCallback

위에서 언급한 바와 같이 레퍼런스 뿐만 아니라, 함수 코드 내부에서 정의한 콜백 함수도 메모리에 저장해서 재사용할 수 있다. 아래와 같이 useCallback의 인자로 우리가 정의한 콜백 함수를 전달해 주면 된다. 남발하면 메모리에 부담이 될 수 있으므로 필요할 때에만 사용하는 것이 중요하다. => 주로 부모 컴포넌트에서 props을 전달받아서 실질적인 변화가 없음에도 re-render가 발생하는 자식 컴포넌트에 useCallback을 이용한다. 

 

useEffect와 마찬가지로 두번째 인자에 dependency list를 전달할 수 있는데, 아무 것도 전달하지 않으면 계속 새로운 함수를 만들기 때문에 해당 API를 사용하는 의미가 없다. 우리가 원하는 것처럼 callBack을 한 번만 만들어서 메모리에 저장한 뒤 재사용하려면 텅 빈 배열을 인자로 전달해야 한다. 

 

import React, { useState, useCallback }

const handleClick = useCallback( () => {
  setCount(count+1)
}, [] )

 

useEffect | Similar to componentDidMount & componentDidUpdate 

함수 컴포넌트 내부에 useEffect 함수를 정의하면, 그 컴포넌트가 처음 마운트 되었을 때 & 업데이트 되었을 때(state나 props이 변경) 마다, 인자로 전달되는 콜백 함수를 실행한다.

두번째 인자에도 선택적으로 값을 전달할 수 있는데, 언제 콜백 함수를 실행할 것인지를 세부적으로 정할 수 있다. 예를 들어, 인자에 [ count ]와 같이 배열 안에 데이터를 전달하면, count가 업데이트 되었을 때에만 콜백함수를 실행할 수 있다. 만약 텅 빈 []를 전달하면 컴포넌트가 처음 마운트 되었을 때에만 콜백 함수를 실행한다. 

 

import React, { useState, useEffect } from 'react';

function Example() {
  const [count, setCount] = useState(0);

  useEffect(() => { // here! 
    document.title = `You clicked ${count} times`;
  }, [count]);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

 

 

emmet | rsi + tab 

 

'Study > React' 카테고리의 다른 글

MVC & Dependency Injection  (0) 2022.04.29
PostCSS  (0) 2022.04.23
Deployment  (0) 2022.04.22
Class Component | Life cycle method  (0) 2022.04.21
Class Component | state, ref, pureComponent  (0) 2022.04.21