본문 바로가기

dev/React

[React] 리액트와 같은 프론트엔드 프레임워크가 필요한 이유?

반응형

 

 

Udemy에서 <The Ultimate React Course 2024: React, Next.js, Redux & More>를 수강하며 공부한 내용입니다.

 

 

리액트와 같은 프론트엔드 프레임워크가 존재하는 이유는 뭘까?

그냥 Vanilla JavaScript를 사용하면 안 되는 걸까?

 

 

과거에는

- 모든 웹사이트가 서버에서 렌더링되며 백엔드와 밀접하게 구동됐다. (server-side rendering)

- 서버/백엔드에서 렌더링 완료한 후 → 브라우저를 통해 단순히 클라이언트/프론트에 보여주기만 함

- jQuery가 널리 사용됨

 

Single-Page Application(SPA)의 등장

- 클라이언트에서 렌더링 (client-side rendering)

- 더이상 '웹 페이지'가 아닌 '웹 어플리케이션'으로서 작동하게 됨

- 하나의 페이지 안에서 모든 처리 페이지를 리로딩 하지 않음

 

Single-Page Application에 리액트가 필요한 이유

- Vanilla JavaScript와 jQuery로 복잡하게 연결된 데이터를 다루려면, 직접적인 DOM 조작 및 체이닝이 많이 필요함

    → 스파게티 코드가 됨

- Vanilla JavaScript를 사용하면 데이터가 DOM에, 그러니까 html 요소 안에 저장됨

    → 직접 DOM에 접근해야 하므로 코드가 더 복잡해짐

- 구조화된 코드를 작성하게 함

    → 여러 사람의 작업이 일관된 스타일을 가질 수 있음

 

todo 페이지를 만드는 예시코드: Vanilla JavaScript & jQuery

  • 할 일 목록(todos 배열)을 수동으로 관리하며 DOM을 조작해 업데이트
  • renderTodos() 함수에서 매번 DOM을 비우고 새로 그리므로, 할 일이 많아질수록 성능 문제가 생길 수 있음
  • 이벤트 체이닝이 많아지고 상태가 복잡해지면 스파게티 코드가 될 수 있음
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>To-Do App</title>
  <style>
    .completed { text-decoration: line-through; color: gray; }
  </style>
  <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
  <h2>My To-Do List</h2>
  <input id="todo-input" type="text" placeholder="Add a new to-do">
  <button id="add-btn">Add</button>
  <ul id="todo-list"></ul>

  <script>
    $(document).ready(function() {
      // 할 일 목록 배열 (데이터를 상태처럼 관리하기 위해)
      let todos = [];

      // 할 일 추가
      $('#add-btn').on('click', function() {
        const task = $('#todo-input').val();
        if (task) {
          todos.push({ task, completed: false });
          $('#todo-input').val('');
          renderTodos();
        }
      });

      // 할 일 렌더링 함수
      function renderTodos() {
        $('#todo-list').empty(); // 기존 리스트를 지우고 다시 그리기
        todos.forEach((todo, index) => {
          const todoItem = $(`
            <li class="${todo.completed ? 'completed' : ''}" data-index="${index}">
              ${todo.task} <button class="complete-btn">Complete</button>
              <button class="delete-btn">Delete</button>
            </li>
          `);
          $('#todo-list').append(todoItem);
        });
      }

      // 할 일 완료 상태 변경
      $('#todo-list').on('click', '.complete-btn', function() {
        const index = $(this).parent().data('index');
        todos[index].completed = !todos[index].completed;
        renderTodos();
      });

      // 할 일 삭제
      $('#todo-list').on('click', '.delete-btn', function() {
        const index = $(this).parent().data('index');
        todos.splice(index, 1);
        renderTodos();
      });
    });
  </script>
</body>
</html>

 

 

 

todo 페이지를 만드는 예시코드: React

  • useState 훅을 통해 todos와 input을 관리하므로 코드가 비교적 간결
  • 상태가 업데이트될 때마다 리액트가 변경된 부분만 자동으로 업데이트
  • 상태 관리와 각 기능(추가, 삭제, 완료 변경)이 명확하게 분리돼 있어 유지보수가 쉬움
import React, { useState } from 'react';

function TodoApp() {
  // 상태 설정: todos 배열과 입력값
  const [todos, setTodos] = useState([]);
  const [input, setInput] = useState("");

  // 할 일 추가 함수
  const addTodo = () => {
    if (input) {
      setTodos([...todos, { task: input, completed: false }]);
      setInput(""); // 입력 필드 초기화
    }
  };

  // 할 일 완료 상태 변경 함수
  const toggleComplete = (index) => {
    const newTodos = [...todos];
    newTodos[index].completed = !newTodos[index].completed;
    setTodos(newTodos);
  };

  // 할 일 삭제 함수
  const deleteTodo = (index) => {
    const newTodos = todos.filter((_, i) => i !== index);
    setTodos(newTodos);
  };

  return (
    <div>
      <h2>My To-Do List</h2>
      <input
        value={input}
        onChange={(e) => setInput(e.target.value)}
        placeholder="Add a new to-do"
      />
      <button onClick={addTodo}>Add</button>
      <ul>
        {todos.map((todo, index) => (
          <li key={index} className={todo.completed ? 'completed' : ''}>
            {todo.task}
            <button onClick={() => toggleComplete(index)}>Complete</button>
            <button onClick={() => deleteTodo(index)}>Delete</button>
          </li>
        ))}
      </ul>
    </div>
  );
}

export default TodoApp;

 

 

 

반응형