π§± λ λλ§ μ½λ°± μ§μ₯: λΆνμν 리λ λλ§κ³Ό μμΈ‘ λΆκ°λ₯ν λΆμμ©, π₯ μ±λ₯ λ³λͺ©
Summary
μ»΄ν¬λνΈ λ λλ§ μ κ³Όλν μ½λ°± ν¨μ μμ± λ° μ λ¬μ λΆνμν 리λ λλ§κ³Ό side effectλ₯Ό μ λ°νμ¬ μ±λ₯ μ νμ μμΈμ΄ λ©λλ€. useCallback
, μ»΄ν¬λνΈ λΆλ¦¬, μν κ΄λ¦¬ λΌμ΄λΈλ¬λ¦¬ νμ©, ν¨μν μ
λ°μ΄νΈ λ±μ ν΅ν΄ ν΄κ²°ν μ μμ΅λλ€.
Why Wrong?
React μ»΄ν¬λνΈ λ΄μμ render
ν¨μ λλ ν¨μν μ»΄ν¬λνΈ λ΄λΆμμ κ³Όλνκ² μ½λ°± ν¨μλ₯Ό μμ±νκ³ propsλ‘ μ λ¬νλ κ²μ μ¬κ°ν μ±λ₯ λ¬Έμ λ₯Ό μΌκΈ°ν μ μμ΅λλ€. λ§€ λ λλ§λ§λ€ μλ‘μ΄ ν¨μκ° μμ±λλ―λ‘, Reactμ memo
, useMemo
, useCallback
λ±μ μ΅μ ν κΈ°λ²μ΄ 무λ ₯νλ©λλ€. μ΄λ νμ μ»΄ν¬λνΈκ° props λ³νλ₯Ό κ°μ§νκ³ λΆνμνκ² λ¦¬λ λλ§λλλ‘ λ§λ€λ©°, λ λμκ° μ½λ°± λ΄μμ side effectκ° λ°μν κ²½μ° μμΈ‘ λΆκ°λ₯ν λμμ μ΄λν μ μμ΅λλ€. νΉν 볡μ‘ν UI ꡬ쑰μμλ μ΄λ¬ν ν¨ν΄μ΄ μ 체 μ ν리μΌμ΄μ
μ μ±λ₯μ μ νμν€λ μ£Όλ²μ΄ λ©λλ€.
How to Fix?
useCallback
ν νμ©: μ½λ°± ν¨μκ° μμ‘΄νλ κ°(dependencies)μ΄ λ³κ²½λμ§ μλ ν, λμΌν ν¨μ μΈμ€ν΄μ€λ₯Ό μ¬μ¬μ©νλλ‘useCallback
ν μ μ¬μ©ν©λλ€. μ΄λ κ² νλ©΄ νμ μ»΄ν¬λνΈκ° λΆνμνκ² λ¦¬λ λλ§λλ κ²μ λ°©μ§ν μ μμ΅λλ€.- μ»΄ν¬λνΈ λΆλ¦¬ λ° Props μ΅μ ν: λ λλ§ μ½λ°±μ μ¬μ©νλ μ»΄ν¬λνΈλ₯Ό λΆλ¦¬νκ³ , νμν propsλ§ μ λ¬ν©λλ€.
React.memo
λ₯Ό μ¬μ©νμ¬ propsκ° λ³κ²½λμ§ μμ κ²½μ° λ¦¬λ λλ§μ λ§μ μ μμ΅λλ€. - μν κ΄λ¦¬ λΌμ΄λΈλ¬λ¦¬ νμ©: μ μ μν κ΄λ¦¬ λΌμ΄λΈλ¬λ¦¬(Redux, Zustand λ±)λ₯Ό μ¬μ©νμ¬ μ»΄ν¬λνΈ κ°μ μν 곡μ λ° μ λ°μ΄νΈλ₯Ό ν¨μ¨μ μΌλ‘ κ΄λ¦¬ν©λλ€. μ½λ°± ν¨μλ₯Ό ν΅ν΄ μνλ₯Ό μ λ°μ΄νΈνλ λμ , μ‘μ μ λμ€ν¨μΉνμ¬ μνλ₯Ό λ³κ²½νκ³ , μ»΄ν¬λνΈλ μν λ³νμ λ°λΌ μλμΌλ‘ μ λ°μ΄νΈλλλ‘ ν©λλ€.
- ν¨μν μ λ°μ΄νΈ: μν μ λ°μ΄νΈ μ ν¨μν μ λ°μ΄νΈ λ°©μμ μ¬μ©νμ¬ μ΄μ μνμ μμ νκ² μ κ·Όνκ³ μ λ°μ΄νΈν©λλ€. μ΄λ κ² νλ©΄ ν΄λ‘μ λ‘ μΈν λ¬Έμ λ₯Ό μλ°©νκ³ , μ΅μ νλ μν μ λ°μ΄νΈλ₯Ό μνν μ μμ΅λλ€.
Before Code (Bad)
import React, { useState } from 'react';
const MyComponent = () => {
const [count, setCount] = useState(0);
// λ λλ§ μλ§λ€ μλ‘μ΄ ν¨μκ° μμ±λ¨
const handleClick = () => {
setCount(count + 1);
};
return (
<div>
<button onClick={handleClick}>Increment</button>
<ChildComponent onClick={handleClick} />
</div>
);
};
const ChildComponent = React.memo(({ onClick }) => {
console.log('ChildComponent rendered'); // λΆνμνκ² μμ£Ό λ λλ§λ¨
return <button onClick={onClick}>Increment in Child</button>;
});
export default MyComponent;
After Code (Good)
import React, { useState, useCallback } from 'react';
const MyComponent = () => {
const [count, setCount] = useState(0);
// useCallbackμ μ¬μ©νμ¬ ν¨μ μΈμ€ν΄μ€ μ¬μ¬μ©
const handleClick = useCallback(() => {
setCount(prevCount => prevCount + 1);
}, []); // μμ‘΄μ± λ°°μ΄μ΄ λΉμ΄μμΌλ―λ‘, μ»΄ν¬λνΈκ° λ§μ΄νΈλ λ ν λ²λ§ μμ±λ¨
return (
<div>
<button onClick={handleClick}>Increment</button>
<ChildComponent onClick={handleClick} />
</div>
);
};
const ChildComponent = React.memo(({ onClick }) => {
console.log('ChildComponent rendered'); // countκ° λ³κ²½λμ΄λ 리λ λλ§λμ§ μμ
return <button onClick={onClick}>Increment in Child</button>;
});
export default MyComponent;