Feliz: [<reactcomponent>] vs React.functionComponent di React refresh</reactcomponent>

Dibuat pada 25 Nov 2020  ·  10Komentar  ·  Sumber: Zaid-Ajaj/Feliz

Halo teman,

sebagai pengembang frontend yang naif, saya menjadi perilaku yang menarik:

Berdasarkan dokumen Anda, saya lebih suka menggunakan React.functionComponent untuk membuat komponen karena saya juga dapat menentukan nama komponen untuk debug yang lebih baik. Lucunya hadir dengan react refresh.

Kode seperti ini selalu memicu pemuatan ulang halaman penuh saat melakukan perubahan apa pun pada kode:

let subView = React.functionComponent("SubView", fun () ->
    Html.text "Hello from sub"
)

let topView = React.functionComponent("TopView", fun () ->
    Html.div [ Html.div "Hello from top"; subView () ]
)

image

Tetapi memiliki komponen root dengan [<ReactComponent>] akan membuat semua penyegaran berfungsi dengan baik tanpa melakukan penyegaran penuh.

let subView = React.functionComponent("SubView", fun () ->
    Html.text "Hello from sub"
)

[<ReactComponent>]
let topView () = Html.div [ Html.div "Hello from top"; subView () ]

Apakah itu bug? Apakah itu bug dalam fitur alias dasi hitam mewah? Apakah ini semua salah saya karena saya tidak mendapatkan perbedaan antara atribut ReactComponent dan fungsi React.functionComponent? 😄

Terima kasih atas bantuan apa pun untuk lebih memahami.

question

Komentar yang paling membantu

Wow! Cuma wow! Orang bodoh mengajukan pertanyaan bodoh dan jawaban pria pintar dengan tiga lembar A4 penuh dengan informasi dan penjelasan yang relevan. 🤯 Anda hanya rock, man! Terima kasih banyak! ❤️ Sekarang saya mengerti dan sebagai gantinya akan mulai menggunakan Atribut.

Apakah masih disarankan untuk memberi nama komponen entah bagaimana (seperti yang kita lakukan menggunakan parameter pertama React.functionComponent ) atau ini tidak diperlukan lagi untuk pendekatan atribut?

Semua 10 komentar

Atribut akan menjadi cara untuk pergi di masa depan, dan diperlukan agar react-refresh berfungsi. Setidaknya, begitulah tapi saya pikir @ Zaid-Ajaj menyelesaikannya sehingga tidak ada perbedaan?

Hai Roman,

Ini adalah pertanyaan yang sangat bagus yang tidak ada jawaban singkatnya, ini dia.

Meskipun begitu saya menyelesaikan masalah internet saya di rumah, saya akan melanjutkan streaming lagi di mana saya menjelaskannya dengan detail yang menyiksa 😁

Berdasarkan dokumen Anda, saya lebih suka menggunakan React.functionComponent untuk membuat komponen karena saya juga dapat menentukan nama komponen untuk debugging yang lebih baik. Lucunya hadir dengan react refresh.

Pertama-tama, saya ingin menunjukkan bahwa dokumentasinya berada dalam keadaan transisi yang tidak menguntungkan: pada dasarnya ketinggalan zaman dengan Feliz terbaru dan kebaikan [<ReactComponent>] sampai kita menyelesaikan masalah plugin kompiler dan menstabilkan AST yang digunakan oleh Fable . Apa yang ingin saya katakan adalah bahwa dokumen tidak mendukung React.functionComponent dan jika Anda menggunakan Fable 3, Anda harus mulai menggunakan [<ReactComponent>] sebagai gantinya.

Ini ada hubungannya dengan bagaimana kode Javascript dibuat. Sekarang pertimbangkan bagian dari kode React ini:

const App = ({ title }) => {
  return (
    <h1>{title}</h1>
  )
};

<App title="My React Application" />

JS ini (yang sebenarnya adalah JSX) desugars ke kode JS berikut

import { createElement } from 'react'

const App = ({ title }) => {
  return createElement("h1", null, title);
};

// <App /> compiles to a call to createElement
createElement(App, { title: "My React Application" })

Penting untuk diperhatikan bahwa inisialisasi komponen App melalui <App ... /> dikompilasi menjadi panggilan ke createElement dari JS.

Ini penting karena dua hal:

  • Ini memisahkan definisi komponen dari pembuatannya
  • Ini memungkinkan App menjadi nilai statis (identitas dicadangkan yang digunakan oleh React)

Sekarang, cara React.functionComponent diimplementasikan adalah "buruk" untuk React karena ini menggabungkan definisi dan kreasi dalam sekali jalan. Kode F # ini

let app React.functionComponent("App", fun (props: {|  tite: string |}) -> Html.h1 props.title)

Apakah setara dengan mengatakan

let app = 
  let render(props: {|  tite: string |}) = 
    let renderFn props= Html.h1 props.title
    createElement(renderFn , props)
  render.displayName <- "App"
  render

Sekarang ini "buruk" karena createElement membuat komponen yang didefinisikan secara dinamis pada setiap pemanggilan dan mutasi fungsi displayName daripada menggunakan nama fungsi itu sendiri.

