Рубрики
Без рубрики

UseCallback Hook-это не замена для методов класса, как избежать ререндарных и доступа

Если вы переходите от компонентов React на новый стиль крючков, вы столкнетесь с большой проблемой производительности. USECALLBACK не совсем то же самое, что иметь метод класса, потому что обратный вызов не может получить доступ к состоянию. Вот как избежать замедления вашего приложения .. Tagged with React, JavaScript.

Реакционные крючки действительно крутые. Я конвертировал некоторые библиотеки в крючки, когда я столкнулся с крупной вычеркиванием.

На первый взгляд, следующие компоненты могут выглядеть так же, как и то же самое …

// Class Style

class ClassStyleComponent extends React.Component {

    state = { val: 0 }

    onAdd = () => {
        const { val } = this.state
        this.setState({ val: val + 1 })
    }

    onSubtract = () => {
        const { val } = this.state
        this.setState({ val: val - 1 })
    }

    render() {
        const { val } = this.state
        return (
            
val: {val}
) } } // Hooks Style const NaiveHooksComponent = () => { const [val, changeVal] = useState(0) const onAdd = useCallback(() => changeVal(val + 1), [val]) const onSubtract = useCallback(() => changeVal(val - 1), [val]) return (
val: {val}
) }

Конечно же, эти компоненты функционально делают то же самое, но есть критическая разница в производительности.

Кнопки редернизируются каждый раз, когда VAL меняется на компоненте в стиле крючков, но в компоненте класса кнопки отображаются только один раз!

Причина этого – UseCallback Необходимо воссоздать функцию обратного вызова каждый раз, когда государство меняется. Состояние обратных вызовов компонента класса без создания новой функции.

Вот простое исправление: Рычаг userEducer и использовать государство, переданное к редуктору.

Вот компонент крючков, переписанный так, что кнопки рендеринг только один раз:

const ReducerHooksComponent = () => {
    const [val, incVal] = useReducer((val, delta) => val + delta, 0)
    const onAdd = useCallback(() => incVal(1), [])
    const onSubtract = useCallback(() => incVal(-1), [])

    return (
        
val: {val}
) }

Все исправлено! Кнопки рендеринг только один раз, потому что Onadd и OnSubtract Не меняйся каждый раз val изменения. Вы можете адаптировать это к более сложным вариантам использования, передавая более подробные действия.

Есть немного более сложная техника по Sophiebits Это отлично подходит для обратных вызовов событий. Чтобы использовать его, нам придется определить пользовательский крючок под названием Использовать Eventcallback Анкет

function useEventCallback(fn) {
  let ref = useRef()
  useLayoutEffect(() => {
    ref.current = fn
  })
  return useCallback((...args) => (0, ref.current)(...args), [])
}

// This looks a lot like our intuitive NaiveHooksComponent!
const HooksComponentWithEventCallbacks = () => {
    const [val, changeVal] = useState(0)

    // Swap useCallback for useEventCallback
    const onAdd = useEventCallback(() => changeVal(val + 1))
    const onSubtract = useEventCallback(() => changeVal(val - 1))

    return (
        
val: {val}
) }

Этот пример является тривиальным (кнопки не имеют огромной стоимости рендеринга), но плохая памятка может иметь огромные последствия для производительности при рефактории большого применения.

Приветствия и удачи, приняв крючки!

Оригинал: “https://dev.to/seveibar/usecallback-hook-isnt-a-drop-in-replacement-for-class-methods-how-to-avoid-rerenders-and-access-stateprops-within-usecallback-2nla”