Kapan menggunakan komponen Bereaksi berbasis kelas ES6 vs komponen Bereaksi ES6 fungsional?

212

Setelah menghabiskan waktu belajar Bereaksi, saya memahami perbedaan antara dua paradigma utama pembuatan komponen.

Pertanyaan saya adalah kapan saya harus menggunakan yang mana dan mengapa? Apa manfaat / pengorbanan dari satu di atas yang lain?


Kelas ES6:

import React, { Component } from 'react';

export class MyComponent extends Component {
  render() {
    return (
      <div></div>
    );
  }
}

Fungsional:

const MyComponent = (props) => {
    return (
      <div></div>
    );
}

Saya berpikir fungsional setiap kali tidak ada keadaan yang dimanipulasi oleh komponen itu, tetapi apakah begitu?

Saya menduga jika saya menggunakan metode siklus hidup, mungkin lebih baik menggunakan komponen berbasis kelas.

omarjmh
sumber
7
Sepertinya Anda sudah tahu jawabannya.
Felix Kling
2
Jika Anda memiliki komponen dengan metode render saja, Anda dapat mengubahnya menjadi bentuk fungsional. Jika Anda membutuhkan sesuatu yang lebih dari fungsi render stateless, gunakan kelas
just-boris
2
Agar lebih ringkas coba ini:const MyComponent = (props) => <div>...</div>
Viliam Simko
1
Saya tidak pernah menggunakan fungsional jika bisa dihindari. Karena saya akhirnya harus refactor ke kelas di ujung jalan. Dan kemudian sering perlu refactor kembali ke fungsional setelah itu.
keithjgrant
Pada tahun 2020 pendekatan yang tepat adalah menggunakan komponen fungsional sedapat mungkin, karena mereka mendukung kait, dan kait (kinerja-bijaksana dan arsitektur) lebih baik daripada alternatif.
polkovnikov.ph

Jawaban:

161

Anda punya ide yang tepat. Pergi dengan fungsional jika komponen Anda tidak melakukan lebih dari menerima beberapa alat peraga dan render. Anda dapat menganggap ini sebagai fungsi murni karena mereka akan selalu membuat dan berperilaku sama, mengingat alat peraga yang sama. Juga, mereka tidak peduli dengan metode siklus hidup atau memiliki kondisi internal mereka sendiri.

Karena ringan, penulisan komponen sederhana ini sebagai komponen fungsional cukup standar.

Jika komponen Anda membutuhkan lebih banyak fungsi, seperti menjaga status, gunakan kelas sebagai gantinya.

Info lebih lanjut: https://facebook.github.io/react/docs/reusable-components.html#es6-classes


EDIT : Banyak hal di atas benar, sampai diperkenalkannya React Hooks.

  • componentDidUpdatedapat direplikasi dengan useEffect(fn), di mana fnfungsi untuk dijalankan saat rerendering.

  • componentDidMountmetode dapat direplikasi dengan useEffect(fn, []), di mana fnfungsi untuk dijalankan pada rerendering, dan []merupakan array objek yang komponen akan rerender, jika dan hanya jika setidaknya satu telah mengubah nilai sejak render sebelumnya. Karena tidak ada, useEffect()berjalan sekali, pada mount pertama.

  • statedapat direplikasi dengan useState(), yang nilai kembaliannya dapat dihancurkan ke referensi negara dan fungsi yang dapat mengatur negara (yaitu, const [state, setState] = useState(initState)). Contoh mungkin menjelaskan ini dengan lebih jelas:

const Counter = () => {
  const [count, setCount] = useState(0)

  const increment = () => { 
    setCount(count + 1);
  }

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={increment}>+</button>
    </div>
  )
}

default export Counter

Mengenai rekomendasi kapan menggunakan kelas atas komponen fungsional, Facebook secara resmi merekomendasikan penggunaan komponen fungsional sedapat mungkin . Di samping yang kecil, saya telah mendengar sejumlah orang berdiskusi tidak menggunakan komponen fungsional untuk alasan kinerja, khususnya itu

