π» κ°μ
Re-rendering
μ 리μ‘νΈ
κ° μ»΄ν¬λνΈλ₯Ό μλ‘μ΄ λ°μ΄ν°λ‘ μ
λ°μ΄νΈ νλ κ³Όμ μΌλ‘, μ΄ κ³Όμ μ΄ μμ΄μΌ μν리μΌμ΄μ
μ μ¬μ©μμ νλ(λ²νΌ ν΄λ¦ λ±)μ λ°μνκ²λ λ§λ€ μ μμ΅λλ€.
μ΄ κΈμμλ re-rendering
μ΄ λ°μνλ μ΄μ μ λΆνμν re-rendering
μ λ§μ μ μλ κΈ°λ³Έμ μΈ λ°©λ² λͺκ°μ§λ₯Ό μ΄ν΄λ³΄κ² μ΅λλ€.
π» μ»΄ν¬λνΈμ μλͺ μ£ΌκΈ°
λ³Έ λ΄μ©μ λ€μ΄κ°κΈ° μμ 리μ‘νΈ
μ»΄ν¬λνΈμ μλͺ
μ£ΌκΈ°λ₯Ό λ¨Όμ μμλ³΄κ² μ΅λλ€.
리μ‘νΈ
μ»΄ν¬λνΈμ μλͺ
μ£ΌκΈ°λ μλμ κ°μ΄ ν¬κ² μΈκ°μ§ λ¨κ³λ‘ λ¨μν ν μ μμ΅λλ€.
Mount
Mount
λ¨κ³μμλ μ»΄ν¬λνΈμ μΈμ€ν΄μ€κ° μ΅μ΄λ‘ μμ±λ©λλ€. μ΄λ, μ»΄ν¬λνΈμ μνμ μ΄κΈ°νκ° μΌμ΄λλ©°,hook
λ€μ΄ μ€νλκ³ μμλ€μ΄DOM
μ μΆκ°λ©λλ€.Re-render
κΈ°μ‘΄μ μ‘΄μ¬νκ³ μλ μ»΄ν¬λνΈλ₯Ό μλ‘μ΄ μ λ³΄λ‘ μ λ°μ΄νΈνλ λ¨κ³μ λλ€.
μ΄λ―Έ μμ±λ μΈμ€ν΄μ€λ₯Ό μ¬μ¬μ©νμ§λ§, μ»΄ν¬λνΈ λ΄λΆμ μλhook
λ€κ³Ό λ‘μ§λ€μ μ¬μ€νλ©λλ€.Unmount
Unmount
λ¨κ³λ μ»΄ν¬λνΈμ μΈμ€ν΄μ€μ κ·Έμ κ΄λ ¨λ λͺ¨λ κ²λ€μ΄ μ κ±°λλ λ¨κ³μ λλ€. μ΄ λ¨κ³μμ μμκ°DOM
μμ μ κ±°λ©λλ€.
π» Re-render
μ μμΈ
Re-render
κ° λ°μνλ μ§μ μ μΈ μμΈμ μ»΄ν¬λνΈκ° μμ νκ³ μλ state
κ°μ λ³κ²½μ
λλ€. μ¦ props
μ λ³κ²½μ¬λΆλ νΉμ μν©μ μ μΈνκ³ λ κ³ λ €λμμ΄ μλλλ€.
1
2
3
4
5
const App = () => {
const [counter, setCounter] = useState(0);
return <div onClick={() => setCounter((prev) => prev + 1)}>{counter}</div>;
};
μ μ½λμμ, div
νκ·Έλ₯Ό ν΄λ¦νκ²λλ©΄ setCounter
κ° μ€νλ©λλ€. setCounter
κ° μ€νλλ©΄, counter
μ κ°μ΄ λ³κ²½(state
μ
λ°μ΄νΈ)λκ³ κ·Έλ‘ μΈν΄ state
λ₯Ό μμ ν App
μ»΄ν¬λνΈκ° re-render
κ° λ©λλ€.
App
μ»΄ν¬λνΈμ μ¬λ¬ μ»΄ν¬λνΈκ° μ€μ²©λμ΄ μλ κ²½μ°μλ counter
μ μμ‘΄μ± μ¬λΆμ μκ΄μμ΄ νμμ λͺ¨λ μ»΄ν¬λνΈλ€μ΄ μ°μμ μΌλ‘ re-render
λ©λλ€. λ€μλ§ν΄, re-render
κ° μ΅μ΄λ‘ μμλ μ»΄ν¬λνΈλ₯Ό ν¬ν¨νμ¬ λͺ¨λ νμμ μ»΄ν¬λνΈλ€μ΄ re-render
λ©λλ€.
1
2
3
4
5
6
7
8
9
10
11
const App = () => {
const [counter, setCounter] = useState(0);
return (
<>
<div onClick={() => setCounter((prev) => prev + 1)}>{counter}</div>
<Component1 />
<Component2 counter={counter} />
</>
);
};
App
μ»΄ν¬λνΈμ Component1
, Component2
κ° μ€μ²©λμ΄ μμΌλ©°, Component2
λ counter
λ₯Ό props
λ‘ λ°κ³ μμ΅λλ€. μ΄λ, setCounter
λ₯Ό μ΄μ©νμ¬ counter
λ₯Ό μ
λ°μ΄νΈνκ²λλ©΄, counter
λ°μ΄ν°μ μ¬μ©μ¬λΆμ κ΄κ³μμ΄ Component1
, Component2
κ° λͺ¨λ re-render
λλκ²μ μ μ μμ΅λλ€.
π» λΆνμν re-render
λ§κΈ°
μλμ κ°μ μ½λκ° μλ€κ³ κ°μ ν΄λ³΄κ² μ΅λλ€.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// App
const App = () => {
const [counter, setCounter] = useState(0);
return (
<>
<div onClick={() => setCounter((prev) => prev + 1)}>{counter}</div>
<SlowComponent />
</>
);
};
// SlowComponent
const SlowComponent = () => {
console.log("[ARTIFICIALLY SLOW] Rendering");
let startTime = performance.now();
while (performance.now() - startTime < 500) {
// Do nothing for 500 ms to emulate extremely slow code
}
return null;
};
SlowComponent
λ μλμ μΌλ‘ 500ms
λμ μ½ μ€νμ μ μ ν΄ λ€λ₯Έ μ½λκ° μ€νλμ§ μλλ‘ λ§λ μ½λμ
λλ€. ν΄λΉ μ»΄ν¬λνΈλ₯Ό App
μ»΄ν¬λνΈμ μΆκ°ν ν, counter
λ₯Ό μ
λ°μ΄νΈνκ² λλ©΄, 500ms
λμ re-render
κ° λ°μνμ§ μκ²λ©λλ€.
SlowComponent
λ μ
λ°μ΄νΈλλ counter
μ 무κ΄νμ§λ§, counter
λ₯Ό μμ νκ³ μλ App
μ»΄ν¬λνΈμ μμ μ»΄ν¬λνΈλΌλ μ΄μ λ‘ re-render
κ° λ°μν©λλ€. μ΄λ₯Ό ν΄κ²°ν μ μλ λ°©λ² λκ°μ§λ₯Ό μ΄ν΄λ³΄κ² μ΅λλ€.
π¨βπ» React.memo
μ΅μ΄λ‘ re-render
λ₯Ό λ°μμν€λ μμΈμ state
μ λ³κ²½μ΄λ©°, props
μ λ³κ²½μ 무κ΄ν©λλ€. νμ§λ§, props
μ λ³κ²½μ λΉκ΅ν΄ μμ μ»΄ν¬λνΈλ‘μ re-render
μ μ νλ λ§μ μ μμ΅λλ€.
React.memo
λ₯Ό μ¬μ©ν κ³ μ°¨μ»΄ν¬λνΈλ λΆλͺ¨λ‘ λΆν° μ λ¬λ°μ props
λ€μ μκ² λΉκ΅νλ©°, λ§μ½ νλλΌλ λ³κ²½μ΄ λμλ€λ©΄ re-render
κ° μ νλκ³ κ·Έλ μ§ μμΌλ©΄ re-render
κ° λ©μΆ₯λλ€.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// App
const App = () => {
const [counter, setCounter] = useState(0);
return (
<>
<div onClick={() => setCounter((prev) => prev + 1)}>{counter}</div>
<SlowComponent />
</>
);
};
// SlowComponent
const SlowComponent = memo(() => {
console.log("[ARTIFICIALLY SLOW] Rendering");
let startTime = performance.now();
while (performance.now() - startTime < 500) {
// Do nothing for 500 ms to emulate extremely slow code
}
return null;
});
React.memo
λ‘ κ°μΌ SlowComponent
λ props
κ° λ³νμ§ μμκΈ° λλ¬Έμ, counter
κ° μ
λ°μ΄νΈ λμ΄λ re-render
λμ§ μμΌλ©° μλλ‘ μ νλμ§λ μμ΅λλ€.
π¨βπ» State
λΆλ¦¬νμ¬, μλλ‘ λμ΄ λ΄λ¦¬κΈ°
counter
state
λ div
νκ·Έμμλ§ μ¬μ©λκ³ μκΈ°λλ¬Έμ, μ»΄ν¬λνΈλ‘ λΆλ¦¬ν΄ κ³ λ¦½μν¬ μ μμ΅λλ€.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// App
const App = () => {
return (
<>
<Counter />
<SlowComponent />
</>
);
};
// Counter
const Counter = () => {
const [counter, setCounter] = useState(0);
return <div onClick={() => setCounter((prev) => prev + 1)}>{counter}</div>;
};
// SlowComponent
const SlowComponent = () => {
console.log("[ARTIFICIALLY SLOW] Rendering");
let startTime = performance.now();
while (performance.now() - startTime < 500) {
// Do nothing for 500 ms to emulate extremely slow code
}
return null;
};
μ μ½λλ Counter
μ»΄ν¬λνΈλ₯Ό λΆλ¦¬νμ¬ counter
state
λ₯Ό κ°λλ‘ λ§λ μ½λμ
λλ€. μ΄ κ²½μ°, counter
λ₯Ό μ
λ°μ΄νΈνκ² λλ©΄ Counter
μ»΄ν¬λνΈμμ re-render
κ° μμλλ©° νμ μ»΄ν¬λνΈλ€λ‘ μ νλκ² λ©λλ€. μ¦, SlowComponent
λ re-render
μ 무κ΄ν¨μΌλ‘ React.memo
λ‘ κ°μΈμ§ μμλ λ©λλ€.
μ°Έκ³ μλ£
React re-renders guide: everything, all at once
Skipping re-rendering of components