함수형 프로그래밍(FP)는 계산을 수학 함수의 평가로 취급하고 상태 변경 및 변경 가능한 데이터를 피하는 프로그래밍 패러다임이다.
React와 결합할 때, FP는 예측 가능하고, 모듈식이며, 유지 보수가 가능한 코드로 이어진다.
여기 React 컨텍스트에서의 함수형 프로그래밍 개요가 있다.
함수형 프로그래밍은 프로그래밍 패러다임의 한 종류로, 계산을 수학적 함수의 평가로 취급하고 상태 변경과 가변 데이터를 피하는 것을 중점으로 둡니다. 이 패러다임은 순수 함수를 사용하여 부작용(side effects)을 최소화하며, 데이터 처리를 위해 함수의 조합과 함수 간의 관계를 강조합니다. 결과적으로, 함수형 프로그래밍은 예측 가능하고, 재사용 가능하며, 테스트하기 쉬운 코드를 작성하도록 돕습니다.
계산을 수학적 함수의 평가로 취급한다."함수형 프로그래밍의 역사"는 컴퓨터 과학과 프로그래밍 언어의 발전과 밀접하게 연결되어 있으며, 수학적 이론과 실제 컴퓨팅의 필요 사이의 간극을 메우는 데 중요한 역할을 해왔다.
함수형 프로그래밍과 객체 지향 프로그래밍은 각기 다른 문제 해결 방식과 프로그래밍 접근 방식을 제공한다.
객체 지향 프로그래밍이 널리 사용되기 시작한 것은 1970년대부터이며, 데이터와 데이터를 조작하는 방법을 하나의 '객체'에 캡슐화하는 것에 중점을 두었다.
이 접근 방식은 소프트웨어 엔지니어링, 특히 대규모 시스템에서 코드의 재사용성, 확장성 및 관리 용이성을 향상시키는 데 큰 도움이 되었다.
그러나 객체 지향 프로그래밍이 일부 문제를 해결하는 데 탁월했음에도 불구하고, 다음과 같은 여러 문제를 완전히 해결하지 못했다
이러한 문제를 해결하고자, 함수형 프로그래밍이 주목받기 시작했다.
함수형 프로그래밍은 다음과 같은 이점을 제공한다.
또한, 오늘날의 애플리케이션은 높은 수준의 병행성과 비동기 처리를 요구하는데, 함수형 프로그래밍은 이러한 복잡성을 추상화하고 코드의 안정성을 향상시키는 데 도움을 준다.
요약하자면, 객체 지향 프로그래밍과 함수형 프로그래밍은 서로 다른 접근 방식과 장단점을 가지고 있다.
많은 현대적인 언어는 이 두 패러다임을 결합하여, 개발자가 상황에 가장 적합한 도구를 선택할 수 있도록 한다.

웹 개발, 특히 React에서 함수형 프로그래밍이 각광받게 된 이유는 여러 가지가 있다.
React의 주요 개념과 함수형 프로그래밍의 원칙 사이에는 많은 연관성이 있기 때문에, 이 두 방식이 자연스럽게 어우러지는 경향이 있다.
이러한 이유로, 함수형 프로그래밍 패러다임은 React와 같은 웹 개발 환경에서 빠르게 인기를 얻고 있으며, 효율적이고 유지 보수가 용이한 애플리케이션을 만드는데 도움이 된다.
훅(Hooks) 도입 전, React의 함수형 컴포넌트는 상태가 없었다.
그들은 오직 props만을 받아들이고 JSX만을 반환했다.
하지만 훅의 도입으로 함수형 컴포넌트는 여전히 함수형 원리를 고수하면서 상태와 사이드 이펙트를 가질 수 있는 능력을 얻었다.
예시 :
import React from "react";
const Greeting = (props) => <h1>안녕하세요, {props.name}님!</h1>;
export default Greeting;
생성자와 this.setState를 가진 클래스 컴포넌트를 사용하는 대신에, 함수형 컴포넌트에서 useState훅을 사용할 수 있다.
import React, { useState } from "react";
const Counter = () => {
const [count, setCount] = useState(0);
return (
<div>
<p>카운트: {count}</p>
<button onClick={() => setCount(count + 1)}>증가</button>
</div>
);
};
componentDidMount, componentDidUpdate, componentWillUnmount 같은 생명주기 메서드를 대체한다.
import React, { useState, useEffect } from "react";
const Timer = () => {
const [seconds, setSeconds] = useState(0);
useEffect(() => {
const interval = setInterval(() => {
setSeconds((prev) => prev + 1);
}, 1000);
return () => clearInterval(interval); // 정리 함수
}, []); // 의존성 배열이 비어 있으면 초기 렌더링 후 한 번 실행됩니다
return <div>경과 시간: {seconds}초</div>;
};
React의 재렌더링 과정은 불변 데이터 구조의 사용으로 이점을 얻습니다.
Immutable.js와 같은 라이브러리나 스프레드 연산자(...)와 같은 유틸리티를 활용함으로써 데이터가 불변하게 유지되는 것을 보장할 수 있다.
이것들은 컴포넌트를 취하고 추가 props 또는 변경된 행동을 가진 새로운 컴포넌트를 반환하는 함수들이다.
function withLogger(WrappedComponent) {
return function LoggerComponent(props) {
console.log("Props:", props);
return <WrappedComponent {...props} />;
};
}
React에서 함수형 프로그래밍 경험을 향상시켜주는 몇 가지 라이브러리가 있다.
함수형 프로그래밍 원칙을 React 개발에 통합함으로써 더 읽기 쉽고, 유지 보수가 가능하며, 테스트 가능한 코드로 이어진다.
React가 계속 발전함에 따라, 함수형 프로그래밍 개념과의 조화는 웹 어플리케이션을 구축하는데 있어 확장 가능하고 효율적인 방법을 보장한ㄷ.