Sintaks ini menggunakan React.functionComponent tidak memengaruhi perilaku runtime React dan itulah mengapa kami dapat menggunakannya tanpa masalah untuk membangun aplikasi React. Masalah mulai muncul ketika TOOLING di sekitar aplikasi React mulai menganalisis kode yang dihasilkan: webpack, babel, react-refresh adalah semua alat yang melihat kode yang dihasilkan, menyuntikkan beberapa keajaiban di sana-sini untuk membuat penggantian modul panas menjadi mungkin tetapi dengan React.functionComponent tidak mungkin karena kode yang dihasilkan tidak sesuai dengan bagaimana aplikasi React biasanya dibuat saat Anda menulis JS dan banyak perkakas di sekitar React membuat asumsi berdasarkan fakta bahwa kode tersebut ditulis sesuai dengan standar Bereaksi itu daripada yang dihasilkan oleh alat.

Solusi untuk masalah ini hadir di Fable 3 di mana kami diizinkan untuk menyesuaikan kompilasi kode melalui plugin kompiler. Jika Anda mempertimbangkan kode F # Feliz ini di Fable 3

[<ReactComponent>]
let app (title: string) = Html.h1 title 

app "My  React Application"

Kemudian dikompilasi hingga setara dengan JS ini (tidak tepat karena lebih banyak sihir)

const App = (props) { 
   const title = props.title
   return createElement("h1", null, title)
}

createElement(App, { title: "My  React Application" })

Sekarang kode yang dihasilkan ini disesuaikan agar terlihat seperti yang diharapkan oleh tooling React:

  • Definisi dan kreasi komponen fungsi terpisah
  • Komponen didefinisikan sebagai huruf besar (ya, ini juga diperlukan dan plugin compiler secara otomatis menulis ulang definisi tersebut)
  • Parameter input secara otomatis diterjemahkan ke dalam props React

Kombinasi ini membuat penyegaran React bekerja dan dengan ekstensi membuat pengalaman Feliz sangat mirip dengan JS atau TS asli. Saya harap ini menghilangkan kebingungan. Kalau ada pertanyaan lagi, beri tahu saya 😉

Wow! Cuma wow! Orang bodoh mengajukan pertanyaan bodoh dan jawaban pria pintar dengan tiga lembar A4 penuh dengan informasi dan penjelasan yang relevan. 🤯 Anda hanya rock, man! Terima kasih banyak! ❤️ Sekarang saya mengerti dan sebagai gantinya akan mulai menggunakan Atribut.

Apakah masih disarankan untuk memberi nama komponen entah bagaimana (seperti yang kita lakukan menggunakan parameter pertama React.functionComponent ) atau ini tidak diperlukan lagi untuk pendekatan atribut?

Sekarang saya mengerti dan akan mulai menggunakan Atribut sebagai gantinya.

Hebat! Izinkan saya jika Anda mengalami masalah apa pun 😉 saat ini satu-satunya masalah yang harus diperhatikan adalah menggunakan tipe record karena input props akan sedikit bermasalah untuk React-refresh, jadi Anda dapat menggunakan record anonim atau parameter primitif. Saya berharap masalah ini segera diperbaiki sehingga saya dapat mendokumentasikan [<ReactComponent>] tanpa peringatan apa pun.

Apakah masih disarankan untuk memberi nama komponen entah bagaimana (seperti yang kita lakukan menggunakan parameter pertama React.functionComponent) atau ini tidak diperlukan lagi untuk pendekatan atribut?

Tidak, satu-satunya persyaratan adalah bahwa komponen dikompilasi sebagai nilai huruf besar yang merupakan salah satu hal yang dilakukan [<ReactComponent>] pada definisi fungsi: smile: Anda dapat mengimplementasikannya di sini

@Dzoukr satu-satunya alasan menggunakan nama untuk komponen react Anda adalah untuk membuat perkakas debug lebih baik.

@Shmew Yup, tetapi tidak ada kelebihan beban pada konstruktor ReactComponent untuk menambahkan nama seperti itu jadi itu sebabnya ditanya.

Jadi, melanjutkan pertanyaan [<ReactComponent>] vs functionComponent : hooks!

Saya punya komponen yang perlu menginisialisasi beberapa status. Untungnya, kami memiliki banyak hook bagus yang tersedia! Saya menulis ini:

[<ReactComponent>]
let Entrypoint() =
    let drawing, updateDrawing = React.useState(Deferred.HasNotStartedYet)
    let loader = React.useDeferredCallback((fun () -> loadDrawing()), updateDrawing)

    React.useEffect(loader, [||])
    // etc

Sayangnya, ketika saya mencoba menjalankan ini, konsol saya sedih dan penuh kesalahan:

Uncaught Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.
    React 

Saya telah melalui langkah-langkah react debug di atas; tampaknya tidak ada yang benar. Haruskah ini berhasil? Apakah ini hanya Fable 3? (Saya masih menggunakan Fable 2.)

Pemahaman saya adalah bahwa atribut reactcomponent membutuhkan fable 3 untuk berfungsi karena ini adalah plugin kompiler fable 3

@landy ah, pasti berhasil. Biar saya bekerja Fable 3, akan melaporkan kembali dalam satu menit

Hei! Ya, itu memperbaiki saya - Saya menggunakan PR ini sebagai panduan untuk konversi.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat