함수형 프로그래밍 기법은 리액트 뿐 아니라 리액트 생태계를 이루는 여러 라이브러리의 근간이다.
함수가 1급 시민이 되면 변수에 함수를 대입할 수 있고, 함수를 다른 함수에 인자로 넘길 수 있으며, 함수에서 함수를 만들어서 반환할 수 있어야 한다.
자바스크립트에서는 함수가 1급 시민이기 때문에, 자바스크립트가 함수형 프로그래밍을 지원한다고 말할 수 있다. 1급 시민이라는 말은 정수나 문자열 같은 다른 일반적인 값과 마찬가지로 함수를 취급할 수 있다는 뜻이다.
함수를 객체, 배열, 다른 함수의 인자에 넣을 수 있다. 또한, 함수가 함수를 반환할 수 있다.
특히, 함수가 함수를 인자로 받는 경우와 함수가 함수를 반환하는 경우를 고차함수
라고 부른다.
// 위 고차함수를 화살표 함수로 표현
const createScream = logger => message => {
logger(message.toUpperCase() + "!!!");
};
이처럼 함수에 2개 이상의 화살표가 있다면 고차 함수를 사용하고 있다는 뜻이다.
프로그래밍 패러다임을 크게 선언적 프로그래밍
과 명령형 프로그래밍
으로 나눌 수 있다.
함수형 프로그래밍은 선언적 프로그래밍
의 방법 중 하나이다.
선언적(declarative) 프로그래밍
은 명령형(imperative) 프로그래밍
은 코드로 원하는 결과를 달성해 나가는 과정에만 관심을 두는 프로그래밍 스타일이다.함수형 프로그래밍의 핵심 개념으로 불변성(immutability), 순수성(purity), 데이터 변환(transformation), 고차 함수, 재귀(recursion) 등이 있다.
함수형 프로그래밍에서는 데이터가 변할 수 없다.
그래서 원본 데이터 구조를 변경하는 대신 그 데이터 구조의 복사본을 만들되 그중 일부를 변경한다.
그리고 원본 대신 변경한 복사본을 사용해 필요한 작업을 진행한다.
[객체]
const ratecolor = (color, rating) => ({
...color,
rating
});
[배열]
const addColor = (title, list) => [...list, {title}];
순수 함수(Pure Functions)는 파라미터에 의해서만 반환값이 결정되는 함수를 뜻한다. 이는 함수형 프로그램의 핵심 개념 중 하나이다.
순수함수에는 부수 효과(side effect)가 없다.
순수함수 규칙
리액트에서는 UI를 순수 함수로 표현한다.
순수 함수를 사용하면 애플리케이션의 상태에 영향을 미치지 않기 때문에 코딩이 편해진다.
다음은 DOM을 변경하는 순수하지 않는 함수의 예시이다.
function Header(text) {
let h1 = document.createElement('h1');
h1.innerText = text;
document.body.appendChild(h1);
}
Header("안녕");
const Header = (props) => <h1>{props.title}</h1>
자바스크립트 내장 함수를 사용하여 데이터 변환하여 다른 데이터를 만들어낼 수 있다.
새 값을 반환하는 Array.join, Array.filter, Array.map, Array.reduce, Array.reduceRight
고차 함수는 다른 함수를 조작할 수 있는 함수다.
고차함수는 다른 함수를 인자로 받을 수 있거나 함수를 반환할 수 있고, 때로는 그 2가지를 모두 수행한다.
예를 들어, Array.map, Array.filter, Array.reduce는 다른 함수를 인자로 받기 때문에, 모두 고차 함수다.
다른 함수를 반환하는 고차 함수는 자바스크립트에서 비동기적인 실행 맥락을 처리할 때 유용하다. 함수를 반환하는 고차 함수를 쓰면 필요할 대 재활용할 수 있는 함수를 만들 수 있다.
커링(Currying)
은 고차 함수 사용법과 관련한 함수형 프로그래밍 기법이다.재귀는 비동기 프로세스에서도 잘 작동하는 또 다른 함수형 기법이다. 함수는 필요할 때 자기 자신을 다시 호출할 수 있다.
함수형 프로그램은 로직을 구체적인 작업을 담당하는 여러 작은 순수 함수로 나눈다. 그 과정에서 언젠가는 모든 작은 함수를 한데 합칠 필요가 있다.
합성 방법으로 체이닝 등이 있으나, 함수를 더 큰 함수로 조합해주는 compose와 같은 커스텀 함수를 사용할 수 있다.
compose는 여러 함수를 인자로 받아서 한 함수를 결과로 내놓는다.
const compose = (...fns) => (arg) =>
fns.reduce((composed, f) => f(composed), arg);
const funcFirst = (word) => `{${word}}`
const funcSecond = (word) => `[${word}]`
const both = compose(
funcFirst,
funcSecond
);
console.log(both('hello')) // [{hello}]
책 [러닝 리액트]에서 발췌 요약한 내용입니다.