Najlepszy sposób na przekazanie parametrów w module obsługi onClick

11

To jest mój komponent Używam wbudowanej funkcji strzałki do zmiany trasy onClickdiv, ale wiem, że nie jest to dobry sposób pod względem wydajności

1. Funkcja strzałki w linii

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

2. Jeśli używam wiązania konstruktora, to jak mogę przekazywać rekwizyty?

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. Jeśli usunę funkcję strzałki, wówczas funkcja jest wywoływana na samym renderingu

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

4. Jeśli używam wiązania wbudowanego, nie jest to również najlepsze z wydajnością

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>
    </>
  )
}

Więc jak mogę przejść do najlepszego sposobu przekazywania parametrów?

Mroczny rycerz
źródło
Prawdopodobnie warto zauważyć, że powodem, dla którego użycie tu wbudowanych funkcji strzałek „nie jest [a] dobry sposób pod względem wydajności”, nie jest to, że funkcje strzałek byłyby z natury powolne w działaniu (nie są, a w każdym razie koszt wywołania funkcji jest całkowicie pomijalny w przypadku czegoś tak rzadko wykonywanego jak moduł obsługi kliknięć), ale ponieważ React utworzy nowe wystąpienia funkcji za każdym razem, gdy komponent jest renderowany ponownie. Wiązanie wbudowane ma dokładnie ten sam problem. I tak zwykle jest w porządku, chyba że komponent jest renderowany bardzo często.
Ilmari Karonen
2
@IlmariKaronen W większości przypadków komponenty często renderują ponownie, ponieważ komponenty mają pole wejściowe, a wpisanie i ustawienie wartości e.target.value powoduje częste renderowanie.
Dark Knight

Odpowiedzi:

6

Możesz użyć funkcji strzałki, aby zdefiniować changeRouteprogram obsługi.

Jest to znane jako Class field syntax. Więcej na ten temat tutaj, w oficjalnych dokumentach dotyczących reakcji.

constructor() {
  super(props)
}

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

Następnie możesz użyć tej funkcji bezpośrednio tak:

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

Nie musisz się martwić o wiązanie. Funkcje strzałek dziedziczą po rodzicach this.

Utsav Patel
źródło
@DarkKnight Twój ostatni komentarz był executing on the go. Moja odpowiedź jest na to odpowiedzią. Próbuję powiedzieć, że Twój moduł obsługi kliknięć nie będzie, execute on the gojeśli zdefiniujesz moduł obsługi, tak jak napisałem.
Utsav Patel
Pls sprawdź to
Dark Knight
@DarkKnight Proszę przeczytać ten reagjs.org/docs/handling-events.html Składnia pól klasowych jest jedną z zalecanych metod oficjalnych dokumentów reagowania.
Utsav Patel
ok dziękuję panu
Dark Knight
3

Możesz dodać dane do div:

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

Następnie możesz pobrać te dane w module obsługi onClick:

onClick = (event) => {
  const id = event.currentTarget.dataset.id;
}
HermitCrab
źródło
Genialne podejście!
Maks.
Ha ha ha ... Można to zrobić. Ale sama reakcja nie działa?
Dark Knight
1

# 1 jest w porządku.

# 2 jest również „w porządku”, ale musisz przekazać rekwizyty, wtedy funkcja renderowania będzie wyglądać dokładnie tak jak # 1 . Będziesz wywoływał funkcję bindd, ponieważ zastąpiłeś ją w konstruktorze.

# 3 jest po prostu zły, ponieważ funkcja jest wywoływana podczas renderowania.

A jeśli chodzi o # 4, od reagujących doktorów

Ogólnie zalecamy powiązanie w konstruktorze lub użycie składni pól klasy, aby uniknąć tego rodzaju problemów z wydajnością.

Powoduje to obniżenie wydajności, gdy twoja funkcja jest używana w jej komponentach potomnych i spowoduje ponowne renderowanie komponentów potomnych (w twoim przypadku tak nie jest). Więc nie powinieneś robić # 4 .

Ben B
źródło
1

Obecnie najlepszym sposobem jest zawinięcie modułu obsługi zdarzeń, useCallbackponieważ uniemożliwi to utworzenie funkcji modułu obsługi za każdym razem, gdy wywoływane jest renderowanie.

import React, { useCallback } from 'react'

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

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

Aby uzyskać więcej informacji sprawdź - użyj dokumentów Callback

Aleh Atsman
źródło
Wygląda na to, że OP używa komponentu klasy, w którym nie można używać haków.
TJ Crowder
Mam nadzieję, że moja odpowiedź pomoże mu lepiej zrozumieć
Aleh Atsman,