OnClick işleyicisinde parametreleri iletmenin en iyi yolu


11

Bu benim bileşenim onClickdiv rotasını değiştirmek için satır içi ok işlevini kullanıyorum ama performans açısından iyi bir yol olmadığını biliyorum

1. Satır içi ok işlevi

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

2. Eğer yapıcı bağlama kullanırsam, nasıl sahne geçmek olabilir?

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. Ok işlevini kaldırırsam, işlemenin kendisinde çağrılan işlev

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

4. Satır içi ciltleme kullanırsam performans açısından da en iyisi değildir

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

Öyleyse parametreleri geçirmenin en iyi yoluna nasıl geçebilirim?


O belirterek değer demektir nedeni ok fonksiyonları nasılsa onlar değil (pistinin özünde yavaş olacaktır çünkü burada fonksiyonları ok satır içi kullanarak neden değil "performans açısından [a] iyi bir yol değildir" ve her halükarda Bir işlev çağrısının maliyeti, tıklama işleyicisi olarak nadiren yürütülen bir şey için tamamen göz ardı edilebilir), ancak React bileşen her yeniden oluşturulduğunda işlevlerin yeni örneklerini oluşturacaktır. Satır içi ciltleme de aynı soruna sahiptir. Ve bileşen çok sık yeniden işlenmedikçe genellikle iyi olur .
Ilmari Karonen

2
@IlmariKaronen Çoğu durumda, bileşenlerin giriş alanı olduğu ve e.target.value değerini yazıp ayarladığı için bileşen sık sık yeniden oluşturulur.
Kara Şövalye

Yanıtlar:


6

changeRouteİşleyicinizi tanımlamak için ok işlevini kullanabilirsiniz .

Bu olarak bilinir Class field syntax. Burada daha fazla resmi tepki belgelerinde.

constructor() {
  super(props)
}

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

Ardından bu işlevi doğrudan şu şekilde kullanabilirsiniz:

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

Bağlanma konusunda endişelenmenize gerek yok. Ok işlevleri ebeveynlerinin mirasını alır this.


@DarkKnight Son yorumunuz oldu executing on the go. Cevabım buna yanıt. Göndermiş olduğum execute on the gogibi işleyiciyi tanımlarsanız, tıklama işleyicinizin olmayacağını söylemeye çalışıyorum .
Utsav Patel

Pls kontrol bu
Dark Knight

@DarkKnight Lütfen bu reaktjs.org/docs/handling-events.html Sınıf alanı sözdizimini resmi reaksiyon belgeleri tarafından önerilen yöntemlerden biridir.
Utsav Patel

tamam teşekkür ederim efendim
Dark Knight

3

Div'inize veri ekleyebilirsiniz:

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

Ardından, bu verileri onClick işleyicinizde alabilirsiniz:

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

Mükemmel yaklaşım!
Max

Ha ha ha ... Yapılabilir. Ama tepkinin kendisinin bir işi yok mu?
Kara Şövalye

1

1. iyidir.

# 2 de 'iyi', ancak sahne geçmeniz gerekiyor, ardından oluşturma işlevi tam olarak # 1 gibi görünecek . Yapıcıda değiştirdiğiniz için bind'd işlevini çağırırsınız.

# 3 , yalnızca render sırasında fonksiyon çağrıldığından yanlıştır.

Ve # 4 ile ilgili olarak, tepki belgelerinden

Bu tür performans sorunlarından kaçınmak için genellikle yapıcıda bağlamayı veya sınıf alanları sözdizimini kullanmanızı öneririz.

Bu, işleviniz alt bileşenlerinde kullanıldığında performans cezasına neden olur ve alt bileşenlerin yeniden oluşturulmasına neden olur (sizin durumunuzda değil). Bu yüzden # 4 yapmamalısınız .


1

Şu anda en iyi yol, olay işleyiciyi useCallbackkancaya sarmaktır, çünkü render işlemi her çağrıldığında işleyici işlevinizin oluşturulmasını önler.

import React, { useCallback } from 'react'

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

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

Daha fazla bilgi için - geri arama dokümanlarını kullanın


OP, kancaları kullanamayacağınız bir sınıf bileşeni kullanıyor gibi görünüyor.
TJ Crowder

Umarım cevabım ona daha iyi yolu anlamasına yardımcı olur
Aleh Atsman
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.