Post

프론트엔드는 어쩌다 함수형 프로그래밍에 빠졌나요?

들어가며

프론트엔드 개발은 시간이 지남에 따라 복잡성과 규모가 증가하여 다양한 패러다임을 받아들이게 되었습니다.

초기의 절차적 프로그래밍에서 객체지향 프로그래밍의 전환 이후로 최근에는 함수형 프로그래밍이 많은 주목을 받고 있는데요.

저도 어느새부턴가 함수형 프로그래밍으로 개발하는 것이 익숙해졌습니다.

프론트엔드에서 점유율이 가장 높은 React가 v16.8을 출시하면서 hook과 함께 함수형 컴포넌트를 선보였고 이는 대 함수형 시대의 개막식이었다고 생각합니다. (역시 대장의 힘은 굉장하다)

Desktop View

이제 함수형 프로그래밍이 프론트엔드 개발에 어떻게 뿌리내리게 되었는지, 그리고 그 주요 이점들을 탐구해보겠습니다.

함수형 프로그래밍

먼저, 함수형 프로그래밍의 개념을 짚고 넘어가 볼까요?

함수형 프로그래밍은 순수 함수불변 데이터를 중심으로 한 프로그래밍 패러다임입니다.

이 접근 방식은 다음과 같은 핵심 개념을 포함합니다:

1. 순수 함수 (Pure Function)

순수 함수는 같은 입력에 대해 항상 같은 출력을 반환하며, 함수의 실행이 외부 상태를 변경하지 않는 함수를 말합니다. 이는 예측 가능성을 높이고, 디버깅을 용이하게 합니다.

순수 함수는 다음과 같은 특성을 가집니다:

  • 부수 효과 없음(No Side Effects)

    함수 내부에서 외부 상태를 변경하지 않습니다. 예를 들어, 데이터베이스에 기록하거나, 파일 시스템을 변경하지 않습니다.

  • 입력과 출력의 일관성

    동일한 입력에 대해 항상 동일한 출력을 반환합니다. 이는 함수를 테스트하기 쉽게 만들며, 코드의 안정성을 높입니다.

1
2
3
// 순수 함수의 예
const add = (a, b) => a + b;
console.log(add(2, 3)); // 항상 5를 반환

2. 불변성(Immutability)

불변성은 데이터가 생성된 이후 변경되지 않는 특성을 의미합니다. 모든 데이터의 수정은 새로운 데이터를 생성하는 방식으로 이루어집니다.

불변성은 다음과 같은 장점을 제공합니다:

  • 변경 추적 용이성

    데이터 변경이 발생할 때마다 새로운 데이터가 생성되므로, 이전 상태를 쉽게 추적할 수 있습니다.

  • 병렬 처리 안전성

    불변 데이터는 여러 스레드에서 동시에 접근해도 안전하므로, 병렬 처리 환경에서 예측 가능성과 안정성을 제공합니다.

1
2
3
4
5
// 불변성 예제
const originalArray = [1, 2, 3];
const newArray = [...originalArray, 4]; // 원본 배열을 변경하지 않고 새로운 배열 생성
console.log(originalArray); // [1, 2, 3]
console.log(newArray); // [1, 2, 3, 4]

3. 고차 함수(Higher-order Functions)

고차 함수는 함수를 인자로 받거나, 함수를 반환하는 함수를 말합니다. 이는 함수의 조합과 재사용성을 높이는 데 도움을 줍니다.

고차 함수는 다음과 같은 이점을 제공합니다:

  • 코드의 간결성

    데이터 변경이 발생할 때마다 새로운 데이터가 생성되므로, 이전 상태를 쉽게 추적할 수 있습니다.

  • 모듈화와 재사용성

    공통 로직을 별도의 함수로 분리하여 여러 곳에서 재사용할 수 있습니다.

1
2
3
4
5
6
7
8
9
10
// 고차 함수의 예
const withLogging = (fn) => {
  return (...args) => {
    console.log("Arguments:", args);
    return fn(...args);
  };
};

const addWithLogging = withLogging((a, b) => a + b);
console.log(addWithLogging(2, 3)); // Arguments: [2, 3] 이후 5 반환

이러한 함수형 프로그래밍의 특징으로 인해 코드의 안정성을 보장하는 동시에, 코드의 가독성, 유지보수성을 크게 향상시킬 수 있게 되었습니다.

프론트엔드의 함수형 프로그래밍

Desktop View

출처: Freepik - macrovector 작가

컴포넌트의 재사용성

React는 함수형 프로그래밍의 개념을 많이 차용한 프론트엔드 라이브러리입니다. 특히 함수형 컴포넌트와 hook은 함수형 프로그래밍의 장점을 잘 보여줍니다.

이는 코드의 중복을 줄이고, 기능을 모듈화하며, 확장성을 높이는 데 기여합니다.

  • 함수형 컴포넌트

    함수형 컴포넌트는 순수 함수처럼 동작하며, 입력(props)에 따라 출력(UI)을 반환합니다.

    1
    2
    
    // 함수형 컴포넌트의 예
    const Greeting = ({ name }) => <h1>Hello, {name}!</h1>;
    
  • Hook

    Hook은 함수형 컴포넌트에서 상태와 생명주기 기능을 사용할 수 있게 해줍니다. 특히 useStateuseEffect hook은 함수형 프로그래밍의 불변성부작용 관리 개념을 잘 반영하고 있습니다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    
    // useState와 useEffect hook의 예
    import React, { useState, useEffect } from "react";
    
    const Counter: React.FC = () => {
      const [count, setCount] = useState<number>(0);
    
      useEffect(() => {
        document.title = `Count: ${count}`;
      }, [count]);
    
      return (
        <div>
          <p>{count}</p>
          <button onClick={() => setCount(count + 1)}>Increment</button>
        </div>
      );
    };
    

불변성과 상태 관리

프론트엔드 애플리케이션에서 상태 관리는 매우 중요한 문제입니다. 이는 일반적인 코드 내의 전역 변수의 역할을 담당하기 때문에 함부로 변경되어선 안됩니다. 이러한 이유로 웬만한 프론트엔드 애플리케이션 내에는 상태 관리 라이브러리를 사용하게 됩니다.

  • 상태 관리 라이브러리

    상태를 불변 객체로 관리하며, 상태를 변경할 때는 새로운 상태 객체를 반환합니다.

마치며

Desktop View

출처: https://bluebirdinternational.com/frontend-frameworks/

지금까지 함수형 프로그래밍 그리고 프론트엔드의 채택 계기에 대해 살펴보았는데요, 개인적인 의견으로는 패러다임의 변화는 React가 가장 큰 원인이지 않았을까 싶습니다.

2024년 기준 React가 프론트엔드 프레임워크 시장에서 승리하게 되었고, 그만큼 가장 큰 커뮤니티를 보유하고 있기 때문입니다.

이로 인해 새로운 라이브러리나 AI 툴 역시 함수형 컴포넌트를 기반으로 코드가 제공됩니다.

앞으로도 새로운 개념이 우리를 힘들게(?) 만들겠지만 과거에 비해 더 좋은 기술을 활용하고 배울 수 있음에 기뻐하겠습니다 XD

레퍼런스

This post is licensed under CC BY 4.0 by the author.