Как использовать React.memo и useCallback

Michael Pautov
2 min readJul 1, 2020

--

В этой статье расскажу о том когда и как использовать 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 когда передаем другим компонентам или когда используются внешние переменные

--

--