Cách tốt nhất để truyền tham số trong trình xử lý onClick


11

Đây là thành phần của tôi Tôi đang sử dụng chức năng mũi tên nội tuyến để thay đổi tuyến onClickcủa div nhưng tôi biết đó không phải là cách tốt về mặt hiệu suất

1. Chức năng mũi tên nội tuyến

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

2. Nếu tôi sử dụng ràng buộc constructor thì làm thế nào tôi có thể vượt qua đạo cụ?

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. Nếu tôi loại bỏ chức năng mũi tên thì chức năng được gọi trên chính kết xuất

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

4. Nếu tôi sử dụng liên kết nội tuyến thì nó cũng không tốt nhất với hiệu suất

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

Sau đó, làm thế nào tôi có thể tiến hành với cách tốt nhất thông qua các tham số?


Có lẽ đáng lưu ý rằng lý do tại sao sử dụng các chức năng mũi tên nội tuyến ở đây "không phải là [một cách tốt về mặt hiệu suất" không phải vì các chức năng mũi tên bằng cách nào đó về bản chất sẽ chạy chậm (trong trường hợp không phải vậy, và trong mọi trường hợp chi phí của một cuộc gọi hàm là hoàn toàn không đáng kể đối với một cái gì đó hiếm khi được thực hiện như một trình xử lý nhấp chuột) nhưng vì React sẽ tạo ra các phiên bản mới của các hàm mỗi khi thành phần được kết xuất lại. Liên kết nội tuyến có cùng một vấn đề chính xác. Và dù sao thì nó vẫn ổn, trừ khi thành phần được kết xuất lại rất thường xuyên.
Ilmari Karonen

2
@IlmariKaronen Trong hầu hết các trường hợp, thành phần tái xuất thường xuyên vì các thành phần có trường nhập và nhập và đặt e.target.value trong trạng thái dẫn đến kết xuất thường xuyên.
Hiệp sĩ bóng đêm

Câu trả lời:


6

Bạn có thể sử dụng chức năng mũi tên để xác định changeRoutetrình xử lý của bạn .

Điều này được gọi là Class field syntax. Thêm về nó ở đây trong các tài liệu phản ứng chính thức.

constructor() {
  super(props)
}

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

Sau đó, bạn có thể sử dụng chức năng này trực tiếp như vậy:

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

Bạn không phải lo lắng về sự ràng buộc. Các hàm mũi tên kế thừa cha mẹ của chúng this.


@DarkKnight Nhận xét cuối cùng của bạn là executing on the go. Câu trả lời của tôi là đáp lại điều đó. Tôi đang cố gắng nói với bạn rằng trình xử lý nhấp chuột của bạn sẽ không execute on the gonếu bạn xác định trình xử lý như tôi đã đăng.
Utsav Patel

Xin kiểm tra điều này
Dark Knight

@DarkKnight Vui lòng đọc phản ứng nàyjs.org/docs/handling-events.html Cú pháp trường lớp là một trong những phương pháp được đề xuất bởi các tài liệu phản ứng chính thức.
Utsav Patel

ok cảm ơn ngài
Dark Knight

3

Bạn có thể thêm dữ liệu vào div của mình:

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

Sau đó, bạn có thể truy xuất dữ liệu đó trong trình xử lý onClick của mình:

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

Cách tiếp cận rực rỡ!
Tối đa

Ha ha ha ... Có thể được thực hiện. Nhưng bản thân phản ứng không có công việc xung quanh?
Hiệp sĩ bóng đêm

1

# 1 là tốt

# 2 cũng là 'tốt', nhưng bạn cần phải vượt qua các đạo cụ, sau đó chức năng kết xuất sẽ trông giống hệt như # 1 . Bạn sẽ gọi hàm bind'd, vì bạn đã thay thế nó trong hàm tạo.

# 3 là sai, vì chức năng được gọi trong khi kết xuất.

Và liên quan đến # 4, từ các tài liệu phản ứng

Chúng tôi thường khuyên bạn nên ràng buộc trong hàm tạo hoặc sử dụng cú pháp trường lớp, để tránh loại vấn đề hiệu năng này.

Điều này gây ra một hình phạt hiệu năng khi chức năng của bạn được sử dụng trong các thành phần con của nó và sẽ khiến các thành phần con hiển thị lại (không phải trong trường hợp của bạn). Vì vậy, bạn không nên làm # 4 .


1

Cách tốt nhất hiện tại là bọc trình xử lý sự kiện của bạn trong useCallbackhook vì nó sẽ ngăn chức năng xử lý của bạn được tạo mỗi khi kết xuất được gọi.

import React, { useCallback } from 'react'

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

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

Để biết thêm thông tin, hãy kiểm tra - useCallback docs


OP dường như đang sử dụng một thành phần lớp, trong đó bạn không thể sử dụng các hook.
TJ Crowder

Tôi hy vọng câu trả lời của tôi sẽ giúp anh ấy hiểu được cách tốt hơn
Aleh Atsman
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.