Pure function thoả hai điều kiện:
1. Cùng input luôn cho cùng output.
2. Không có side effect — không sửa gì bên ngoài phạm vi của nó.
// pure
const add = (a, b) => a + b
const addItem = (arr, item) => [...arr, item] // trả mảng MỚI
// impure — sửa tham số truyền vào
const push = (arr, item) => { arr.push(item); return arr }
// impure — phụ thuộc trạng thái ngoài
let rate = 0.1
const tax = (amount) => amount * rate
// impure — output đổi theo thời điểm
const id = () => Date.now()Lợi ích thực tế:
- Test không cần mock — gọi hàm, so kết quả, hết.
- Cache được (memoization) vì cùng input là cùng output.
- Dễ lần bug — lỗi chỉ có thể nằm trong input hoặc thân hàm, không đến từ nơi khác.
Trong React, đây không phải lời khuyên mà là yêu cầu: component và reducer phải pure, nếu không Strict Mode (gọi hai lần) và concurrent rendering sẽ lộ ra hành vi sai.
// reducer: KHÔNG được sửa state cũ
function reducer(state, action) {
return { ...state, count: state.count + 1 } // đúng
// state.count++; return state // sai — React không thấy thay đổi
}Chốt: không thể viết chương trình toàn pure — gọi API, ghi DB, in log đều là side effect.
Mục tiêu là đẩy side effect ra lớp ngoài cùng (event handler, effect, tầng service) và giữ phần logic ở giữa pure.