Вопросы об использовании ловушки обратного вызова и анонимной функции - PullRequest
0 голосов
/ 24 января 2020

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

Пример анонимной функции, о которой я говорил, выглядит следующим образом.

import React, { useState } from 'react';

const Component = () => {
  const [param, setParam] = useState('');
  ...

  return (
    ...
    <SomeComponent
      onClick={() => setParam('parameter')}
      {...others}
    />
  );
}

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

, и я использовал useCallback, как показано ниже.

import React, { useState, useCallback } from 'react';

const Component = () => {
  const [param, setParam] = useState('');

  const handleClick = useCallback((params) => {
    setParam(params);
  },[]);

  ...
  return (
    ...
    <SomeComponent
      onClick={handleClick('parameter')}
      {...others}
    />
  );
}

Однако при использовании анонимной функции для возврата в useCallback, это тоже сработало.

Это означает код как здесь. (Только различия по сравнению с кодом выше.)

  const handleClick = useCallback((params) => {
    return () => setParam(params);
  },[]);

В этой ситуации мне интересно, будет ли это хуже, чем просто использовать анонимную функцию внутри useCallback, если я просто использую анонимную функцию вместо использования этот крюк.

Ответы [ 3 ]

1 голос
/ 24 января 2020
  const handleClick = useCallback((params) => {
    setParam(params);
  },[]);

  ...
  return (
    ...
    <SomeComponent
      onClick={handleClick('parameter')}
      {...others}
    />
  );

в приведенном выше коде во время первого рендеринга, в этом операторе "onClick={handleClick('parameter')}" функция handleClick вызывается со строкой с именем «parameter». так как handleClick имеет setParam («параметр»), он обновит состояние. Обновление состояния вызовет повторную визуализацию, которая снова примет тот же оператор "onClick={handleClick('parameter')}", что вызовет infinte l oop.

следующий код, который вы добавили позже, работает, потому что вы не обновляете состояние, а вместо этого возвращаете функцию, которая действует в качестве обработчика onclick время рендеринга дочерних компонентов внутри функции возврата внутри вашего Compoenent. допустим, у вас есть другое onclickHanldier с именем 'anotherHandleClick' внутри вашего приложения. тогда ваш компонент будет выглядеть следующим образом

const Component = () => {
  const [param, setParam] = useState('');
  const [anotherParam, setAnotherParam] = useState('');

  const handleClick = (params) => {
    setParam(params);
  };
const anotherHandleClick =(params) => {
    setAnotherParam(params);
  };
  ...
  return (
    ...
    <SomeComponent
      onClick={handleClick('parameter')}
      {...others}
    />
<SomeComponent
      onClick={antherHandleClick('parameter')}
      {...others}
    />
  );
}

в вышеупомянутом компоненте, когда любой из «SomeCompoenent» щелкает по всему «Компоненту», повторно отображает, поэтому функции-обработчики определяются заново, а когда оба объекта ссылаются проверка на равенство в функциях-обработчиках onclick, они считают, что это новая функция-обработчик, которая заставляет их отображать оба. в этом случае лучше использовать ловушку useCallBack, как показано ниже,

const Component = () => {
  const [param, setParam] = useState('');
      const [anotherParam, setAnotherParam] = useState('');

  const handleClick = useCallback((params) => {
    setParam(params);
  },[]);
const anotherHandleClick = useCallback((params) => {
    setAnotherParam(params);
  },[]);
  ...
  return (
    ...
    <SomeComponent
      onClick={handleClick('parameter')}
      {...others}
    />
<SomeComponent
      onClick={antherHandleClick('parameter')}
      {...others}
    />
  );
}

в приведенном выше коде при нажатии любой из них состояние изменяется. затем при рендеринге useCallback убедитесь, что ссылки на обработчики onclick не изменились. поэтому наличие зависимости от обработчиков onclick переопределено не будет.

, поэтому в конечном итоге В обоих случаях создается функция для каждого рендера. вторая (потому что она обернута в useCallback) вернет запомненную функцию, созданную в начальном рендере

, когда использовать useMemo или useCallback , см. это

0 голосов
/ 24 января 2020

Использование ловушки useCallback будет лучше, если вы хотите сохранить функцию, пока не будет изменена зависимость ловушки. Это дает вам лучшую производительность, потому что хук помнит внутреннюю функцию.

0 голосов
/ 24 января 2020

В вашем коде:

const handleClick = useCallback((params) => {
    setParam(params);
  },[]);

Вы должны передать параметры во второй аргумент useCallback примерно так:

const handleClick = useCallback((params) => {
    setParam(params);
  },[setParam,param, SETPARAMACTUALVALUE]); 
// Change SETPARAMACTUALVALUE to whatever the variable name is for the `setParam` hook
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...