https://react.dev/reference/react/useCallback
https://react.dev/reference/react/useMemo
react-dnd를 사용하여 folder-file 계층구조의 드래그앤드랍 기능을 구현하기 위해.
react-dnd 공식문서에서 안내 된 example에서 memo
및 useMemo
, useCallback
을 사용한 것을 확인하여 이해하기 위해 react 공식문서를 참고하여 번역 및 중요내용을 기록하고자 한다.
// example 1 )
const cachedFn = useCallback(fn, dependencies)
// useEffect에서 사용하는 예 )
import { useCallback } from 'react';
function ProductPage({ productId, referrer, theme }) {
const handleSubmit = useCallback((orderDetails) => {
post('/product/' + productId + '/buy', {
referrer,
orderDetails,
});
}, [productId, referrer]);
// ...
...
// example 1 )
const cachedValue = useMemo(calculateValue, dependencies)
// 2 ) 계산 결과 캐싱 예시
import { useMemo } from 'react';
function TodoList({ todos, tab, theme }) {
// 필터 계산 결과값을 useMemo를 사용하여 캐시(리렌더 간 계산값을 공유)
const visibleTodos = useMemo(() => filterTodos(todos, tab), [todos, tab]);
// ...
}
// 3 ) totdoList.ts
import { useMemo } from 'react';
import { filterTodos } from './utils.js'
export default function TodoList({ todos, theme, tab }) {
const visibleTodos = useMemo(
() => filterTodos(todos, tab),
[todos, tab]
);
return (
<div className={theme}>
<p><b>Note: <code>filterTodos</code> is artificially slowed down!</b></p>
<ul>
{visibleTodos.map(todo => (
<li key={todo.id}>
{todo.completed ?
<s>{todo.text}</s> :
todo.text
}
</li>
))}
</ul>
</div>
);
}
By default, when a component re-renders, React re-renders all of its children recursively. This is why, when TodoList re-renders with a different theme, the List component also re-renders. This is fine for components that don’t require much calculation to re-render. But if you’ve verified that a re-render is slow, you can tell List to skip re-rendering when its props are the same as on last render by wrapping it in memo
-> 해당 함수형 컴포넌트의 props가 직전 리렌더와 동일한 경우, 캐시된 전의 리렌더 결과를 사용.
import { memo } from 'react';
const List = memo(function List({ items }) {
// ...
});
With this change, List will skip re-rendering if all of its props are the same as on the last render.