1. React와 함수형 JavaScript의 관계
React가 함수형 프로그래밍 언어인 것은 아니지만, 함수형 프로그래밍의 핵심 아이디어를 매우 많이 활용합니다.
props / state→함수 컴포넌트→JSX
UI = f(state, props)
React에서는 “기존 값을 직접 고친다”보다 “기존 값을 이용해 새로운 값을 만든다”는 사고방식이 중요합니다.
2. 함수 기본 필수
함수 선언식
function add(a, b) {
return a + b
}
화살표 함수
const add = (a, b) => {
return a + b
}
const double = value => value * 2
- 함수 선언식
- 함수 표현식
- 화살표 함수
- 매개변수 / 인자
- return / 암시적 return
- 기본 매개변수
- 나머지 매개변수
...args - 함수를 변수·객체·배열에 저장
- 함수를 다른 함수에 전달
- 함수에서 함수 반환
3. 콜백 함수 최우선
React 이벤트와 배열 메서드는 거의 전부 콜백과 연결됩니다.
function handleClick() {
console.log('click')
}
<button onClick={handleClick}>버튼</button>
setCount(prev => prev + 1)
- 이벤트 콜백
- 익명 콜백
- 화살표 콜백
- map / filter / find / reduce 콜백
- state setter 콜백
- 함수를 props로 전달
4. 배열 메서드 최우선
| 메서드 | 용도 | React 실전 |
|---|---|---|
map() | 각 항목을 다른 값으로 변환 | 목록 렌더링, 특정 객체 수정 |
filter() | 조건에 맞는 항목만 남김 | 삭제, 검색, 카테고리 필터 |
find() | 조건에 맞는 첫 항목 조회 | 선택된 사용자/상품 찾기 |
findIndex() | 조건에 맞는 index 조회 | 특정 위치 찾기 |
reduce() | 하나의 값으로 누적 | 합계, 개수, 그룹화 |
some() | 하나라도 만족 여부 | 선택 여부 확인 |
every() | 전부 만족 여부 | 전체 체크 여부 |
includes() | 포함 여부 | ID 목록 포함 여부 |
slice() | 일부 복사 | 원본 유지하며 일부 추출 |
toSorted() | 원본 변경 없이 정렬 | 불변 정렬 |
flat()/flatMap() | 중첩 배열 평탄화 | API 데이터 변환 |
목록 렌더링
users.map(user => (
<User key={user.id} user={user} />
))
삭제
setUsers(prev =>
prev.filter(user =>
user.id !== targetId
)
)
수정
setUsers(prev =>
prev.map(user =>
user.id === targetId
? { ...user, name: '홍길동' }
: user
)
)
5. 불변성 핵심
React state에서는 기존 배열/객체를 직접 수정하는 방식보다 새 배열/객체를 만들어 반환하는 패턴을 사용합니다.
피하기
users.push(newUser)
users[0].name = '홍길동'
권장 패턴
const nextUsers = [
...users,
newUser
]
const nextUser = {
...user,
name: '홍길동'
}
배열 추가
setUsers(prev => [
...prev,
newUser
])
배열 여러 항목 삭제
setUsers(prev =>
prev.filter(user =>
!deleteIds.includes(user.id)
)
)
boolean 토글
setUsers(prev =>
prev.map(user =>
user.id === targetId
? {
...user,
active: !user.active
}
: user
)
)
6. 구조분해 + Spread/Rest 필수
객체 구조분해
const {
name,
age
} = user
function User({
name,
age
}) {
...
}
배열 구조분해
const [
value,
setValue
] = useState('')
props 나머지 전달
function Button({
children,
className,
...props
}) {
return (
<button
className={className}
{...props}
>
{children}
</button>
)
}
동적 property 변경
setForm(prev => ({
...prev,
[name]: value
}))
7. 조건식과 안전한 값 접근 필수
| 문법 | 예제 | 의미 |
|---|---|---|
| 삼항연산자 | active ? 'on' : 'off' | 둘 중 하나 선택 |
&& | error && <Error /> | 조건부 렌더링 |
?. | user?.profile?.name | null/undefined 안전 접근 |
?? | value ?? '기본값' | null/undefined일 때 기본값 |
| 함수 optional chaining | onChange?.(value) | 함수가 있을 때만 호출 |
Boolean() | Boolean(errorText) | true/false로 변환 |
filter(Boolean) | items.filter(Boolean) | falsy 값 제거 |
8. 고차 함수 중요
함수를 인자로 받거나 함수를 반환하는 함수입니다.
function createHandler(id) {
return () => {
deleteUser(id)
}
}
<button onClick={createHandler(user.id)}>
삭제
</button>
map, filter, find, reduce도 콜백 함수를 인자로 받으므로 대표적인 고차 함수입니다.
9. 클로저 중요
function createHandler(id) {
return () => {
console.log(id)
}
}
바깥 함수가 끝난 뒤에도 내부 함수가 id를 기억할 수 있는 패턴입니다. 이벤트 핸들러, debounce, throttle, Hook 내부 함수 등에서 자주 만납니다.
10. 순수 함수 중요
function double(value) {
return value * 2
}
function getTotal(items) {
return items.reduce(
(sum, item) => sum + item.price,
0
)
}
- 같은 입력이면 같은 출력
- 외부 변수나 원본 데이터를 함부로 변경하지 않음
- 계산/검증/포맷 로직을 컴포넌트 바깥 함수로 분리하기 좋음
11. 파생값 Derived Value React 핵심
const selectedUser =
users.find(
user => user.id === selectedId
)
const activeUsers =
users.filter(user => user.active)
const total =
items.reduce(
(sum, item) => sum + item.price,
0
)
이미 존재하는 state에서 계산 가능한 값은 별도의 state로 만들지 않고 렌더링 과정에서 계산하는 경우가 많습니다.
12. 함수형 State 업데이트 최우선
setCount(prev => prev + 1)
setOpen(prev => !prev)
setUsers(prev => [
...prev,
newUser
])
setUsers(prev =>
prev.filter(user =>
user.id !== targetId
)
)
prev는 현재 state를 기준으로 다음 state를 계산할 때 사용하는 대표적인 함수형 업데이트 패턴입니다.
13. Form에서의 함수형 패턴
const [form, setForm] = useState({
name: '',
age: ''
})
function handleChange(event) {
const { name, value } = event.target
setForm(prev => ({
...prev,
[name]: value
}))
}
- 하나의 객체 state로 폼 관리
- 동적 property 업데이트
- validation 함수 분리
- trim / 숫자 변환 / submit 데이터 가공
- error 객체 생성 및 파생값 처리
14. Hooks와 함수형 사고
| Hook | 함수형 관점 |
|---|---|
useState | 이전 state → 다음 state |
useEffect | 렌더링 외부의 side effect 처리 |
useMemo | 계산 결과 memoization |
useCallback | 함수 참조 memoization |
useReducer | state + action → 새로운 state |
| Custom Hook | 상태/로직을 함수 단위로 재사용 |
Reducer 예제
function reducer(state, action) {
switch (action.type) {
case 'delete':
return state.filter(
user => user.id !== action.id
)
default:
return state
}
}
15. 함수 참조 vs 실행 React 필수
함수 전달
onClick={handleClick}
클릭할 때 React가 호출
함수를 감싸서 인자 전달
onClick={() =>
handleClick(id)
}
onClick={handleClick()}은 렌더링 시점에 함수를 즉시 실행하므로 의미가 다릅니다.16. 데이터 → UI 변환 패턴
원본 데이터→filter→map→JSX
const visibleUsers =
users
.filter(user => user.active)
.map(user => (
<User
key={user.id}
user={user}
/>
))
이처럼 “어떻게 DOM을 하나씩 조작할지”보다 “이 데이터라면 어떤 UI가 나와야 하는지”를 선언하는 방식이 React와 잘 맞습니다.
17. 함수 합성과 로직 분리 중요
const activeUsers =
getActiveUsers(users)
const sortedUsers =
sortUsers(activeUsers)
const visibleUsers =
formatUsers(sortedUsers)
- validation 함수
- formatting 함수
- filtering 함수
- sorting 함수
- API → UI 데이터 변환 함수
- 이벤트 처리 함수 분리
18. 객체·배열 변환 도구
| 도구 | 용도 |
|---|---|
Object.keys() | 객체 key 배열 |
Object.values() | 객체 value 배열 |
Object.entries() | [key, value] 배열 |
Object.fromEntries() | entries 배열 → 객체 |
Set | 중복 제거 |
Map | key-value 데이터 구조 |
Number() | 문자열 → 숫자 |
String() | 값 → 문자열 |
19. 조금 더 깊은 함수형 프로그래밍 개념 나중에
- 일급 함수 First-class Function
- 고차 함수 Higher-order Function
- 순수 함수 Pure Function
- 불변성 Immutability
- 참조 투명성 Referential Transparency
- 함수 합성 Function Composition
- 커링 Currying
- 부분 적용 Partial Application
- 선언형 프로그래밍
- 명령형 vs 선언형
- 부수 효과 Side Effect
- Side Effect 격리
- 재귀 Recursion
- Memoization
- Lazy Evaluation
- Predicate 함수
- Reducer 패턴
- Pipeline 패턴
20. React 학습 우선순위
1순위 — 무조건
- 함수 / 화살표 함수
- 콜백
- map / filter / find
- spread
- 구조분해
- 삼항연산자 / &&
- ?. / ??
- 불변성
- setState(prev => ...)
2순위 — 실력 상승
- reduce
- some / every / includes
- 순수 함수
- 고차 함수
- 클로저
- 파생값
- 함수 props
- controlled component
- 객체/배열 변환
3순위 — 나중에
- 함수 합성
- 커링
- 부분 적용
- 참조 투명성
- 재귀
- Pipeline
- Memoization
- Reducer 이론
- Side Effect 설계
21. React에서 가장 많이 쓰는 6대 실전 패턴
1) 조회
const user =
users.find(user =>
user.id === id
)
2) 필터 / 삭제
const activeUsers =
users.filter(user =>
user.active
)
3) 변환 / 수정
const newUsers =
users.map(user =>
user.id === id
? {
...user,
active: !user.active
}
: user
)
4) 추가
const newUsers = [
...users,
newUser
]
5) 집계
const total =
items.reduce(
(sum, item) =>
sum + item.price,
0
)
6) React state 업데이트
setUsers(prev =>
prev.map(user =>
user.id === id
? {
...user,
active: !user.active
}
: user
)
)
압축 결론: React에서는 특히
map + filter + find + spread + 콜백 + 불변성을 자유롭게 다룰 수 있으면 데이터와 state를 처리하는 코드 대부분이 훨씬 쉽게 읽힙니다.