Reactμ μΌκ΄ μν μ λ°μ΄νΈλ₯Ό λ§μ€ν°νμ¬ μ±λ₯μ ν¬κ² ν₯μμν€μΈμ. Reactκ° μν λ³κ²½μ μλμΌλ‘ κ·Έλ£Ήννκ³ , μ΄λ₯Ό νμ©νμ¬ λ λΆλλ½κ³ λΉ λ₯Έ μ¬μ©μ κ²½νμ μ 곡νλ λ°©λ²μ μμ보μΈμ.
React μΌκ΄ μν μ λ°μ΄νΈ: μ±λ₯ μ΅μ νλ μν λ³κ²½
λΉ λ₯΄κ² λ³ννλ νλ μΉ κ°λ° μΈκ³μμλ λ§€λλ½κ³ λ°μμ΄ λΉ λ₯Έ μ¬μ©μ κ²½νμ μ 곡νλ κ²μ΄ κ°μ₯ μ€μν©λλ€. React κ°λ°μμκ² μμ΄ μνλ₯Ό ν¨μ¨μ μΌλ‘ κ΄λ¦¬νλ κ²μ μ΄ λͺ©νλ₯Ό λ¬μ±νκΈ° μν μ΄μμ λλ€. Reactκ° μ±λ₯μ μ΅μ ννκΈ° μν΄ μ¬μ©νλ κ°μ₯ κ°λ ₯νλ©΄μλ λλ‘λ μ€ν΄λ°λ λ©μ»€λμ¦ μ€ νλκ° λ°λ‘ μν λ°°μΉ(state batching)μ λλ€. Reactκ° μ¬λ¬ μν μ λ°μ΄νΈλ₯Ό ν¨κ» κ·Έλ£Ήννλ λ°©λ²μ μ΄ν΄νλ©΄ μ ν리μΌμ΄μ μ μ±λ₯μ ν¬κ² ν₯μμμΌ λ λΆλλ¬μ΄ UIμ μ λ°μ μΌλ‘ λ λμ μ¬μ©μ κ²½νμ μ 곡ν μ μμ΅λλ€.
Reactμ μν λ°°μΉλ 무μμΈκ°?
ν΅μ¬μ μΌλ‘, μν λ°°μΉλ λμΌν μ΄λ²€νΈ νΈλ€λ¬λ λΉλκΈ° μμ λ΄μμ λ°μνλ μ¬λ¬ μν μ λ°μ΄νΈλ₯Ό λ¨μΌ 리λ λλ§μΌλ‘ κ·Έλ£Ήννλ Reactμ μ λ΅μ λλ€. κ° κ°λ³ μν λ³κ²½μ λν΄ μ»΄ν¬λνΈλ₯Ό 리λ λλ§νλ λμ , Reactλ μ΄λ¬ν λ³κ²½ μ¬νλ€μ λͺ¨μμ ν λ²μ λͺ¨λ μ μ©ν©λλ€. μ΄λ λΆνμν 리λ λλ§ νμλ₯Ό ν¬κ² μ€μ¬μ£Όλ©°, μ΄λ μ’ μ’ μ ν리μΌμ΄μ μ±λ₯μ λ³λͺ© νμμ΄ λκ³€ ν©λλ€.
ν΄λ¦νμ λ λ κ°μ κ°λ³ μνλ₯Ό μ λ°μ΄νΈνλ λ²νΌμ΄ μλ μλ리μ€λ₯Ό μκ°ν΄ 보μΈμ. λ°°μΉκ° μλ€λ©΄ Reactλ μΌλ°μ μΌλ‘ 첫 λ²μ§Έ μν μ λ°μ΄νΈ ν ν λ², λ λ²μ§Έ μν μ λ°μ΄νΈ ν λ ν λ², μ΄ λ λ²μ κ°λ³ 리λ λλ§μ νΈλ¦¬κ±°ν©λλ€. λ°°μΉλ₯Ό μ¬μ©νλ©΄ Reactλ κ°κΉκ² λ°μνλ μ΄λ¬ν μ λ°μ΄νΈλ€μ μ§λ₯μ μΌλ‘ κ°μ§νκ³ λ¨μΌ 리λ λλ§ μ£ΌκΈ°λ‘ ν΅ν©ν©λλ€. μ΄λ μ»΄ν¬λνΈμ μλͺ μ£ΌκΈ° λ©μλ(λλ ν¨μν μ»΄ν¬λνΈμ λλ±ν κΈ°λ₯)κ° λ μ κ² νΈμΆλκ³ UIκ° λ ν¨μ¨μ μΌλ‘ μ λ°μ΄νΈλλ€λ κ²μ μλ―Έν©λλ€.
λ°°μΉκ° μ±λ₯μ μ€μν μ΄μ λ 무μμΈκ°?
리λ λλ§μ Reactκ° μνλ propsμ λ³κ²½ μ¬νμ λ°μνμ¬ UIλ₯Ό μ λ°μ΄νΈνλ μ£Όμ λ©μ»€λμ¦μ λλ€. νμμ μ΄μ§λ§, κ³Όλνκ±°λ λΆνμν 리λ λλ§μ λ€μκ³Ό κ°μ λ¬Έμ λ₯Ό μΌκΈ°ν μ μμ΅λλ€:
- CPU μ¬μ©λ μ¦κ°: κ° λ¦¬λ λλ§μ Reactκ° μ΄μ κ°μ DOMκ³Ό νμ¬ κ°μ DOMμ λΉκ΅νμ¬ μ€μ DOMμμ 무μμ μ λ°μ΄νΈν΄μΌ ν μ§ κ²°μ νλ μ‘°μ (reconciliation) κ³Όμ μ ν¬ν¨ν©λλ€. 리λ λλ§μ΄ λ§μμλ‘ λ λ§μ κ³μ°μ΄ νμν©λλ€.
- λλ¦° UI μ λ°μ΄νΈ: λΈλΌμ°μ κ° μ»΄ν¬λνΈλ₯Ό μμ£Ό 리λ λλ§νλλΌ λ°μ λ, μ¬μ©μ μνΈ μμ©, μ λλ©μ΄μ λ° κΈ°ν μ€μν μμ μ μ²λ¦¬ν μκ°μ΄ μ€μ΄λ€μ΄ μΈν°νμ΄μ€κ° λ리거λ λ°μμ΄ μλ κ²μ²λΌ λ³΄μΌ μ μμ΅λλ€.
- λ©λͺ¨λ¦¬ μλΉ μ¦κ°: κ° λ¦¬λ λλ§ μ£ΌκΈ°λ μλ‘μ΄ κ°μ²΄μ λ°μ΄ν° ꡬ쑰λ₯Ό μμ±ν μ μμΌλ©°, μκ°μ΄ μ§λ¨μ λ°λΌ λ©λͺ¨λ¦¬ μ¬μ©λμ΄ μ¦κ°ν μ μμ΅λλ€.
μν μ λ°μ΄νΈλ₯Ό λ°°μΉν¨μΌλ‘μ¨ Reactλ μ΄λ¬ν λΉμ©μ΄ λ§μ΄ λλ 리λ λλ§ μμ μ μλ₯Ό ν¨κ³Όμ μΌλ‘ μ΅μννμ¬, νΉν μν λ³κ²½μ΄ μ¦μ 볡μ‘ν μ ν리μΌμ΄μ μμ λ μ±λ₯μ΄ μ’κ³ μ μ°ν μ ν리μΌμ΄μ μ λ§λ€ μ μμ΅λλ€.
Reactκ° μν λ°°μΉλ₯Ό μ²λ¦¬νλ λ°©λ² (μλ λ°°μΉ)
μμ¬μ μΌλ‘ Reactμ μλ μν λ°°μΉλ μ£Όλ‘ ν©μ± μ΄λ²€νΈ νΈλ€λ¬μ κ΅νλμμ΅λλ€. μ¦, ν΄λ¦μ΄λ ν€λ³΄λ μ΄λ²€νΈμ κ°μ λ€μ΄ν°λΈ λΈλΌμ°μ μ΄λ²€νΈ λ΄μμ μνλ₯Ό μ λ°μ΄νΈνλ©΄ Reactκ° ν΄λΉ μ λ°μ΄νΈλ₯Ό λ°°μΉνμ΅λλ€. κ·Έλ¬λ νλ‘λ―Έμ€(promise), `setTimeout` λλ λ€μ΄ν°λΈ μ΄λ²€νΈ 리μ€λμμ λ°μνλ μ λ°μ΄νΈλ μλμΌλ‘ λ°°μΉλμ§ μμ μ¬λ¬ λ²μ 리λ λλ§μ΄ λ°μνμ΅λλ€.
μ΄λ¬ν λμμ React 18μμ λμμ± λͺ¨λ(Concurrent Mode)(νμ¬λ λμμ± κΈ°λ₯μΌλ‘ λΆλ¦Ό)κ° λμ λλ©΄μ ν¬κ² λ³κ²½λμμ΅λλ€. React 18 μ΄μμμλ νλ‘λ―Έμ€, `setTimeout`, λ€μ΄ν°λΈ μ΄λ²€νΈ 리μ€λλ₯Ό ν¬ν¨ν λͺ¨λ λΉλκΈ° μμ μμ νΈλ¦¬κ±°λ μν μ λ°μ΄νΈλ₯Ό κΈ°λ³Έμ μΌλ‘ μλμΌλ‘ λ°°μΉν©λλ€.
React 17 λ° μ΄μ λ²μ : μλ λ°°μΉμ λ―Έλ¬ν μ°¨μ΄
μ΄μ λ²μ μ Reactμμλ μλ λ°°μΉκ° λ μ νμ μ΄μμ΅λλ€. μΌλ°μ μΌλ‘ λ€μκ³Ό κ°μ΄ μλνμ΅λλ€:
- ν©μ± μ΄λ²€νΈ νΈλ€λ¬: μ΄ μμμμ μ λ°μ΄νΈλ λ°°μΉλμμ΅λλ€. μ:
- λΉλκΈ° μμ (νλ‘λ―Έμ€, setTimeout): μ΄ μμμμ μ λ°μ΄νΈλ μλμΌλ‘ λ°°μΉλμ§ μμμ΅λλ€. μ΄λ‘ μΈν΄ κ°λ°μλ€μ μ’ μ’ λΌμ΄λΈλ¬λ¦¬λ νΉμ React ν¨ν΄μ μ¬μ©νμ¬ μλμΌλ‘ μ λ°μ΄νΈλ₯Ό λ°°μΉν΄μΌ νμ΅λλ€.
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
const [value, setValue] = useState(0);
const handleClick = () => {
setCount(c => c + 1);
setValue(v => v + 1);
};
return (
Count: {count}
Value: {value}
);
}
export default Counter;
μ΄ μμ μμ λ²νΌμ ν΄λ¦νλ©΄ onClickμ΄ ν©μ± μ΄λ²€νΈ νΈλ€λ¬μ΄κΈ° λλ¬Έμ λ¨μΌ 리λ λλ§λ§ νΈλ¦¬κ±°λ©λλ€.
import React, { useState } from 'react';
function AsyncCounter() {
const [count, setCount] = useState(0);
const [value, setValue] = useState(0);
const handleAsyncClick = () => {
// This will cause two re-renders in React < 18
setTimeout(() => {
setCount(c => c + 1);
setValue(v => v + 1);
}, 1000);
};
return (
Count: {count}
Value: {value}
);
}
export default AsyncCounter;
React 18 μ΄μ λ²μ μμλ setTimeout μ½λ°±μ΄ μλμΌλ‘ λ°°μΉλμ§ μμκΈ° λλ¬Έμ λ λ²μ κ°λ³ 리λ λλ§μ νΈλ¦¬κ±°νμ΅λλ€. μ΄κ²μ΄ μ±λ₯ λ¬Έμ μ μΌλ°μ μΈ μμΈμ΄μμ΅λλ€.
React 18 μ΄μ: 보νΈμ μΈ μλ λ°°μΉ
React 18μ νΈλ¦¬κ±°μ κ΄κ³μμ΄ λͺ¨λ μ λ°μ΄νΈμ λν΄ μλ λ°°μΉλ₯Ό νμ±ννμ¬ μν λ°°μΉλ₯Ό νμ νμ΅λλ€.
React 18μ ν΅μ¬ μ΄μ :
- μΌκ΄μ±: μν μ λ°μ΄νΈκ° μ΄λ²€νΈ νΈλ€λ¬, νλ‘λ―Έμ€, `setTimeout` λλ λ€λ₯Έ λΉλκΈ° μμ λ± μ΄λμμ μμλλ μκ΄μμ΄ React 18μ μλμΌλ‘ μ΄λ₯Ό λ¨μΌ 리λ λλ§μΌλ‘ λ°°μΉν©λλ€.
React 18μμμ AsyncCounter μμ λ₯Ό λ€μ μ΄ν΄λ³΄κ² μ΅λλ€:
import React, { useState } from 'react';
function AsyncCounterReact18() {
const [count, setCount] = useState(0);
const [value, setValue] = useState(0);
const handleAsyncClick = () => {
// In React 18+, this will cause only ONE re-render.
setTimeout(() => {
setCount(c => c + 1);
setValue(v => v + 1);
}, 1000);
};
return (
Count: {count}
Value: {value}
);
}
export default AsyncCounterReact18;
React 18μμλ μ΄μ setTimeout μ½λ°±μ΄ λ¨ ν λ²μ 리λ λλ§λ§ νΈλ¦¬κ±°ν©λλ€. μ΄λ κ°λ°μμκ² ν° κ°μ μ΄λ©°, μ½λλ₯Ό λ¨μννκ³ μλμΌλ‘ μ±λ₯μ ν₯μμν΅λλ€.
μλμΌλ‘ μ λ°μ΄νΈ λ°°μΉνκΈ° (νμν κ²½μ°)
React 18μ μλ λ°°μΉκ° κ²μ 체μΈμ μ΄κΈ΄ νμ§λ§, λ°°μΉλ₯Ό λͺ
μμ μΌλ‘ μ μ΄ν΄μΌ νκ±°λ μ΄μ React λ²μ μΌλ‘ μμ
νλ λλ¬Έ μλ리μ€κ° μμ μ μμ΅λλ€. μ΄λ¬ν κ²½μ°λ₯Ό μν΄ Reactλ unstable_batchedUpdates ν¨μλ₯Ό μ 곡ν©λλ€ (νμ§λ§ λΆμμ νλ€λ μ΄λ¦μ κ°λ₯ν λ μλ λ°°μΉλ₯Ό μ νΈνλΌλ κ²μ μκΈ°μμΌ μ€λλ€).
μ€μ μ°Έκ³ : unstable_batchedUpdates APIλ λΆμμ ν κ²μΌλ‘ κ°μ£Όλλ©° ν₯ν React λ²μ μμ μ κ±°λκ±°λ λ³κ²½λ μ μμ΅λλ€. μ£Όλ‘ μλ λ°°μΉμ μμ‘΄ν μ μκ±°λ λ κ±°μ μ½λλ‘ μμ
νλ μν©μ μν κ²μ
λλ€. νμ React 18 μ΄μμ μλ λ°°μΉλ₯Ό νμ©νλ κ²μ λͺ©νλ‘ νμΈμ.
μ΄λ₯Ό μ¬μ©νλ €λ©΄ μΌλ°μ μΌλ‘ react-dom(DOM κ΄λ ¨ μ ν리μΌμ΄μ
μ κ²½μ°)μμ κ°μ Έμ μν μ
λ°μ΄νΈλ₯Ό κ·Έ μμ λνν©λλ€:
import React, { useState } from 'react';
import ReactDOM from 'react-dom'; // Or 'react-dom/client' in React 18+
// If using React 18+ with createRoot, unstable_batchedUpdates is still available but less critical.
// For older React versions, you'd import from 'react-dom'.
function ManualBatchingExample() {
const [count, setCount] = useState(0);
const [value, setValue] = useState(0);
const handleManualBatchClick = () => {
// In older React versions, or if auto-batching fails for some reason,
// you might wrap updates here.
ReactDOM.unstable_batchedUpdates(() => {
setCount(c => c + 1);
setValue(v => v + 1);
});
};
return (
Count: {count}
Value: {value}
);
}
export default ManualBatchingExample;
μ΄λ€ κ²½μ°μ `unstable_batchedUpdates`λ₯Ό μ¬μ ν κ³ λ €ν μ μμκΉμ (μ£Όμν΄μ)?
- λΉ-React μ½λμμ ν΅ν©: Reactμ ν©μ± μ΄λ²€νΈ μμ€ν μ μ°ννλ λΉ-React λΌμ΄λΈλ¬λ¦¬λ 컀μ€ν μ΄λ²€νΈ μμ€ν μ μν΄ μν μ λ°μ΄νΈκ° νΈλ¦¬κ±°λλ λκ·λͺ¨ μ ν리μΌμ΄μ μ React μ»΄ν¬λνΈλ₯Ό ν΅ν©νκ³ μκ³ , React 18 μ΄μ λ²μ μ μ¬μ© μ€μ΄λΌλ©΄ μ΄κ²μ΄ νμν μ μμ΅λλ€.
- νΉμ μλνν° λΌμ΄λΈλ¬λ¦¬: λλλ‘ μλνν° λΌμ΄λΈλ¬λ¦¬κ° μλ λ°°μΉλ₯Ό μ°ννλ λ°©μμΌλ‘ React μνμ μνΈ μμ©ν μ μμ΅λλ€.
κ·Έλ¬λ React 18μ 보νΈμ μΈ μλ λ°°μΉκ° λμ
λλ©΄μ unstable_batchedUpdatesμ νμμ±μ κΈκ²©ν μ€μ΄λ€μμ΅λλ€. νλμ μΈ μ κ·Ό λ°©μμ Reactμ λ΄μ₯ μ΅μ νμ μμ‘΄νλ κ²μ
λλ€.
리λ λλ§κ³Ό λ°°μΉ μ΄ν΄νκΈ°
λ°°μΉλ₯Ό μ§μ μΌλ‘ μ΄ν΄νλ €λ©΄ Reactμμ 무μμ΄ λ¦¬λ λλ§μ νΈλ¦¬κ±°νκ³ λ°°μΉκ° μ΄λ»κ² κ°μ νλμ§ μ΄ν΄νλ κ²μ΄ μ€μν©λλ€.
무μμ΄ λ¦¬λ λλ§μ μ λ°νλκ°?
- μν λ³κ²½: μν μ€μ ν¨μ(μ:
setCount(5))λ₯Ό νΈμΆνλ κ²μ΄ κ°μ₯ μΌλ°μ μΈ νΈλ¦¬κ±°μ λλ€. - Prop λ³κ²½: λΆλͺ¨ μ»΄ν¬λνΈκ° 리λ λλ§λκ³ μμ μ»΄ν¬λνΈμ μλ‘μ΄ propsλ₯Ό μ λ¬νλ©΄ μμ μ»΄ν¬λνΈκ° 리λ λλ§λ μ μμ΅λλ€.
- 컨ν μ€νΈ λ³κ²½: μ»΄ν¬λνΈκ° 컨ν μ€νΈλ₯Ό μ¬μ©νκ³ μ»¨ν μ€νΈ κ°μ΄ λ³κ²½λλ©΄ 리λ λλ§λ©λλ€.
- κ°μ μ
λ°μ΄νΈ: μΌλ°μ μΌλ‘ κΆμ₯λμ§ μμ§λ§,
forceUpdate()λ λͺ μμ μΌλ‘ 리λ λλ§μ νΈλ¦¬κ±°ν©λλ€.
λ°°μΉκ° 리λ λλ§μ λ―ΈμΉλ μν₯:
countμ valueμ μμ‘΄νλ μ»΄ν¬λνΈκ° μλ€κ³ μμν΄ λ³΄μΈμ. λ°°μΉκ° μλ€λ©΄, setCountκ° νΈμΆλ μ§ν setValueκ° νΈμΆλλ©΄(μ: λ³λμ λ§μ΄ν¬λ‘νμ€ν¬λ νμμμμμ), Reactλ λ€μκ³Ό κ°μ΄ μλν μ μμ΅λλ€:
setCountλ₯Ό μ²λ¦¬νκ³ λ¦¬λ λλ§μ μ€μΌμ€ν©λλ€.setValueλ₯Ό μ²λ¦¬νκ³ λ λ€λ₯Έ 리λ λλ§μ μ€μΌμ€ν©λλ€.- 첫 λ²μ§Έ 리λ λλ§μ μνν©λλ€.
- λ λ²μ§Έ 리λ λλ§μ μνν©λλ€.
λ°°μΉλ₯Ό μ¬μ©νλ©΄ Reactλ ν¨κ³Όμ μΌλ‘ λ€μκ³Ό κ°μ΄ μλν©λλ€:
setCountλ₯Ό μ²λ¦¬νκ³ λ³΄λ₯ μ€μΈ μ λ°μ΄νΈ νμ μΆκ°ν©λλ€.setValueλ₯Ό μ²λ¦¬νκ³ νμ μΆκ°ν©λλ€.- νμ¬ μ΄λ²€νΈ 루νλ λ§μ΄ν¬λ‘νμ€ν¬ νκ° λΉμμ§λ©΄(λλ Reactκ° μ»€λ°νκΈ°λ‘ κ²°μ νλ©΄), Reactλ ν΄λΉ μ»΄ν¬λνΈ(λλ κ·Έ μ‘°μ)μ λν λͺ¨λ 보λ₯ μ€μΈ μ λ°μ΄νΈλ₯Ό κ·Έλ£Ήννκ³ λ¨μΌ 리λ λλ§μ μ€μΌμ€ν©λλ€.
λμμ± κΈ°λ₯μ μν
React 18μ λμμ± κΈ°λ₯μ 보νΈμ μΈ μλ λ°°μΉμ μλλ ₯μ λλ€. λμμ± λ λλ§μ ν΅ν΄ Reactλ λ λλ§ μμ μ μ€λ¨, μΌμ μ€μ§ λ° μ¬κ°ν μ μμ΅λλ€. μ΄ κΈ°λ₯μ Reactκ° DOMμ μ λ°μ΄νΈλ₯Ό 컀λ°νλ λ°©λ²κ³Ό μμ μ λν΄ λ μ§λ₯μ μΌλ‘ λμ²ν μ μκ² ν΄μ€λλ€. λ λλ§μ΄ λ¨μΌμ λΈλ‘νΉ νλ‘μΈμ€κ° μλλΌ λ μΈλΆνλκ³ μ€λ¨ κ°λ₯νκ² λμ΄, Reactκ° UIμ 컀λ°νκΈ° μ μ μ¬λ¬ μ λ°μ΄νΈλ₯Ό ν΅ν©νκΈ°κ° λ μ¬μμ§λλ€.
Reactκ° λ λλ§μ μννκΈ°λ‘ κ²°μ νλ©΄, λ§μ§λ§ μ»€λ° μ΄ν λ°μν λͺ¨λ 보λ₯ μ€μΈ μν μ λ°μ΄νΈλ₯Ό μ΄ν΄λ΄ λλ€. λμμ± κΈ°λ₯μ μ¬μ©νλ©΄ λ©μΈ μ€λ λλ₯Ό μ₯μκ° μ°¨λ¨νμ§ μκ³ μ΄λ¬ν μ λ°μ΄νΈλ₯Ό λ ν¨κ³Όμ μΌλ‘ κ·Έλ£Ήνν μ μμ΅λλ€. μ΄κ²μ΄ λΉλκΈ° μ λ°μ΄νΈμ μλ λ°°μΉλ₯Ό λ·λ°μΉ¨νλ κ·Όλ³Έμ μΈ λ³νμ λλ€.
μ€μ©μ μΈ μμ λ° μ¬μ© μ¬λ‘
μν λ°°μΉλ₯Ό μ΄ν΄νκ³ νμ©νλ κ²μ΄ μ μ΅ν λͺ κ°μ§ μΌλ°μ μΈ μλ리μ€λ₯Ό μ΄ν΄λ³΄κ² μ΅λλ€:
1. μ¬λ¬ μ λ ₯ νλκ° μλ νΌ
μ¬μ©μκ° νΌμ μμ±ν λ, κ° ν€ μ λ ₯μ ν΄λΉ μ λ ₯ νλμ λν μν λ³μλ₯Ό μ λ°μ΄νΈνλ κ²½μ°κ° λ§μ΅λλ€. 볡μ‘ν νΌμμλ μ΄λ‘ μΈν΄ λ§μ κ°λ³ μν μ λ°μ΄νΈμ μ μ¬μ μΈ λ¦¬λ λλ§μ΄ λ°μν μ μμ΅λλ€. κ°λ³ μ λ ₯ μ λ°μ΄νΈλ Reactμ μ°¨μ΄ λΉκ΅ μκ³ λ¦¬μ¦(diffing algorithm)μ μν΄ μ΅μ νλ μ μμ§λ§, λ°°μΉλ μ λ°μ μΈ λ³λμ μ€μ΄λ λ° λμμ΄ λ©λλ€.
import React, { useState } from 'react';
function UserProfileForm() {
const [name, setName] = useState('');
const [email, setEmail] = useState('');
const [age, setAge] = useState(0);
// In React 18+, all these setState calls within a single event handler
// will be batched into one re-render.
const handleNameChange = (e) => setName(e.target.value);
const handleEmailChange = (e) => setEmail(e.target.value);
const handleAgeChange = (e) => setAge(parseInt(e.target.value, 10) || 0);
// A single function to update multiple fields based on event target
const handleInputChange = (event) => {
const { name, value } = event.target;
if (name === 'name') setName(value);
else if (name === 'email') setEmail(value);
else if (name === 'age') setAge(parseInt(value, 10) || 0);
};
return (
);
}
export default UserProfileForm;
React 18 μ΄μμμλ μ΄λ¬ν νλ μ€ νλμ λν κ° ν€ μ λ ₯μ΄ μν μ λ°μ΄νΈλ₯Ό νΈλ¦¬κ±°ν©λλ€. κ·Έλ¬λ μ΄λ€μ λͺ¨λ λμΌν ν©μ± μ΄λ²€νΈ νΈλ€λ¬ μ²΄μΈ λ΄μ μκΈ° λλ¬Έμ Reactκ° μ΄λ₯Ό λ°°μΉν©λλ€. λ³λμ νΈλ€λ¬κ° μλλΌλ λμΌν μ΄λ²€νΈ 루νμ ν΄ λ΄μμ λ°μνλ©΄ React 18μ μ¬μ ν μ΄λ₯Ό λ°°μΉν©λλ€.
2. λ°μ΄ν° κ°μ Έμ€κΈ° λ° μ λ°μ΄νΈ
λ°μ΄ν°λ₯Ό κ°μ Έμ¨ ν μλ΅μ λ°λΌ μ¬λ¬ μν λ³μλ₯Ό μ λ°μ΄νΈνλ κ²½μ°κ° λ§μ΅λλ€. λ°°μΉλ μ΄λ¬ν μμ°¨μ μ λ°μ΄νΈκ° 리λ λλ§μ νλ°μ μΌμΌν€μ§ μλλ‘ λ³΄μ₯ν©λλ€.
import React, { useState, useEffect } from 'react';
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const fetchUserData = async () => {
try {
// Simulate API call
await new Promise(resolve => setTimeout(resolve, 1500));
const response = await fetch(`https://api.example.com/users/${userId}`);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
// In React 18+, these updates are batched into a single re-render.
setUser(data);
setIsLoading(false);
setError(null);
} catch (err) {
setError(err.message);
setIsLoading(false);
setUser(null);
}
};
fetchUserData();
}, [userId]);
if (isLoading) {
return Loading user data...;
}
if (error) {
return Error: {error};
}
if (!user) {
return No user data available.;
}
return (
{user.name}
Email: {user.email}
{/* Other user details */}
);
}
export default UserProfile;
μ΄ `useEffect` ν μμ λΉλκΈ° λ°μ΄ν° κ°μ Έμ€κΈ° λ° μ²λ¦¬ ν `setUser`, `setIsLoading`, `setError`λΌλ μΈ κ°μ§ μν μ λ°μ΄νΈκ° λ°μν©λλ€. React 18μ μλ λ°°μΉ λλΆμ μ΄ μΈ κ°μ§ μ λ°μ΄νΈλ λ°μ΄ν°κ° μ±κ³΅μ μΌλ‘ κ°μ Έμ€κ±°λ μ€λ₯κ° λ°μν ν λ¨ ν λ²μ UI 리λ λλ§λ§ νΈλ¦¬κ±°ν©λλ€.
3. μ λλ©μ΄μ λ° μ ν
μκ°μ λ°λΌ μ¬λ¬ μν λ³κ²½μ ν¬ν¨νλ μ λλ©μ΄μ (μ: μμμ μμΉ, λΆν¬λͺ λ, ν¬κΈ° μ λλ©μ΄μ )μ ꡬνν λ, λ°°μΉλ λΆλλ¬μ΄ μκ°μ μ νμ 보μ₯νλ λ° μ€μν©λλ€. κ° μμ μ λλ©μ΄μ λ¨κ³κ° 리λ λλ§μ μ λ°νλ€λ©΄ μ λλ©μ΄μ μ΄ λλ λκΈ°λ κ²μ²λΌ λ³΄μΌ κ²μ λλ€.
μ μ© μ λλ©μ΄μ λΌμ΄λΈλ¬λ¦¬λ μ’ μ’ μ체 λ λλ§ μ΅μ νλ₯Ό μ²λ¦¬νμ§λ§, Reactμ λ°°μΉλ₯Ό μ΄ν΄νλ©΄ μ¬μ©μ μ§μ μ λλ©μ΄μ μ λ§λ€κ±°λ ν΅ν©ν λ λμμ΄ λ©λλ€.
import React, { useState, useEffect, useRef } from 'react';
function AnimatedBox() {
const [position, setPosition] = useState({ x: 0, y: 0 });
const [opacity, setOpacity] = useState(1);
const animationFrameId = useRef(null);
const animate = () => {
setPosition(currentPos => {
const newX = currentPos.x + 5;
const newY = currentPos.y + 5;
// If we reach the end, stop the animation
if (newX > 200) {
// Cancel the next frame request
if (animationFrameId.current) {
cancelAnimationFrame(animationFrameId.current);
}
// Optionally fade out
setOpacity(0);
return currentPos;
}
// In React 18+, setting position and opacity here
// within the same animation frame processing turn
// will be batched.
// Note: For very rapid, sequential updates within the *same* animation frame,
// direct manipulation or ref updates might be considered, but for typical
// 'animate in steps' scenarios, batching is powerful.
return { x: newX, y: newY };
});
};
useEffect(() => {
// Start animation on mount
animationFrameId.current = requestAnimationFrame(animate);
return () => {
// Cleanup: cancel animation frame if component unmounts
if (animationFrameId.current) {
cancelAnimationFrame(animationFrameId.current);
}
};
}, []); // Empty dependency array means this runs once on mount
return (
);
}
export default AnimatedBox;
μ΄ λ¨μνλ μ λλ©μ΄μ μμ μμλ `requestAnimationFrame`μ΄ μ¬μ©λ©λλ€. React 18μ `animate` ν¨μ λ΄μμ λ°μνλ μν μ λ°μ΄νΈλ₯Ό μλμΌλ‘ λ°°μΉνμ¬, λ°μ€κ° λ μ μ 리λ λλ§μΌλ‘ μμ§μ΄κ³ μ μ¬μ μΌλ‘ μ¬λΌμ§κ² ν¨μΌλ‘μ¨ λ λΆλλ¬μ΄ μ λλ©μ΄μ μ κΈ°μ¬ν©λλ€.
μν κ΄λ¦¬ λ° λ°°μΉλ₯Ό μν λͺ¨λ² μ¬λ‘
- React 18+ μ¬μ©νκΈ°: μ νλ‘μ νΈλ₯Ό μμνκ±°λ μ κ·Έλ μ΄λν μ μλ€λ©΄ React 18λ‘ μ΄μ νμ¬ λ³΄νΈμ μΈ μλ λ°°μΉμ μ΄μ μ λ리μΈμ. μ΄κ²μ΄ μν μ λ°μ΄νΈμ κ΄λ ¨λ μ±λ₯ μ΅μ νλ₯Ό μν΄ μ·¨ν μ μλ κ°μ₯ μ€μν λ¨κ³μ λλ€.
- νΈλ¦¬κ±° μ΄ν΄νκΈ°: μν μ λ°μ΄νΈκ° μ΄λμμ μ€λμ§ νμ νμΈμ. ν©μ± μ΄λ²€νΈ νΈλ€λ¬ λ΄μ μλ€λ©΄ μ΄λ―Έ λ°°μΉλ κ°λ₯μ±μ΄ λμ΅λλ€. μ΄μ λΉλκΈ° 컨ν μ€νΈμ μλ€λ©΄ μ΄μ React 18μ΄ μ²λ¦¬ν κ²μ λλ€.
- ν¨μν μ
λ°μ΄νΈ μ νΈνκΈ°: μλ‘μ΄ μνκ° μ΄μ μνμ μμ‘΄ν λ ν¨μν μ
λ°μ΄νΈ νμ(μ:
setCount(prevCount => prevCount + 1))μ μ¬μ©νμΈμ. μ΄λ νΉν λΉλκΈ° μμ λ° λ°°μΉμ κ΄λ ¨νμ¬ μ΅μ μν κ°μΌλ‘ μμ νλ κ²μ 보μ₯νλ―λ‘ μΌλ°μ μΌλ‘ λ μμ ν©λλ€. - νμνμ§ μμ ν μλ λ°°μΉ νΌνκΈ°:
unstable_batchedUpdatesλ μμΈμ μΈ κ²½μ°μ λ κ±°μ μ½λλ₯Ό μν΄ λ¨κ²¨λμΈμ. μλ λ°°μΉμ μμ‘΄νλ©΄ λ μ μ§λ³΄μνκΈ° μ½κ³ λ―Έλμλ μ¬μ© κ°λ₯ν μ½λκ° λ©λλ€. - μ ν리μΌμ΄μ νλ‘νμΌλ§νκΈ°: React κ°λ°μ λꡬ νλ‘νμΌλ¬λ₯Ό μ¬μ©νμ¬ κ³Όλνκ² λ¦¬λ λλ§λλ μ»΄ν¬λνΈλ₯Ό μλ³νμΈμ. λ°°μΉκ° λ§μ μλ리μ€λ₯Ό μ΅μ ννμ§λ§, λΆμ μ ν λ©λͺ¨μ΄μ μ΄μ μ΄λ prop λ릴λ§κ³Ό κ°μ λ€λ₯Έ μμΈλ€λ μ¬μ ν μ±λ₯ λ¬Έμ λ₯Ό μΌμΌν¬ μ μμ΅λλ€. νλ‘νμΌλ§μ μ νν λ³λͺ© μ§μ μ μ°Ύλ λ° λμμ΄ λ©λλ€.
- κ΄λ ¨ μν κ·Έλ£ΉννκΈ°: κ΄λ ¨ μνλ₯Ό λ¨μΌ κ°μ²΄λ‘ κ·Έλ£Ήννκ±°λ 볡μ‘ν μν κ³μΈ΅ ꡬ쑰λ₯Ό μν΄ μ»¨ν μ€νΈ/μν κ΄λ¦¬ λΌμ΄λΈλ¬λ¦¬λ₯Ό μ¬μ©νλ κ²μ κ³ λ €νμΈμ. κ°λ³ μν μ€μ μ λ°°μΉμ μ§μ μ μΈ κ΄λ ¨μ μμ§λ§, μν μ λ°μ΄νΈλ₯Ό λ¨μννκ³ νμν κ°λ³ `setState` νΈμΆ μλ₯Ό μ€μΌ μ μμ΅λλ€.
μΌλ°μ μΈ ν¨μ κ³Ό μ΄λ₯Ό νΌνλ λ°©λ²
- React λ²μ 무μνκΈ°: λͺ¨λ React λ²μ μμ λ°°μΉκ° λμΌνκ² μλνλ€κ³ κ°μ νλ©΄ μ€λλ μ½λλ² μ΄μ€μμ μκΈ°μΉ μμ λ€μ€ 리λ λλ§μ΄ λ°μν μ μμ΅λλ€. νμ μ¬μ© μ€μΈ React λ²μ μ μΌλμ λμΈμ.
- λκΈ°μκ³Ό μ μ¬ν μ λ°μ΄νΈμ `useEffect` κ³Όλνκ² μμ‘΄νκΈ°: `useEffect`λ λΆμ ν¨κ³Όλ₯Ό μν κ²μ΄μ§λ§, `useEffect` λ΄μμ λκΈ°μμ²λΌ λκ»΄μ§λ λΉ λ₯΄κ³ λ°μ νκ² κ΄λ ¨λ μν μ λ°μ΄νΈλ₯Ό νΈλ¦¬κ±°νλ κ²½μ°, λ μ λ°°μΉλ μ μλμ§ κ³ λ €ν΄ λ³΄μΈμ. React 18μ΄ μ¬κΈ°μ λμμ΄ λμ§λ§, μν μ λ°μ΄νΈμ λ Όλ¦¬μ κ·Έλ£Ήνλ μ¬μ ν μ€μν©λλ€.
- νλ‘νμΌλ¬ λ°μ΄ν° μ€ν΄νκΈ°: νλ‘νμΌλ¬μμ μ¬λ¬ μν μ λ°μ΄νΈκ° 보μ΄λ κ²μ΄ λ¨μΌ 컀λ°μΌλ‘ μ¬λ°λ₯΄κ² λ°°μΉλμλ€λ©΄ νμ λΉν¨μ¨μ μΈ λ λλ§μ μλ―Ένλ κ²μ μλλλ€. λ¨μν μν μ λ°μ΄νΈ μ보λ€λ 컀λ°(리λ λλ§) μμ μ§μ€νμΈμ.
- `componentDidUpdate` λλ `useEffect` λ΄μμ νμΈ μμ΄ `setState` μ¬μ©νκΈ°: ν΄λμ€ μ»΄ν¬λνΈμμ μ μ ν 쑰건 νμΈ μμ΄ `componentDidUpdate`λ `useEffect` λ΄μμ `setState`λ₯Ό νΈμΆνλ©΄ λ°°μΉ κΈ°λ₯μ΄ μλλΌλ 무ν 리λ λλ§ λ£¨νμ λΉ μ§ μ μμ΅λλ€. μ΄λ₯Ό λ°©μ§νκΈ° μν΄ νμ 쑰건μ ν¬ν¨νμΈμ.
κ²°λ‘
μν λ°°μΉλ Reactμ κ°λ ₯ν λ΄λΆ μ΅μ ν κΈ°λ₯μΌλ‘, μ ν리μΌμ΄μ μ±λ₯μ μ μ§νλ λ° μ€μν μν μ ν©λλ€. React 18μμ 보νΈμ μΈ μλ λ°°μΉκ° λμ λ¨μ λ°λΌ, κ°λ°μλ€μ μ΄μ λ€μν λΉλκΈ° μμ€μμ λ°μνλ μ¬λ¬ μν μ λ°μ΄νΈκ° μ§λ₯μ μΌλ‘ λ¨μΌ 리λ λλ§μΌλ‘ κ·Έλ£Ήνλλ―λ‘ ν¨μ¬ λ λΆλλ½κ³ μμΈ‘ κ°λ₯ν κ²½νμ λ릴 μ μμ΅λλ€.
λ°°μΉκ° μλνλ λ°©μμ μ΄ν΄νκ³ ν¨μν μ λ°μ΄νΈ μ¬μ© λ° React 18μ κΈ°λ₯ νμ©κ³Ό κ°μ λͺ¨λ² μ¬λ‘λ₯Ό μ±νν¨μΌλ‘μ¨, λ λ°μμ΄ λΉ λ₯΄κ³ ν¨μ¨μ μ΄λ©° μ±λ₯μ΄ λ°μ΄λ React μ ν리μΌμ΄μ μ ꡬμΆν μ μμ΅λλ€. νμ μ ν리μΌμ΄μ μ νλ‘νμΌλ§νμ¬ μ΅μ νλ₯Ό μν νΉμ μμμ μλ³νλ, Reactμ λ΄μ₯ λ°°μΉ λ©μ»€λμ¦μ΄ μλ²½ν μ¬μ©μ κ²½νμ μΆκ΅¬νλ λ° μμ΄ μ€μν λλ§Ήμμ νμ νμΈμ.
React κ°λ° μ¬μ μ κ³μνλ©΄μ μ΄λ¬ν μ±λ₯μ λ―Έλ¬ν μ°¨μ΄μ μ£Όμλ₯Ό κΈ°μΈμ΄λ κ²μ μμ¬ν μ¬μ§μμ΄ μ¬μ©μκ° μΈκ³ μ΄λμ μλ μ ν리μΌμ΄μ μ νμ§κ³Ό μ¬μ©μ λ§μ‘±λλ₯Ό λμ¬μ€ κ²μ λλ€.