"Fungsi penanganan acara didefinisikan ulang per render dalam komponen fungsional"

Meskipun benar, harap pertimbangkan apakah komponen Anda benar-benar merender dengan kecepatan atau volume sedemikian rupa sehingga ini patut diperhatikan.

Jika ya, Anda dapat mencegah mendefinisikan ulang fungsi menggunakan useCallbackdan useMemokait. Namun, ingatlah bahwa ini dapat membuat kode Anda (secara mikroskopis) lebih buruk dalam kinerjanya .

Tapi jujur, saya belum pernah mendengar mendefinisikan ulang fungsi menjadi hambatan dalam aplikasi Bereaksi. Optimalisasi prematur adalah akar dari semua kejahatan - khawatir tentang ini ketika itu menjadi masalah

Jeff Cousins
sumber
Bagaimana dengan fungsionalitas yang tidak mempertahankan status, tetapi sangat terkait dengan komponen, misalnya menentukan beberapa atribut dinamis untuk render.
Dennis
Ini adalah artikel terbaik tentang perbedaan antara dua jenis komponen dalam Bereaksi: code.tutsplus.com/tutorials/…
Arian Acosta
5
Pada Bereaksi 16.8, Anda dapat menggunakan status dalam komponen fungsional, melalui useStatehook.
Greg
Pada Bereaksi 16.8, Anda dapat melakukan hampir semua hal dalam komponen fungsional, dan semua efek akhirnya dapat dimodulasi dengan hanya dampak minimal pada kinerja.
polkovnikov.ph
1
Di mana Anda menemukan info di mana Facebook officially recommends using functional components wherever possible?
johannchopin
40

Selalu berusaha menggunakan fungsi stateless (komponen fungsional) bila memungkinkan. Ada beberapa skenario di mana Anda harus menggunakan kelas Bereaksi reguler:

  • Komponen perlu mempertahankan status
  • Komponen rendering ulang terlalu banyak dan Anda harus mengontrolnya via shouldComponentUpdate
  • Anda memerlukan komponen kontainer

MEMPERBARUI

Sekarang ada kelas Bereaksi yang disebut PureComponentbahwa Anda dapat memperluas (bukannya Component) yang mengimplementasikan sendiri shouldComponentUpdateyang menangani perbandingan alat peraga dangkal untuk Anda. Baca lebih lajut

ffxsam
sumber
43
Always try to use stateless functions (functional components) whenever possible.Saya telah membaca sepuluh orang mengatakan itu. Masih tidak ada dari mereka yang memberikan penjelasan mengapa.
Rotareti
25
In an ideal world, most of your components would be stateless functions because in the future we’ll also be able to make performance optimizations specific to these components by avoiding unnecessary checks and memory allocations. This is the recommended pattern, when possible.Info lebih lanjut: facebook.github.io/react/docs/…
Diogo Cardoso
2
@rotareti Saya tidak tahu apakah Anda merasa Anda menjawab pertanyaan Anda, tetapi fungsi murni jauh lebih mudah untuk dipahami, diuji, dan dipelihara. Dengan parameter yang sama, mereka selalu memberikan hal yang sama. Komponen yang mempertahankan status dan berubah ketika peristiwa siklus hidup terjadi lebih sulit untuk dipahami. Bukan untuk mengatakan bahwa mereka kadang-kadang tidak diperlukan, tetapi saya harap jelas bahwa jika keuntungan mereka tidak diperlukan, yang mereka lakukan adalah menambahkan pelat baja dan overhead yang tidak diinginkan tanpa manfaat.
door_number_three
Anda juga ingin membuat kelas Komponen jika Anda memiliki definisi event handler Anda sendiri. Dengan begitu Anda dapat mengikat sebelumnya penangan acara ke komponen di konstruktor alih-alih membuat fungsi baru yang segar di setiap render. Perhatikan ini tidak diperlukan jika semua penangan acara Anda berasal dari alat peraga.
Dobes Vandermeer
Perhatikan bahwa rekomendasi Facebook yang dikutip sudah tidak ada lagi (lihat komentar saya di atas).
Garrett
34

