1. 일반 함수 → 화살표 함수
function add(a, b) {
return a + b
}
const add2 = (a, b) => a + b
console.log(add2(10, 20)) // 30
기초 함수 → 배열 처리 → 불변성 → 고차 함수 → 실무 데이터 처리 → React 상태 패턴 순서로 정리.
function add(a, b) {
return a + b
}
const add2 = (a, b) => a + b
console.log(add2(10, 20)) // 30
const double = num => num * 2
console.log(double(10)) // 20
const createUser = name => ({
name: name,
active: true
})
console.log(createUser('홍길동')) // { name: '홍길동', active: true }
const createNumbers = () => [1, 2, 3]
console.log(createNumbers()) // [1, 2, 3]
const greet = (name = '사용자') => {
return `안녕하세요 ${name}`
}
console.log(greet()) // '안녕하세요 사용자'
const sum = (...numbers) => {
return numbers.reduce((acc, num) => acc + num, 0)
}
console.log(sum(1, 2, 3, 4)) // 10
const arr1 = [1, 2]
const arr2 = [...arr1, 3]
console.log(arr2) // [1, 2, 3]
const user = {
name: '철수',
age: 30
}
const newUser = {
...user,
age: 31
}
console.log(newUser) // { name: '철수', age: 31 }
const numbers = [1, 2, 3]
const result = numbers.map(num => num * 2)
console.log(result) // [2, 4, 6]
const users = [
{ name: '철수' },
{ name: '영희' }
]
const result = users.map(user => ({
...user,
active: true
}))
console.log(result) // [{ name: '철수', active: true }, { name: '영희', active: true }]
const users = [
{ id: 1, name: '철수' },
{ id: 2, name: '영희' }
]
const names = users.map(user => user.name)
console.log(names) // ['철수', '영희']
const numbers = [1, 2, 3, 4, 5]
const result = numbers.filter(num => num >= 3)
console.log(result) // [3, 4, 5]
const users = [
{ id: 1, name: '철수' },
{ id: 2, name: '영희' }
]
const result = users.filter(user => user.id !== 1)
console.log(result) // [{ id: 2, name: '영희' }]
const users = [
{ id: 1, name: '철수' },
{ id: 2, name: '영희' }
]
const user = users.find(user => user.id === 2)
console.log(user) // { id: 2, name: '영희' }
const users = [
{ id: 10 },
{ id: 20 },
{ id: 30 }
]
const index = users.findIndex(user => user.id === 20)
console.log(index) // 1
const numbers = [1, 3, 5, 8]
const hasEven = numbers.some(num => num % 2 === 0)
console.log(hasEven) // true
const numbers = [10, 20, 30]
const result = numbers.every(num => num >= 10)
console.log(result) // true
const roles = ['admin', 'user']
console.log(roles.includes('admin')) // true
const prices = [1000, 2000, 3000]
const total = prices.reduce(
(sum, price) => sum + price,
0
)
console.log(total) // 6000
const users = [
{ id: 1, name: '철수' },
{ id: 2, name: '영희' }
]
const result = users.reduce((acc, user) => {
acc[user.id] = user
return acc
}, {})
console.log(result) // { 1: { id: 1, name: '철수' }, 2: { id: 2, name: '영희' } }
const users = ['철수', '영희']
const result = [...users, '민수']
console.log(result) // ['철수', '영희', '민수']
const users = ['철수', '영희']
const result = ['민수', ...users]
console.log(result) // ['민수', '철수', '영희']
const numbers = [1, 2, 3, 4]
const result = numbers.filter(num => num !== 2)
console.log(result) // [1, 3, 4]
const users = [
{ id: 1, name: '철수' },
{ id: 2, name: '영희' }
]
const result = users.map(user =>
user.id === 2
? { ...user, name: '민지' }
: user
)
console.log(result) // [{ id: 1, name: '철수' }, { id: 2, name: '민지' }]
const user = {
name: '철수',
age: 30
}
const result = {
...user,
age: 40
}
console.log(result) // { name: '철수', age: 40 }
const user = {
name: '철수',
profile: {
age: 30,
city: '서울'
}
}
const result = {
...user,
profile: {
...user.profile,
age: 31
}
}
console.log(result) // { name: '철수', profile: { age: 31, city: '서울' } }
const users = [
{ id: 1, active: true }
]
const result = users.map(user =>
user.id === 1
? { ...user, active: !user.active }
: user
)
console.log(result) // [{ id: 1, active: false }]
const deleteIds = [1, 3]
const users = [
{ id: 1 },
{ id: 2 },
{ id: 3 },
{ id: 4 }
]
const result = users.filter(
user => !deleteIds.includes(user.id)
)
console.log(result) // [{ id: 2 }, { id: 4 }]
const targetIds = [1, 3]
const users = [
{ id: 1, active: false },
{ id: 2, active: false },
{ id: 3, active: false }
]
const result = users.map(user =>
targetIds.includes(user.id)
? { ...user, active: true }
: user
)
console.log(result) // [{ id: 1, active: true }, { id: 2, active: false }, { id: 3, active: true }]
const user = {
id: 1,
name: '철수',
password: '1234'
}
const { password, ...safeUser } = user
console.log(safeUser) // { id: 1, name: '철수' }
const name = 'age'
const value = 40
const user = {
name: '철수',
age: 30
}
const result = {
...user,
[name]: value
}
console.log(result) // { name: '철수', age: 40 }
// React에서 자주 쓰는 형태
setForm(prev => ({
...prev,
[e.target.name]: e.target.value
}))
const numbers = [1, 1, 2, 2, 3]
const result = [...new Set(numbers)]
console.log(result) // [1, 2, 3]
const users = [
{ id: 1, name: '철수' },
{ id: 1, name: '철수' },
{ id: 2, name: '영희' }
]
const result = users.filter(
(user, index, array) =>
index === array.findIndex(item => item.id === user.id)
)
console.log(result) // [{ id: 1, name: '철수' }, { id: 2, name: '영희' }]
const numbers = [3, 1, 2]
const result = [...numbers].sort((a, b) => a - b)
console.log(result) // [1, 2, 3]
console.log(numbers) // [3, 1, 2] (원본 유지)
const numbers = [1, 2, 3]
const result = [...numbers].reverse()
console.log(result) // [3, 2, 1]
const numbers = [10, 20, 30]
const result = numbers.map(
(num, index) => index === 1 ? 100 : num
)
console.log(result) // [10, 100, 30]
const a = [1, 2]
const b = [3, 4]
const result = [...a, ...b]
console.log(result) // [1, 2, 3, 4]
const user = { name: '철수' }
const profile = { age: 30 }
const result = {
...user,
...profile
}
console.log(result) // { name: '철수', age: 30 }
const isAdmin = true
const user = {
name: '철수',
...(isAdmin && {
role: 'admin'
})
}
console.log(user) // { name: '철수', role: 'admin' }
const isAdmin = true
const menu = [
'홈',
'게시판',
...(isAdmin ? ['관리자'] : [])
]
console.log(menu) // ['홈', '게시판', '관리자']
const calculate = (a, b, callback) => {
return callback(a, b)
}
const add = (a, b) => a + b
console.log(calculate(10, 20, add)) // 30
const createMultiplier = num => {
return value => value * num
}
const double = createMultiplier(2)
console.log(double(10)) // 20
const run = callback => {
callback()
}
run(() => {
console.log('실행') // '실행' (1회)
})
const repeat = (count, callback) => {
for (let i = 0; i < count; i++) {
callback(i)
}
}
repeat(3, index => {
console.log(index) // 0, 1, 2 (순서대로 출력)
})
const double = num => num * 2
const numbers = [1, 2, 3]
const result = numbers.map(double)
console.log(result) // [2, 4, 6]
const isAdult = user => user.age >= 20
const users = [
{ age: 18 },
{ age: 30 },
{ age: 15 }
]
const result = users.filter(isAdult)
console.log(result) // [{ age: 30 }]
const ascending = (a, b) => a - b
const numbers = [3, 1, 2]
console.log([...numbers].sort(ascending)) // [1, 2, 3]
const sumReducer = (total, num) => total + num
const numbers = [1, 2, 3]
const total = numbers.reduce(sumReducer, 0)
console.log(total) // 6
const numbers = [1, 2, 3]
const result = numbers.map(num => num * 10)
console.log(result) // [10, 20, 30]
// 새 배열을 만들 목적이면 map()이 적합
const add10 = num => num + 10
const double = num => num * 2
const result = double(add10(5))
console.log(result) // 30
const compose =
(f, g) =>
value =>
f(g(value))
const double = n => n * 2
const add10 = n => n + 10
const calculate = compose(double, add10)
console.log(calculate(5)) // 30
const pipe =
(...functions) =>
value =>
functions.reduce(
(result, fn) => fn(result),
value
)
const add10 = n => n + 10
const double = n => n * 2
const calculate = pipe(add10, double)
console.log(calculate(5)) // 30
const trim = text => text.trim()
const lower = text => text.toLowerCase()
const addPrefix = text => `user_${text}`
const result = addPrefix(
lower(
trim(' JOHN ')
)
)
console.log(result) // user_john
const add =
a =>
b =>
a + b
console.log(add(10)(20)) // 30
const add = a => {
return b => {
return a + b
}
}
const add10 = add(10)
console.log(add10(20)) // 30
const greaterThan =
min =>
value =>
value > min
const greaterThan10 = greaterThan(10)
console.log(greaterThan10(20)) // true
const greaterThan =
min =>
value =>
value > min
const numbers = [5, 15, 20, 3]
const result = numbers.filter(
greaterThan(10)
)
console.log(result) // [15, 20]
const hasProperty =
key =>
object =>
key in object
const hasName = hasProperty('name')
console.log(
hasName({ name: '철수' })
) // true
const multiply = (a, b) => a * b
const double = b => multiply(2, b)
console.log(double(10)) // 20
const createLogger =
prefix =>
message => {
console.log(`[${prefix}]`, message) // '[ERROR] 오류 발생'
}
const errorLogger = createLogger('ERROR')
errorLogger('오류 발생')
const users = [
{ name: '철수', active: true },
{ name: '영희', active: false },
{ name: '민수', active: true }
]
const activeUsers = users.filter(
user => user.active
)
console.log(activeUsers) // [{ name: '철수', active: true }, { name: '민수', active: true }]
const users = [
{ name: '철수' },
{ name: '영희' }
]
const names = users.map(
user => user.name
)
console.log(names) // ['철수', '영희']
const targetId = 2
const users = [
{ id: 1, name: '철수' },
{ id: 2, name: '영희' }
]
const result = users.map(user =>
user.id === targetId
? { ...user, name: '민지' }
: user
)
console.log(result) // [{ id: 1, name: '철수' }, { id: 2, name: '민지' }]
const targetId = 2
const result = users.filter(
user => user.id !== targetId
)
const targetId = 1
const result = users.map(user =>
user.id === targetId
? { ...user, active: !user.active }
: user
)
const users = [
{ id: 1, checked: true },
{ id: 2, checked: false },
{ id: 3, checked: true }
]
const ids = users
.filter(user => user.checked)
.map(user => user.id)
console.log(ids) // [1, 3]
const checkedUsers = users.filter(
user => user.checked
)
const keyword = '철'
const users = [
{ name: '김철수' },
{ name: '이영희' }
]
const result = users.filter(user =>
user.name.includes(keyword)
)
console.log(result) // [{ name: '김철수' }]
const category = 'book'
const products = [
{ name: '책1', category: 'book' },
{ name: '노트북', category: 'pc' }
]
const result = products.filter(
product => product.category === category
)
const products = [
{ price: 10000 },
{ price: 30000 },
{ price: 50000 }
]
const result = products.filter(
product =>
product.price >= 20000 &&
product.price <= 40000
)
console.log(result) // [{ price: 30000 }]
const users = [
{ name: '민수' },
{ name: '철수' },
{ name: '영희' }
]
const result = [...users].sort(
(a, b) => a.name.localeCompare(b.name)
)
console.log(result) // [{ name: '민수' }, { name: '영희' }, { name: '철수' }]
const products = [
{ price: 5000 },
{ price: 1000 },
{ price: 3000 }
]
const result = [...products].sort(
(a, b) => a.price - b.price
)
const posts = [
{ date: '2026-09-03' },
{ date: '2026-09-01' }
]
const result = [...posts].sort(
(a, b) => new Date(b.date) - new Date(a.date)
)
const users = [
{ name: '철수', team: 'A' },
{ name: '영희', team: 'B' },
{ name: '민수', team: 'A' }
]
const grouped = users.reduce((acc, user) => {
if (!acc[user.team]) {
acc[user.team] = []
}
acc[user.team].push(user)
return acc
}, {})
console.log(grouped) // { A: [{ name: '철수', team: 'A' }, { name: '민수', team: 'A' }], B: [{ name: '영희', team: 'B' }] }
const products = [
{ name: '책1', category: 'book' },
{ name: '책2', category: 'book' },
{ name: 'PC', category: 'computer' }
]
const grouped = products.reduce((acc, item) => {
const key = item.category
acc[key] = acc[key] ?? []
acc[key].push(item)
return acc
}, {})
const tasks = [
{ status: 'done' },
{ status: 'done' },
{ status: 'todo' }
]
const count = tasks.reduce((acc, task) => {
acc[task.status] =
(acc[task.status] ?? 0) + 1
return acc
}, {})
console.log(count)
// { done: 2, todo: 1 }
const products = [
{ price: 1000 },
{ price: 2000 },
{ price: 3000 }
]
const total = products.reduce(
(sum, product) => sum + product.price,
0
)
console.log(total) // 6000
const products = [
{ price: 1000, checked: true },
{ price: 2000, checked: false },
{ price: 3000, checked: true }
]
const total = products
.filter(item => item.checked)
.reduce(
(sum, item) => sum + item.price,
0
)
console.log(total) // 4000
const targetId = 2
const cart = [
{ id: 1, count: 1 },
{ id: 2, count: 2 }
]
const result = cart.map(item =>
item.id === targetId
? { ...item, count: item.count + 1 }
: item
)
const targetId = 2
const result = cart.filter(
item => item.id !== targetId
)
setUsers(prev => [
...prev,
{
id: 3,
name: '민수'
}
])
// prev = 현재 users 상태값
setUsers(prev =>
prev.filter(
user => user.id !== targetId
)
)
setUsers(prev =>
prev.map(user =>
user.id === targetId
? {
...user,
name: '홍길동'
}
: user
)
)
setUser(prev => ({
...prev,
age: 40
}))
setActive(prev => !prev)
const [items, setItems] = useState([])
function addItem() {
setItems(prev => [
...prev,
{
id: Date.now(),
name: '새 항목'
}
])
}
function deleteItem(id) {
setItems(prev =>
prev.filter(
item => item.id !== id
)
)
}
function updateItem(id) {
setItems(prev =>
prev.map(item =>
item.id === id
? { ...item, name: '변경' }
: item
)
)
}
const [selectedIds, setSelectedIds] = useState([])
function toggle(id) {
setSelectedIds(prev =>
prev.includes(id)
? prev.filter(item => item !== id)
: [...prev, id]
)
}
// 있으면 filter()로 제거
// 없으면 [...prev, id]로 추가
function Input({ onChange }) {
return (
<input
onChange={e =>
onChange(e.target.value)
}
/>
)
}
// 사용
<Input onChange={setName} />
// 내부적으로 setName(value)가 실행되는 셈
function handleChange(value) {
onChange?.(value)
}
// 아래와 비슷한 의미
if (onChange) {
onChange(value)
}
const [form, setForm] = useState({
name: '',
age: ''
})
function handleChange(e) {
setForm(prev => ({
...prev,
[e.target.name]: e.target.value
}))
}
<input name="name" onChange={handleChange} />
<input name="age" onChange={handleChange} />
const users = [
{ id: 1, name: '철수' },
{ id: 2, name: '영희' }
]
return (
<ul>
{users.map(user => (
<li key={user.id}>
{user.name}
</li>
))}
</ul>
)
return (
<ul>
{users
.filter(user => user.active)
.map(user => (
<li key={user.id}>
{user.name}
</li>
))}
</ul>
)
// 전체 users → filter → 활성 사용자 → map → li 생성
const result = users
.filter(user => user.active)
.toSorted((a, b) => a.age - b.age)
.map(user => user.name)
// 활성회원만 → 나이순 정렬 → 이름만 추출
const upper = text => text.toUpperCase()
const lower = text => text.toLowerCase()
const transform =
type === 'upper'
? upper
: lower
console.log(transform('Hello')) // 'hello' 또는 'HELLO' (type 값에 따라)
function List({
items,
renderItem
}) {
return (
<ul>
{items.map(item => (
<li key={item.id}>
{renderItem(item)}
</li>
))}
</ul>
)
}
<List
items={users}
renderItem={user => (
<strong>{user.name}</strong>
)}
/>
function Parent() {
function handleDelete(id) {
console.log('삭제', id)
}
return (
<Child onDelete={handleDelete} />
)
}
function Child({ onDelete }) {
return (
<button onClick={() => onDelete(10)}>
삭제
</button>
)
}
const activeUsers = useMemo(() => {
return users.filter(
user => user.active
)
}, [users])
// users가 바뀔 때만 다시 계산
// 단순한 filter에는 무조건 쓸 필요 없음
function reducer(state, action) {
switch (action.type) {
case 'ADD':
return [
...state,
action.user
]
case 'DELETE':
return state.filter(
user => user.id !== action.id
)
case 'TOGGLE':
return state.map(user =>
user.id === action.id
? {
...user,
active: !user.active
}
: user
)
default:
return state
}
}
const [users, dispatch] = useReducer(reducer, [])
dispatch({
type: 'ADD',
user: {
id: 1,
name: '철수',
active: true
}
})
dispatch({
type: 'DELETE',
id: 1
})
dispatch({
type: 'TOGGLE',
id: 1
})
전부 외울 필요는 없다. 우선 map, filter, find, some,
includes, spread, 삼항연산자, ?., ??,
setState(prev => ...), 함수 Props 전달 패턴을 자연스럽게 읽는 게 중요하다.
setUsers(prev =>
prev
.filter(user => user.active)
.map(user =>
user.id === targetId
? {
...user,
name: '홍길동'
}
: user
)
)
한글로 읽으면: 현재 users를 가져온다 → active 사용자만 남긴다 → targetId와 같은 사용자는 복사 후 name만 변경한다 → 나머지는 그대로 둔다 → 새 배열을 상태로 저장한다.