[React] 리액트를 사용한 코드의 특징

1 분 소요

To-do list를 각각 Vanila Javascript와 React.js 라이브러리를 사용해서 작성하고, 리액트를 왜 사용하는지에 대해 공부합니다.

Vanila Javascript를 사용했을 때

기본 틀은 아래와 같습니다.

<body>
  <div class="todo">
    <h3>할일 목록</h3>
    <ul class="list"></ul>
    <input type="text" class="desc" />
    <button onclick="onAdd()">추가</button>
    <button onclick="onSaveToServer()">서버에 저장</button>
  </div>
</body>

body 안에 script 코드를 작성합니다.

<script>
      let currentId = 1;
      const todoList = [];

      function onAdd() {
        const descEl = document.querySelector(".todo .desc");
        const todo = { id: currentId++, desc: descEl.value };
        todoList.push(todo);

        const listEl = document.querySelector(".todo .list");
        const todoEl = makeTodoElement(todo);
        listEl.appendChild(todoEl);
      }

      function makeTodoElement(todo) {
        const todoEl = document.createElement("li");
        const spanEl = document.createElement("span");
        const buttonEl = document.createElement("button");

        spanEl.innerHTML = todo.desc;
        buttonEl.innerHTML = "삭제";
        buttonEl.dataset.id = todo.id;
        buttonEl.onclick = onDelete;

        todoEl.appendChild(spanEl);
        todoEl.appendChild(buttonEl);

        return todoEl;
      }

      function onDelete(e) {
        const id = e.target.dataset.id;
        const index = todoList.findIndex((todo) => todo.id == id);
        if (index >= 0) {
          todoList.splice(index, 1);
          const listEl = document.querySelector(".todo .list");
          const todoEl = e.target.parentNode;
          listEl.removeChild(todoEl);
        }
      }

      function onSaveToServer() {
          // todoList를 서버로 전송한다.
      }
</script>

React를 사용했을 때

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

function App() {
  const [todoList, setTodoList] = useState([]);
  const [currentId, setCurrentId] = useState(1);
  const [desc, setDesc] = useState("");
  const [showOdd, setShowOdd] = useState(false);
  useEffect(() => {
    console.log("todoList : ", todoList);
  });

  function onAdd(e) {
    setTodoList([...todoList, { id: currentId, desc }]);
    setCurrentId((prev) => prev + 1);
    setDesc("");
  }

  function onDelete(e) {
    console.log(typeof e.target.dataset.id);
    setTodoList(
      todoList.filter((todo) => todo.id !== Number(e.target.dataset.id))
    );
  }

  function onSaveToServer() {}

  return (
    <div>
      <h3>할 일 목록</h3>
      <ul>
        {todoList
          .filter((_, index) => (showOdd ? index % 2 === 0 : true))
          .map((todo) => (
            <li key={todo.id}>
              <span>{todo.desc}</span>
              <button data-id={todo.id} onClick={onDelete}>
                삭제
              </button>
            </li>
          ))}
      </ul>
      <input
        tyle="text"
        value={desc}
        onChange={(e) => {
          setDesc(e.target.value);
        }}
      />
      <button onClick={onAdd}>추가</button>
      <button onClick={() => setShowOdd(!showOdd)}>
        홀수 아이템만 보기 on/off
      </button>
      <button onClick={onSaveToServer}>서버에 저장</button>
    </div>
  );
}

export default App;

차이

리액트를 사용하면 코드의 이벤트 핸들러에서는 데이터를 변경하는 작업만 하고 있습니다. 이에 반해, Vanila Javascript를 사용한 코드는 데이터를 변경하는 코드도 있지만 DOM에 접근하는 코드도 섞여있습니다.

리액트는 비즈니스 로직UI를 접근하는 코드 가 분리되어 있습니다. jsx 부분에서 한 번만 작성해 두면 이후엔 신경을 쓰지 않아도 되는 장점이 있습니다.

당장에 위의 코드에서 사용한 자바스크립트 내장 함수 filter를 사용한 렌더링을 Vanila Javascript로 구현한다고 하면 되게 복잡한 코드로 작성될 것입니다.


참고)

위의 filter 함수의 콜백 함수에서 사용된 파라미터 _는 사용하지 않는 인수인 경우 사용합니다. 사용하지 않는다는 것을 명확히하면 가독성이 나아지기 때문입니다.

카테고리:

업데이트:

댓글남기기