순수 함수란 사이드 이펙트가 없는 함수, 즉 함수의 실행이 외부에 영향을 끼치지 않는 함수를 뜻하고, 입력으로 전달된 값을 수정하지 않는 불변성을 가지고 있습니다.
따라서 순수함수는 어떠한 전달인자가 주어지더라도 항상 똑같은 값이 리턴됨을 보장한다.
함수의 입력 외에도 함수의 결과에 영향을 미치는 요인, 대표적으로 네트워크 요청, API 호출이 Side Effect이다.
사이드 이펙트를 줄이고, 모듈화 수준을 높이는 함수형 프로그래밍의 특징, 즉 순수함수는 평가 시점이 무관하다는 특징으로 인해 효율적인 로직을 구성할 수 있다.
순수함수를 만들기 위해 데이터의 불변성을 유지하는 것은 중요하다.
함수의 전달인자로 참조 자료형이 전달되면 의도치 않게 해당 객체 자체를 바꾸는 사이드 이펙트를 만들 수 있는데 이는 해당 데이터의 불변성을 손상시킨다.
따라서 배열의 불변성을 보장하는 메소드 map, filter, reduce 등을 사용하기도 한다.
함수형 프로그래밍의 이점들을 활용해 로직을 구현하고, 컨셉을 이해하기 위해 일급 함수에 대해 먼저 알아보자.
// ✅ 일급 함수는 변수에 함수를 담을 수 있다.
const foo = function (a) {
return a * a;
};
console.log(foo);
// ƒ (a) {
// return a * a;
// }
// ✅ 변수 끝에 괄호 ()를 사용해서 함수를 호출할 수 있다.
const foo = function (a) {
return a * a;
};
console.log(foo(3));
// 9
위 예제를 보면 변수 foo에 함수를 할당하고 출력해보면 함수가 담긴 것을 확인할 수 있다.
변수를 사용하여 끝에 괄호 ()를 추가하면 함수를 호출할 수 있다.
// ✅ f1 함수에게 인자로 함수를 전달하였다.
function f1(f) {
return f(); // 인자로 받은 함수를 평가(수행)
}
console.log(
f1(function () {
return 10;
})
);
// 10
위 예제의 f1 함수는 인자로 함수를 받아서 함수 내부에서 함수를 평가한 다음 그 결과를 리턴하는 함수(일급 함수)이다.
따라서 f1()은 어떤 함수를 인자로 넘겼느냐에 따라 결과값이 결정 될 것이다.(순수 함수)
다른 함수(f1)에 인자로 전달된 함수(익명 함수)를 콜백 함수라고 한다. 위 예제에선 익명 함수(10을 리턴)가 콜백 함수이다.
일급 함수라는 개념과 순수 함수라는 개념을 이용해서 함수의 조합성을 높여 나가는 것이 함수형 프로그래밍이다.
다시 말해 언제 평가해도 상관 없는 순수 함수들을 만들고, 그 순수 함수들을 값(변수)으로 들고 다니면서 적절한 시점(필요한 시점)에 평가를 하는 방식으로 다양한 로직을 만들어 나가는 것이 함수형 프로그래밍인 것이다.
// ✅ 함수를 리턴하는 함수
// a라는 값을 받고 a라는 값을 알고 있는 컨텍스트의 함수를 정의한 후 리턴한다.
function addMaker(a) {
return function (b) {
// 클로저
return a + b;
};
}
// 결국 addMaker 함수를 호출하면 a라는 값을 기억하는 클로저가 된다.
// 따라서 변수 add10은 10의 값을 기억하는 클로저이다.
const add10 = addMaker(10);
// 10(a) + 20(b) = 30
console.log(add10(20)); // 30
// 15의 값을 기억하는 클로저
const add15 = addMaker(15);
// 15(a) + 20(b) = 35
console.log(add15(20)); // 35
위 예제의 addMaker 함수는 일급 함수의 개념과 클로저의 개념이 함께 사용된 함수이다. 함수를 값처럼 취급하기 때문에 함수 또한 리턴 할 수 있다.
함수를 리턴하는 함수를 고차 함수라고 부른다.
여기서 주의할 점은 위 예제의 클로저는 순수 함수도 된다는 점이다. a라는 매개변수는 클로저 내부에서 참조만 할 뿐 a라는 값을 직접 변경하지 않는다. 그리고 외부 어느 곳에서도 a가 존재하지 않는다.
그래서 위 예제의 클로저는 항상 동일한 값을 가리키고 있는 a라는 값에 b를 더하는 순수 함수이다. 결국 addMaker()를 통해 만든 add10이나 add15는 어느 시점에 평가를 해도 무관하다(항상 동일한 결과값을 낸다).
위의 예제들은 함수형 프로그래밍으로 작성한 다양한 방식의 코드들을 나타낸다. 함수를 값으로 다루면서 순수 함수를 정의하고, 함수의 평가 시점이 무관해서 다양한 방식으로 작성하는 것. 이것을 함수형 프로그래밍이라고 한다.
함수형 프로그래밍 - https://reactnext-central.xyz/blog/react/functional-programming#google_vignette
순수 함수 - https://dev-ellachoi.tistory.com/54
일급 함수 - https://onlydev.tistory.com/97