Как использовать React.memo и useCallback
В этой статье расскажу о том когда и как использовать React.memo и хук useCallback. После этой статьи поймете в каких случаях используют useCallback. Узнаете как работает между собой React.Memo и useCallback.
Кратко о React.memo и useCallback
React.Memo — компонент высшего порядка. Похож на React.PureComponent, но предназначен для функциональных компонентов.
Вторым аргументом React.Memo есть возможность передать функцию которая будет принимать решение ре-рендерить компонент на основе предыдущих и нынешних props
Компонент высшего порядка — функция принимает дочерний компонент и параметры, и затем создаёт контейнер поверх дочернего компонента.
React.PureComponent — схож с React.Component, но единственная разница в методе shouldComponentUpdate.
В PureComponent сравнивает новые значения с предыдущими и возвращает результат сравнения. React.Component — возвращает true
useCallback — хук вернёт мемоизированную функцию колбэка, который изменяется только, если изменяются значения из зависимостей.
Примеры использования
Base — не использует React.Memo. Компонент будет рендерится каждый раз
let count = 0
export default function Base({ action }) {
console.log(`${++count} Base component`)
return <h3 onClick={action}>Base</h3>
}
Memo — использует React.Memo. Компонент будет рендерится каждый раз когда меняются свойства
let count = 0
export default React.memo(function Memo({ action }) {
console.log(`${++count} Memo component`)
return <h3 onClick={action}>Memo</h3>
})
NoUseCallback — не используем useCallback. Рендерится Base и Memo компоненты каждый раз
export default function NoUseCallback() {
const [a, setA] = useState('')
const [b, setB] = useState('')
useEffect(() => {
setTimeout(() => {
console.log('change value not related to action')
setA('a')
}, 1000)
setTimeout(() => {
console.log('change value related to action')
setB('b')
}, 3000)
}, [])
const action = () => console.log(b)
return (
<>
<Base action={action} />
<Memo action={action} />
</>
);
}
Console:
1 Base component
1 Memo component
change value not related to action
2 Base component
2 Memo component
change value related to action
3 Base component
3 Memo component
UseCallback — используем useCallback метод. Рендерится Base 3 и Memo 2 раза
export default function UseCallback() {
const [a, setA] = useState('')
const [b, setB] = useState('')
useEffect(() => {
setTimeout(() => {
console.log('change value not related to action')
setA('a')
}, 1000)
setTimeout(() => {
console.log('change value related to action')
setB('b')
}, 3000)
}, [])
const action = useCallback(() => {
console.log(b)
}, [b]);
return (
<>
<Memo action={action} />
<Base action={action} />
</>
);
}
Console:
1 Memo component
1 Base component
change value not related to action
2 Base component
change value related to action
2 Memo component
3 Base component
Заключение
Используем React.Memo когда хотим что бы компонент ререндерился когда меняются props или конкретные props.
Оборачиваем функцию в useCallback когда передаем другим компонентам или когда используются внешние переменные