[07.18] Virtual DOM, React Hooks

0
post-thumbnail

목차

  • DOM
  • React Hoks
  • Custom Hooks

📌 DOM

: Document Object Model의 약자로 문서 객체 모델을 의미

  • 문서 객체란 : 브라우저가 Javascript와 같은 스크립팅 언어가 < html >, < head >, < body >와 같은 태그들에 접근하고 조작할 수 있도록 문서를 트리 구조로 객체화 한것
    -> DOM은 브라우저가 HTML문서를 조작할 수 있도록 트리 구조화한 객체 모델
  • 실제 DOM 조작이 느린 경우는 DOM 조작이 발생될때 마다 브라우저에서 다시 레이아웃을 계산하고, 페이지를 다시 그리는 렌더링과정이 있기 때문이다 이것은 발생하는 비용이 큰 단점도 있음

Virtual DOM (가상돔)

: Real Dom의 복사본이며, 실제 DOM 객체처럼 직접 접근하여 조작하는 것은 안되지만 이 가상 DOM에 접근하여 어떤 변화가 있는지 확인

  • Real DOM은 Browser에서 생성되는 Document Object Model을 가리키는 용어이며 Virtual DOM과 구분하기 위해 해당 용어를 씀
  • 가상 DOM은 실제 DOM과 동기화되어 상태가 변경될때마다 가상 DOM을 생성하여 이전 상태와 비교(Diffing)
  • 변경이 필요한 부부만 실제 DOM에 반영하여 업데이트(Reconciliation:재조정)
    -> 전체 UI를 다시 그릴 필요가 없음
  • 여러 개의 상태 변경을 그때 그때 처리하는 것이 아니라 일괄적으로 한번에 업데이트 (Batch Update)

React Key

: Key는 React가 어떤 항목을 변경, 추가 또는 삭제할지 식별을 하기 위해 사용

  • key는 엘리먼트에 안정적인 고유성을 부여하기 위해 배열 내부의 엘리번트에 지정
  • 전역적으로 유일할 필요는 없다 형제 엘리먼트 사이에서만 유일하면 됨
  • key값으로 사용할 유니크한 값이 없다면 최후의 수단으로 index를 key로 사용하기도 하지만 항목의 순서가 바뀔 수 있는 경우 key에 인덱스를 사용하는 것은 권장하지 않음

📌 React Hooks

useMemo(예시)

: 특정 값(value)을 재사용하고자 할 때 사용하는 Hook

  • useMemo는 처음에 계산된 결과값을 메모리에 저장해서 컴포넌트가 리렌더링되어도 해당 함수를 계속 호출하지 않고 저장된 메모리값을 불러와서 사용
    -> Memoization과도 긴밀한 관계가 있음

    📍 Memoization이란?
    기존에 수행한 연사의 견과 값을 메모리에 저장을 해두고, 동일한 입력이 들어오면 재활용하는 프로그램이 기법
    -> 중복 연산을 할 필요가 없어지니깐 앱의 성능 최적화할 수 있음

  • 상태값이 변해서 리렌더링이 될 경우에, 특정 변수에 useMemo를 사용해서 해당 함수만 실행되도록 처리하게되면 불필요한 곳에서 렌더링은 일어나지 않음

useCallback(예시)

: 함수의 재사용을 위해 사용하는 Hook

  • 함수는 객체로서 리렌더링시 값이 같아도 주소값이 다르기 때문에 기존의 함수와 다르다고 판단을 함
    -> useCallback을 이용해 함수 자체를 저장해서 다시 사용하면 메모리 주소값을 저장했다가 다시 사용함

📌 Custom Hooks

: 개발자가 스스로 커스텀한 훅을 의미하여 이를 이용해서 반복되는 로직을 함수로 뽑아내어 재사용이 가능

  • 상태 관리 로직의 재활용이 가능
  • 클래스 컴포넌트보다 적은 양의 코드로 동일한 로직을 구현할 수 있음
  • 함수형으로 작성하기 때문에 명료하다는 장점이 있음

useInput

App.js

import { useInput } from './useInput'
import './App.css'
// 확인 버튼을 누를시 나타는 alert창 함수
function displayMessage(message) {
  alert(message)
}

function App() {
  const [inputValue, handleChange, handleSubmit] = useInput('', displayMessage )

  return (
    <div>
      <h1>useInput</h1>
      <input value={inputValue} onChange={handleChange}/>
      <button onClick={handleSubmit}>확인</button>
    </div> 
  );
}

export default App;

useInpust.js

import { useState } from "react";

// input의 초기값을 매개변수로 줌
export function useInput (initialValue, submiAction) {
    const [inputValue, setInputValue] = useState(initialValue);

    const handleChange = (e) => {
        setInputValue(e.target.value);
    };

    const handleSubmit = () => {
      // 확인 버튼을 누르면 input에 빈 문자열로 해주고
      // input을 초기값(initialValue)로 해줘
        setInputValue('');
        submiAction(inputValue);
    }

    return [inputValue, handleChange, handleSubmit];
}

useFetch

App.js

import "./styles.css";
import useFetchData from "./util/hooks";

export default function App() {
  const data = useFetchData();

  return (
    <div className="App">
      <h1>To do List</h1>
      <div className="todo-list">
        {data &&
          data.todo.map((el) => {
            return <li key={el.id}>{el.todo}</li>;
          })}
      </div>
    </div>
  );
}

hooks.js

import { useEffect, useState } from "react";

const useFetchData = () => {
  const [data, setData] = useState();

  useEffect(() => {
    fetch("data.json", {
      headers: {
        "Content-Type": "application/json",
        Accept: "application/json"
      }
    })
      .then((response) => {
        return response.json();
      })
      .then((myJson) => {
        setData(myJson);
      })
      .catch((error) => {
        console.log(error);
      });
  }, []);

  return data;
};

export default useFetchData;

1개의 댓글

comment-user-thumbnail
2023년 7월 18일

훌륭한 글이네요. 감사합니다.

답글 달기