Странное поведение параметризованной функции, переданной как опора в React

Я, вероятно, не вижу здесь чего-то очевидного, но я чувствую себя довольно застрявшим в этом.

У меня есть функция

public handleTest = (testNum: number) => {
    console.info(testNum);
  };

И следующий случай: у меня есть компонент, которому я хочу передать эту функцию, чтобы в дальнейшем использовать его в событии onCLick.

<Controls handleTest = {() => this.handleTest}>
 <Button label = "Test1" clicked = {() => this.handleTest(42)} />
</Controls>

Дочерний компонент следующий:

interface IProps {
  handleTest: (type: number) => void;
}

class Controls extends React.Component<IProps, {}> {
  public render() {
    const {
      handleTest
    } = this.props;

return (
  <React.Fragment>
    {this.props.children}
    <button onClick = {handleTest(42)} label = "Test2" />
  </React.Fragment>
);
 }
}

В этом случае интересно то, что в случае кнопки Test2 кажется, что он не распознает переданный ей аргумент, пока он регистрирует объект -

Object { dispatchConfig: {…}, _targetInst: {…}, nativeEvent: click, type: "click", target: button.sc-bwzfXH.gonlMM, currentTarget: button.sc-bwzfXH.gonlMM, eventPhase: 3, bubbles: true, cancelable: true, timeStamp: 689, … }

В случае Test1 все работает правильно. Мне интересно, что я делаю не так, и не все ли портит машинописный текст или какая-то моя ошибка

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
0
0
30
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

<button onClick = {handleTest(42)} label = "Test2" /> вместо

<button onClick = {() => handleTest(42)} label = "Test2" />

<button onClick = {handleTest(42)} label = "Test2" /> работал бы, если бы handleTest выглядел так:

public handleTest = (testNum: number) => () => {
  console.info(testNum);
};

Обновлено: Я бы действительно рекомендовал использовать обработчики вторым способом, когда вам нужно добавить внешний параметр в функцию обработчика. Объявив обработчик через {() => doSomething()}, каждый раз, когда вы визуализируете компонент, эта функция-обработчик будет инициализироваться снова.

Тем не менее, в большинстве случаев это всего лишь небольшая оптимизация.

Ответ принят как подходящий

Это связано с тем, что когда вы инициализируете компонент <Controls />, отправляемая вами функция выглядит примерно так:

() => this.handleTest

Итак, в button Test2 вы ничего не выполняете, потому что последняя функция просто возвращает функцию

Итак, если вы хотите решить эту проблему:

<Controls handleTest = {(number) => this.handleTest(number)}>
 <Button label = "Test1" clicked = {() => this.handleTest(42)} />
</Controls>

Также, если вы сделаете это таким образом во время рендеринга <Controls />, ваша функция будет выполнена, а не когда пользователь щелкнет по ней. Чтобы решить эту проблему, вам нужно изменить его следующим образом:

<React.Fragment>
  {this.props.children}
  <button onClick = {()=>handleTest(42)} label = "Test2" />
</React.Fragment>

Для оптимизации просто отправьте функцию. Это внедрение функции

<Controls handleTest = {this.handleTest}>
   <Button label = "Test1" clicked = {() => this.handleTest(42)} />
</Controls>

Другие вопросы по теме