Как заставить функцию onClick срабатывать по щелчку значка?

Я пытаюсь настроить функцию onClick для значка плюса FontAwesome. Значок появляется только рядом с любым элементом, у которого нет дочерних элементов (например, в моем вложенном меню элементы, внутри которых нет других элементов). Когда я тестирую onClick, console.info кажется, что каждый раз, когда я нажимаю на элемент в меню, он срабатывает либо два, либо четыре раза. Кто-нибудь знает, что я могу сделать, чтобы он срабатывал только при нажатии на значок плюса? Или почему он срабатывает каждый раз, когда щелкают любой элемент? Смотрите скриншоты ниже для более подробной информации.

class MenuTest extends React.Component {
  state = {
    categories: [],
    objectKeys: null,
    tempKeys: []
  };

Здесь я установил onClick внутри тега FontAwesome с плюсом.

  makeMenuLayer = layer => {
    const { objectKeys } = this.state;
    const layerKeys = Object.entries(layer).map(([key, value]) => {
{/*if the element still has children, insert an arrow, if not, insert nothing*/}      
var arrow = Object.keys(value).length ? (
        <FontAwesome name = "angle-right" />
      ) : (
        ""
      );
{/*if the element has no children, insert a plus sign, if not, insert nothing*/}
      var ex =
        Object.keys(value).length === 0 ? <FontAwesome name = "plus" onClick = {console.info("clicked")} /> : "";
      return (
        <ul key = {key}>
          <div onClick = {() => this.handleShowMore(key)}>
            {key} {arrow} {ex}
          </div>

          {objectKeys[key] && this.makeMenuLayer(value)}
        </ul>
      );
    });
    return <div>{layerKeys}</div>;
  };

  handleShowMore = key => {
    this.setState(prevState => ({
      objectKeys: {
        ...prevState.objectKeys,
        [key]: !this.state.objectKeys[key]
      }
    }));
  };

  initializeTempKeys = layer => {
    // eslint-disable-next-line
    Object.entries(layer).map(([key, value]) => {
      const newTempKeys = this.state.tempKeys;
      newTempKeys.push(key);
      this.setState({ tempKeys: newTempKeys });
      this.initializeTempKeys(value);
    });
  };

  initializeObjectKeys = () => {
    const { tempKeys } = this.state;
    let tempObject = {};
    tempKeys.forEach(tempKey => {
      tempObject[tempKey] = true;
    });

    this.setState({ objectKeys: tempObject });
  };

  componentDidMount() {
    axios.get("https://www.ifixit.com/api/2.0/categories").then(response => {
      this.setState({ categories: response.data });
    });
    const { categories } = this.state;
    this.initializeTempKeys(categories);
    this.initializeObjectKeys();
    this.setState({ categories });
  }

  render() {
    const { categories } = this.state;
    return <div>{this.makeMenuLayer(categories)}</div>;
  }
}

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

Это то, что появляется в консоли, когда я пытаюсь это проверить

Как заставить функцию onClick срабатывать по щелчку значка?

Данные, с которыми я работаю: Как заставить функцию onClick срабатывать по щелчку значка?

У Аксессуаров двое детей? А у Галстука тоже двое детей?

Chris Ngo 12.05.2019 02:26

У Аксессуара @ChristopherNgo двое детей, а у Галстука — нет. Двое детей Аксессури - Галстук и Зонт. Я опубликую скриншот данных для лучшего взгляда

Emily 12.05.2019 02:28

Ясно, я думаю, вы можете обойти это, выполнив onClick = {() => console.info("test")}.

Chris Ngo 12.05.2019 02:31

@ChristopherNgo Это сработало! Спасибо! Не могли бы вы объяснить, почему это работает, а не использует () =>?

Emily 12.05.2019 02:35

Конечно, на самом деле это всего лишь React/JSX! Когда вы сделали onClick = {console.info("clicked")}, он немедленно выполнит эту логику, когда вы отобразите свой FontAwesomeIcon. Чтобы обойти это, вы должны вместо этого передать анонимную функцию, например () =>, которая будет пассивно ждать срабатывания вашего прослушивателя событий щелчка.

Chris Ngo 12.05.2019 02:41

@ChristopherNgo Понятно, теперь я понимаю. Большое спасибо за Вашу помощь!

Emily 12.05.2019 02:47

Пожалуйста :)!

Chris Ngo 12.05.2019 02:54
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
7
1 732
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Обертывание события onclick функцией обратного вызова, а затем вызов консоли будет работать, так как вам нужно связать асинхронную функцию с onClick, а не напрямую вызывать console.info:

<FontAwesome name = "plus" onClick = {() => {console.info("clicked")}} /> 

Спасибо

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

@Emily просто собирается опубликовать здесь нашу беседу из комментариев, чтобы было легче ссылаться на решение.

«Когда вы это сделаете onClick = {console.info("clicked")}, он немедленно выполнит эту логику, когда вы отобразите свой FontAwesomeIcon. Чтобы обойти это, вы вместо этого передадите анонимную функцию like () => yourlogic(), которая будет пассивно ждать срабатывания вашего прослушивателя событий щелчка».

<FontAwesome name = "plus" onClick = {() => console.info("clicked")} />

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