PEMBARUAN Maret 2019

https://overreacted.io/how-are-function-components-different-from-classes/

UPDATE Feb 2019:

Dengan diperkenalkannya kait Bereaksi , tampaknya seolah-olah tim Bereaksi menginginkan kita untuk menggunakan komponen fungsional bila memungkinkan (yang lebih baik mengikuti sifat fungsional JavaScript).

Motivasi mereka:

1.) Its hard to reuse stateful logic between components
2.) Complex components become hard to understand
3.) Classes confuse both people and machines

Komponen fungsional dengan pengait dapat melakukan hampir semua hal yang dapat dilakukan komponen kelas, tanpa ada penarikan mundur yang disebutkan di atas.

Saya sarankan menggunakannya sesegera mungkin.

Jawaban Asli

Komponen fungsional tidak lebih ringan daripada komponen berbasis kelas, "mereka berfungsi persis seperti kelas." - https://github.com/facebook/react/issues/5677#issuecomment-241190513

Tautan di atas sedikit tanggal, tetapi React 16.7.0's dokumentasi mengatakan bahwa komponen fungsional dan kelas:

"Setara dengan sudut pandang React." - https://reactjs.org/docs/components-and-props.html#stateless-functions

Pada dasarnya tidak ada perbedaan antara komponen fungsional dan komponen kelas yang hanya mengimplementasikan metode render, selain sintaksis.

Di masa mendatang (mengutip tautan di atas) "kami [Bereaksi] mungkin menambahkan optimasi seperti itu."

Jika Anda mencoba untuk meningkatkan kinerja dengan menghilangkan render yang tidak perlu, kedua pendekatan menyediakan dukungan. memountuk komponen fungsional dan PureComponentuntuk kelas.

- https://reactjs.org/docs/react-api.html#reactmemo

- https://reactjs.org/docs/react-api.html#reactpurecomponent

Itu benar-benar terserah Anda. Jika Anda ingin pelat ketel kurang, gunakan fungsional. Jika Anda menyukai pemrograman fungsional dan tidak suka kelas, aktifkan. Jika Anda ingin konsistensi antara semua komponen dalam basis kode Anda, ikuti kelas. Jika Anda bosan melakukan refactoring dari komponen berbasis fungsional ke kelas saat Anda membutuhkan sesuatu state, lanjutkan dengan kelas.

Galupuf
sumber
1
Saya pikir membuat setiap komponen memperpanjang React.Component membuat kode lebih mudah dibaca, terutama untuk orang-orang baru. Sangat menyenangkan ketika Anda melihat komponen yang dibuat dengan cara yang sama setiap kali. Seperti kata @ Galupuf, komponen sederhana hanya memiliki satu metode yang disebut "render ()". Ini juga bagus untuk membuat semuanya memperpanjang React.Component karena ketika Anda ingin mulai mengikat "ini", memiliki status, dll. Anda tidak harus memperbaiki semuanya, Anda bisa menambahkan apa yang Anda butuhkan.
jeffski13
10

Pada Bereaksi 16.8 istilah komponen Fungsional Stateless menyesatkan dan harus dihindari karena mereka tidak lagi tanpa kewarganegaraan ( React.SFC usang , Dan Abramov pada React.SFC ), mereka dapat memiliki keadaan, mereka dapat memiliki kait (yang bertindak sebagai metode siklus hidup) juga, mereka lebih atau kurang tumpang tindih dengan komponen kelas

Komponen berbasis kelas

Komponen fungsional:

Mengapa saya lebih suka komponen Funtional

  • Bereaksi menyediakan hook useEffect yang merupakan cara yang sangat jelas dan ringkas untuk menggabungkan componentDidMount, componentDidUpdatedan componentWillUnmountmetode siklus hidup
  • Dengan kait, Anda dapat mengekstrak logika yang dapat dengan mudah dibagikan di seluruh komponen dan dapat diuji
  • kurang kebingungan tentang pelingkupan

Bereaksi motivasi mengapa menggunakan kait (yaitu komponen fungsional).

Karim
sumber