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

那么,如何进行传递参数的最佳方式呢?


这也许值得一提的是,原因为何使用内嵌这里arrow功能“是不是在性能方面[A]好办法”是不是因为箭头的功能会以某种方式在本质上缓慢运行(他们不是,在任何情况下,对于像单击处理程序这样很少执行的事情,函数调用的成本完全可以忽略不计),但是因为React每次重新渲染组件时都会创建函数的新实例。内联绑定具有完全相同的问题。无论如何,通常都很好,除非非常频繁地重新渲染组件。
Ilmari Karonen

2
@IlmariKaronen在大多数情况下,组件会频繁重新渲染,因为组件具有输入字段,并且在状态中键入和设置e.target.value会导致频繁渲染。
黑暗骑士

Answers:


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请阅读此reactjs.org/docs/handling-events.html类字段语法是官方react文档推荐的方法之一。
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也是'fine',但是您需要传递prop,然后render函数将看起来与#1完全一样。您将调用bind'd函数,因为您在构造函数中将其替换了。

#3是错误的,因为该函数在渲染过程中被调用。

关于#4,来自react docs

我们通常建议在构造函数中进行绑定或使用类字段语法进行绑定,以避免此类性能问题。

当在子组件中使用您的函数时,这会导致性能下降,并且会导致子组件重新呈现(在您的情况下不是)。因此,您不应该执行#4


1

当前最好的方法是将事件处理程序包装在useCallback钩子中,因为它将阻止每次调用render时都创建处理程序功能。

import React, { useCallback } from 'react'

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

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

有关更多信息,请检查-useCallback文档


OP似乎使用的是类组件,您不能在其中使用钩子。
TJ Crowder

我希望我的回答将帮助他理解更好的方法
Aleh Atsman
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.