Найкращий спосіб передавати параметри в обробці onClick


11

Це мій компонент. Я використовую функцію вбудованої стрілки, щоб змінити маршрут onClickdiv, але я знаю, що це не гарний спосіб з точки зору продуктивності

1. Функція вбудованої стрілки

changeRoute (routeName) {
  console.log(routeName)
}
render() {
  return (
    <>
      <div onClick={() => this.changeRoute("page1")}>1</div>
      <div onClick={() => this.changeRoute("page2")}>2</div>
    </>
  )
}

2. Якщо я використовую прив'язку конструктора, то як я можу передавати реквізит?

constructor() {
  super(props)
  this.changeRoute = this.changeRoute.bind(this)
}
changeRoute (routeName) {
  console.log(routeName)
}
render() {
  return (
    <>
      <div onClick={this.changeRoute}>1</div>
      <div onClick={this.changeRoute}>2</div>
    </>
  )
}

3. Якщо я видаляю функцію стрілки, то функція, що викликається, на самому візуалізації

changeRoute (routeName) {
  console.log(routeName)
}
render() {
  return (
    <>
      <div onClick={this.changeRoute("page1")}>1</div>
      <div onClick={this.changeRoute("page2")}>2</div>
    </>
  )
}

4. Якщо я використовую вбудовану прив'язку, то це також не найкраще з продуктивністю

changeRoute (routeName) {
  console.log(routeName)
}
render() {
  return (
    <>
      <div onClick={this.changeRoute.bind(this, "page1")}>1</div>
      <div onClick={this.changeRoute.bind(this, "page2")}>2</div>
    </>
  )
}

Тоді як я можу перейти до найкращого способу проходження параметрів?


Напевно, варто зауважити, що причина використання вбудованих функцій стрілок тут "не є [a] хорошим способом щодо продуктивності", не тому, що функції стрілок якось по-справжньому будуть повільно працювати (вони відсутні, і в будь-якому випадку вартість виклику функції абсолютно незначна для чогось рідко виконуваного, як обробник кліків), а тому React створюватиме нові екземпляри функцій щоразу, коли компонент буде повторно наданий. Вбудована палітура має точно таку ж проблему. І це, як правило , штраф в будь-якому випадку, якщо компонент не отримує повторно виявляється дуже часто.
Ільмарі Каронен

2
@IlmariKaronen У більшості випадків компонент повторно відображається через те, що компоненти мають поле введення, а введення та встановлення значення e.target.value у стані призводить до частого відображення.
Темний лицар

Відповіді:


6

Ви можете використовувати функцію стрілки для визначення вашого changeRouteобробника.

Це відомо як Class field syntax. Детальніше про це тут, в офіційних документах реагування.

constructor() {
  super(props)
}

const changeRoute = (parameter) => (event) => {
    // business logic for route change.
}

Потім ви можете використовувати цю функцію безпосередньо так:

render() {
  return (
    <>
      <div onClick={changeRoute(params1)}>1</div>
      <div onClick={changeRoute(params2)}>2</div>
    </>
  )
}

Вам не доведеться турбуватися про зв’язування. Функції стрілок успадковують батьківські this.


@DarkKnight Ваш останній коментар був executing on the go. Моя відповідь у відповідь на це. Я намагаюся сказати вам, що ваш обробник клацань не буде, execute on the goякщо ви визначите обробник, як я розмістив.
Utsav Patel

Перевірте це
Темний лицар

@DarkKnight Будь ласка, прочитайте цей reakctjs.org/docs/handling-events.html Синтаксис поля класу є одним із рекомендованих методів офіційними документами реагування.
Utsav Patel

ок, дякую, сер
Темний лицар

3

Ви можете додати дані у свій div:

<div data-id={1} onClick={this.changeRoute}>1</div>

Потім ви можете отримати ці дані у своєму обробнику onClick:

onClick = (event) => {
  const id = event.currentTarget.dataset.id;
}

Блискучий підхід!
Макс

Ха-ха-ха ... Можна зробити. Але реагувати сам не має роботи?
Темний лицар

1

№1 добре.

№2 також "добре", але вам потрібно передати реквізит, тоді функція візуалізації буде мати вигляд №1 . Ви будете викликати функцію bind'd, тому що ви замінили її в конструкторі.

№3 - це просто неправильно, оскільки функція викликається під час візуалізації.

Щодо №4, від док

Ми, як правило, рекомендуємо прив'язувати конструктор або використовувати синтаксис класових полів, щоб уникнути подібної проблеми з продуктивністю.

Це спричиняє покарання за ефективність, коли ваша функція використовується в дочірніх компонентах і призведе до повторного відображення дочірніх компонентів (це не у вашому випадку). Тож вам не слід робити №4 .


1

Найкращий на даний момент спосіб - загорнути обробник подій у useCallbackгачок, оскільки це не дозволить створювати функцію обробника щоразу, коли викликається візуалізація.

import React, { useCallback } from 'react'

const MyComponent = ({ changeRoute }) => {
  const eventHandler = useCallback(() => {
    changeRoute('page1')
  }, [changeRoute])

  return (
    <div onClick={eventHandler}>1</div>
  )
}

Для більш детальної перевірки - використовуйте документиCallback


ОП, здається, використовує компонент класу, де ви не можете використовувати гачки.
TJ Crowder

Сподіваюся, моя відповідь допоможе йому зрозуміти кращий шлях
Алег Атсман
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.