기존에 수행한 연산의 결과값을 어딘가에 저장해두고 동일한 입력이 들어오면 재활용하는 기법
중복 연산을 방지해주기 때문에 애플리케이션의 성능 최적화
메모이제이션된 값을 반환하는 함수
deps로 지정한 값이 변화게되면 함수를 실행하고, 함수의 반환 값을 반환해줌
useMemo는 deps값이 변하면 함수를 실행하는것이라면 이건
export default functino App() {
const [ex, setEx] = useState(0);
const [why, setWhy] = useStatue(0);
1) useMemo(()-> {console.log(ex), [deps]});
2) console.log(ex)
return (
<>
<button onClick=>{()=>setEx((curr1=>curr1+1))}>X</button>
<button onClick=>{()=>setWhy((curr2=>curr2+1))}>Y</button>
</>
)
}
메모이제이션된 함수를 반환함
useCallback 은 함수를 반환하기 때문에 그 함수를 가지는 const 변수에 초기화하는 것이 일반적
자식 컴포넌트에 props로 함수를 전달하는 경우
외부에서 값을 가져오는 API를 호출하는 경우
const sampleFunction1 = function() { return 5 }
const sampleFunction2 = function() { return 5 }
console.log(sampleFunction1 === sampleFunction2)
// 함수는 참조값으로 비교하기떄문에 false
function App() {
const [name, setName] = useState('')
const onSave = () => {};
return (
<div className="App">
<input
type="text"
value={name}
onChange={(e)=>setName(e.target.valu)}
/>
<Profile onSave={onSave} />
</div>
)
}
function App() {
const [name, setName] = useState('')
const onSave = useCallback(() => {
console.log(name);
},[name]);
return (
<div className="App">
<input
type="text"
value={name}
onChange={(e)=>setName(e.target.valu)}
/>
<Profile onSave={onSave} />
</div>
)
}
function Profile({userId}) {
const [user, setUser] = useState(null);
const fetchUser = () => {
fetch('url')
.then((response)=> response.json())
.then(({user})=>user);
}
useEffect(()=>{
fetchUser().then((user)=>setUser(user));
},[fetchUser])
}
위의 코드는 fetchUser함수가 변경될때만 외부에서 API를 가져와 useEffect가 실행된다.
여기서 문제점은 Profile이라는 컴포넌트가 리렌더링이 발생할 경우 fetchUser가 실행되고, 다시 user상태값이 바뀌어 다시 리렌더링이 일어나서 무한루프에 빠지게 됨
useCallvack을 사용하여 fetchUser 함수의 참조값을 동일하게 유지시킴
function Profile({userId}) {
const [user, setUser] = useState(null);
const fetchUser = useCallback(() => {
fetch('url')
.then((response)=> response.json())
.then(({user})=>user);
},[userId]);
useEffect(()=>{
fetchUser().then((user)=>setUser(user));
},[fetchUser])
}