React: RFC: Rencanakan atribut/properti elemen khusus di React 18

Dibuat pada 24 Okt 2017  ·  129Komentar  ·  Sumber: facebook/react

Ini dimaksudkan untuk mengatasi #7249. Dokumen menguraikan pro dan kontra dari berbagai pendekatan yang dapat digunakan React untuk menangani atribut dan properti pada elemen kustom.

Daftar Isi/Ringkasan

  • Latar belakang
  • Proposal

    • Opsi 1: Hanya setel properti

    • kelebihan



      • Mudah dipahami/diimplementasikan


      • Menghindari konflik dengan atribut global masa depan


      • Mengambil keuntungan dari elemen kustom "upgrade"


      • Elemen khusus diperlakukan seperti komponen Bereaksi lainnya



    • Kontra



      • Mungkin perubahan yang merusak


      • Perlu referensi untuk mengatur atribut


      • Tidak jelas bagaimana rendering sisi server akan bekerja



    • Opsi 2: Properti-jika-tersedia

    • kelebihan



      • Perubahan tanpa putus



    • Kontra



      • Pengembang perlu memahami heuristik


      • Kembali ke atribut mungkin bertentangan dengan global masa depan



    • Opsi 3: Bedakan properti dengan sigil

    • kelebihan



      • Perubahan tanpa henti yang dapat diikuti oleh pengembang


      • Mirip dengan bagaimana perpustakaan lain menangani atribut/properti


      • Sistemnya eksplisit



    • Kontra



      • Ini sintaks baru


      • Tidak jelas bagaimana rendering sisi server akan bekerja



    • Opsi 4: Tambahkan objek atribut

    • kelebihan



      • Sistemnya eksplisit


      • Memperluas sintaks juga dapat memecahkan masalah dengan penanganan acara



    • Kontra



      • Ini sintaks baru


      • Ini mungkin perubahan yang menghancurkan


      • Ini mungkin perubahan yang lebih besar daripada proposal sebelumnya



    • Opsi 5: API untuk menggunakan elemen khusus

    • kelebihan



      • Sistemnya eksplisit


      • Perubahan tanpa putus


      • Idiomatik untuk Bereaksi



    • Kontra



      • Bisa jadi banyak pekerjaan untuk komponen yang kompleks


      • Mungkin mengasapi ukuran bundel


      • Konfigurasi perlu mengikuti komponen



Latar belakang

Ketika React mencoba mengirimkan data ke elemen kustom, ia selalu melakukannya menggunakan atribut HTML.

<x-foo bar={baz}> // same as setAttribute('bar', baz)

Karena atribut harus diserialisasi ke string, pendekatan ini menimbulkan masalah ketika data yang dikirimkan adalah objek atau larik. Dalam skenario itu, kita berakhir dengan sesuatu seperti:

<x-foo bar="[object Object]">

Solusi untuk ini adalah dengan menggunakan ref untuk mengatur properti secara manual.

<x-foo ref={el => el.bar = baz}>

Solusi ini terasa sedikit tidak perlu karena sebagian besar elemen khusus yang dikirimkan hari ini ditulis dengan pustaka yang secara otomatis menghasilkan properti JavaScript yang mendukung semua atribut yang terbuka. Dan siapa pun yang menulis elemen kustom vanilla didorong untuk mengikuti praktik ini juga. Kami ingin melihat komunikasi runtime dengan elemen kustom di React menggunakan properti JavaScript secara default.

Dokumen ini menguraikan beberapa proposal tentang bagaimana React dapat diperbarui untuk mewujudkannya.

Proposal

Opsi 1: Hanya setel properti

Daripada mencoba memutuskan apakah properti atau atribut harus disetel, React selalu bisa mengatur properti pada elemen kustom. Bereaksi TIDAK akan memeriksa untuk melihat apakah properti ada pada elemen sebelumnya.

Contoh:

<x-foo bar={baz}>

Kode di atas akan menghasilkan React yang mengatur properti .bar dari elemen x-foo sama dengan nilai baz .

Untuk nama properti camelCased, React dapat menggunakan gaya yang sama dengan yang digunakan sekarang untuk properti seperti tabIndex .

<x-foo squidInk={pasta}> // sets .squidInk = pasta

kelebihan

Mudah dipahami/diimplementasikan

Model ini sederhana, eksplisit, dan cocok dengan "JavaScript-centric API to the DOM" React.

Elemen apa pun yang dibuat dengan pustaka seperti Polymer atau Skate akan secara otomatis menghasilkan properti untuk mendukung atribut yang terbuka. Semua elemen ini harus "berfungsi" dengan pendekatan di atas. Pengembang komponen vanilla yang ditulis tangan didorong untuk mendukung atribut dengan properti karena mencerminkan betapa modernnya (yaitu tidak eksentrik seperti <input> ) elemen HTML5 ( <video> , <audio> , dll.) telah dilaksanakan.

Menghindari konflik dengan atribut global masa depan

Saat React menetapkan atribut pada elemen kustom, selalu ada risiko bahwa versi HTML yang akan datang akan mengirimkan atribut dengan nama yang sama dan merusak sesuatu. Kekhawatiran ini telah didiskusikan dengan penulis spesifikasi tetapi tidak ada solusi yang jelas untuk masalah tersebut. Menghindari atribut sepenuhnya (kecuali jika pengembang secara eksplisit menetapkan atribut menggunakan ref ) dapat menghindari masalah ini hingga browser menemukan solusi yang lebih baik.

Mengambil keuntungan dari elemen kustom "upgrade"

Elemen khusus dapat ditingkatkan dengan malas di halaman dan beberapa pola PRPL mengandalkan teknik ini. Selama proses pemutakhiran, elemen kustom dapat mengakses properti yang diteruskan ke sana oleh React—bahkan jika properti tersebut disetel sebelum definisi dimuat—dan menggunakannya untuk merender status awal.

Elemen khusus diperlakukan seperti komponen Bereaksi lainnya

Ketika komponen React mengirimkan data satu sama lain, mereka sudah menggunakan properti. Ini hanya akan membuat elemen khusus berperilaku dengan cara yang sama.

Kontra

Mungkin perubahan yang merusak

Jika pengembang telah membuat elemen kustom vanilla yang hanya memiliki atribut API, maka mereka perlu memperbarui kode mereka atau aplikasi mereka akan rusak. Cara mengatasinya adalah dengan menggunakan ref untuk mengatur atribut (dijelaskan di bawah).

Perlu referensi untuk mengatur atribut

Dengan mengubah perilaku sehingga properti lebih disukai, itu berarti pengembang perlu menggunakan ref untuk menetapkan atribut secara eksplisit pada elemen khusus.

<custom-element ref={el => el.setAttribute('my-attr', val)} />

Ini hanyalah kebalikan dari perilaku saat ini di mana pengembang membutuhkan ref untuk menetapkan properti. Karena pengembang jarang perlu menetapkan atribut pada elemen khusus, ini tampaknya merupakan pertukaran yang masuk akal.

Tidak jelas bagaimana rendering sisi server akan bekerja

Tidak jelas bagaimana model ini akan dipetakan ke elemen kustom rendering sisi server. React dapat berasumsi bahwa properti memetakan ke atribut bernama serupa dan mencoba mengaturnya di server, tetapi ini jauh dari antipeluru dan mungkin memerlukan heuristik untuk hal-hal seperti properti camelCased -> atribut dash-cased.

Opsi 2: Properti-jika-tersedia

Saat runtime, React dapat mencoba mendeteksi jika ada properti pada elemen kustom. Jika properti ini ada, React akan menggunakannya, jika tidak maka akan mundur ke pengaturan atribut. Ini adalah model yang digunakan Preact untuk menangani elemen khusus.

Implementasi kode semu:

if (propName in element) {
  element[propName] = value;
} else {
  element.setAttribute(propName.toLowerCase(), value);
}

Kemungkinan langkah:

  • Jika suatu elemen memiliki properti yang ditentukan, React akan menggunakannya.

  • Jika sebuah elemen memiliki properti yang tidak terdefinisi, dan React mencoba meneruskannya dengan data primitif (string/angka/boolean), ia akan menggunakan atribut.

    • Alternatif: Peringatkan dan jangan disetel.
  • Jika suatu elemen memiliki properti yang tidak terdefinisi, dan React mencoba untuk meneruskannya ke objek/array, ia akan menetapkannya sebagai properti. Ini karena some-attr="[object Object]" tidak berguna.

    • Alternatif: Peringatkan dan jangan disetel.
  • Jika elemen sedang dirender di server, dan React mencoba meneruskannya dengan string/angka/boolean, itu akan menggunakan atribut.

  • Jika elemen sedang dirender di server, dan React mencoba meneruskannya sebagai objek/array, itu tidak akan melakukan apa pun.

kelebihan

Perubahan tanpa putus

Dimungkinkan untuk membuat elemen khusus yang hanya menggunakan atribut sebagai antarmukanya. Gaya penulisan ini TIDAK dianjurkan, tetapi itu mungkin terjadi. Jika pembuat elemen kustom mengandalkan perilaku ini, maka perubahan ini tidak akan mengganggu mereka.

Kontra

Pengembang perlu memahami heuristik

Pengembang mungkin bingung ketika React menetapkan atribut alih-alih properti tergantung pada bagaimana mereka memilih untuk memuat elemen mereka.

Kembali ke atribut mungkin bertentangan dengan global masa depan

Sebastian mengemukakan kekhawatiran bahwa menggunakan in untuk memeriksa keberadaan properti pada elemen kustom mungkin secara tidak sengaja mendeteksi properti pada superclass (HTMLElement).

Ada juga potensi konflik lain dengan atribut global yang dibahas sebelumnya dalam dokumen ini.

Opsi 3: Bedakan properti dengan sigil

React dapat melanjutkan pengaturan atribut pada elemen kustom, tetapi memberikan sigil yang dapat digunakan pengembang untuk mengatur properti secara eksplisit. Ini mirip dengan pendekatan yang digunakan oleh Glimmer.js .

Contoh secercah:

<custom-img @src="corgi.jpg" @hiResSrc="[email protected]" width="100%">

Dalam contoh di atas, @ sigil menunjukkan bahwa src dan hiResSrc harus meneruskan data ke elemen kustom menggunakan properti, dan width harus diserialisasi ke string atribut.

Karena komponen React sudah mengirimkan data satu sama lain menggunakan properti, mereka tidak perlu menggunakan sigil (walaupun itu akan berhasil jika mereka melakukannya, itu hanya akan menjadi berlebihan). Sebagai gantinya, ini terutama akan digunakan sebagai instruksi eksplisit untuk meneruskan data ke elemen khusus menggunakan properti JavaScript.

h/t ke @developit dari Preact untuk menyarankan pendekatan ini :)

kelebihan

Perubahan tanpa henti yang dapat diikuti oleh pengembang

Semua aplikasi elemen React + kustom yang sudah ada sebelumnya akan terus bekerja persis seperti yang mereka miliki. Pengembang dapat memilih apakah mereka ingin memperbarui kode mereka untuk menggunakan gaya sigil baru.

Mirip dengan bagaimana perpustakaan lain menangani atribut/properti

Mirip dengan Glimmer, Angular dan Vue menggunakan pengubah untuk membedakan antara atribut dan properti.

Contoh Vue:

<!-- Vue will serialize `foo` to an attribute string, and set `squid` using a JavaScript property -->
<custom-element :foo="bar” :squid.prop=”ink”>

Contoh sudut:

<!-- Angular will serialize `foo` to an attribute string, and set `squid` using a JavaScript property -->
<custom-element [attr.foo]="bar” [squid]=”ink”>

Sistemnya eksplisit

Pengembang dapat memberi tahu React apa yang mereka inginkan daripada mengandalkan heuristik seperti pendekatan properti-jika-tersedia .

Kontra

Ini sintaks baru

Pengembang perlu diajari cara menggunakannya dan perlu diuji secara menyeluruh untuk memastikannya kompatibel.

Tidak jelas bagaimana rendering sisi server akan bekerja

Haruskah sigil beralih menggunakan atribut bernama serupa?

Opsi 4: Tambahkan objek atribut

Bereaksi dapat menambahkan sintaks tambahan yang memungkinkan penulis secara eksplisit meneruskan data sebagai atribut. Jika pengembang tidak menggunakan objek atribut ini, maka data mereka akan diteruskan menggunakan properti JavaScript.

Contoh:

const bar = 'baz';
const hello = 'World';
const width = '100%';
const ReactElement = <Test
  foo={bar} // uses JavaScript property
  attrs={{ hello, width }} // serialized to attributes
/>;

Ide ini awalnya diusulkan oleh @treshugart , penulis Skate.js, dan diimplementasikan di perpustakaan val .

kelebihan

Sistemnya eksplisit

Pengembang dapat memberi tahu React apa yang mereka inginkan daripada mengandalkan heuristik seperti pendekatan properti-jika-tersedia .

Memperluas sintaks juga dapat memecahkan masalah dengan penanganan acara

Catatan: Ini di luar cakupan dokumen ini tetapi mungkin perlu disebutkan :)

Masalah #7901 meminta agar React melewati sistem kejadian sintetiknya saat pengendali kejadian deklaratif ditambahkan ke elemen kustom. Karena nama peristiwa elemen khusus adalah string arbitrer, itu berarti mereka dapat dikapitalisasi dengan cara apa pun. Untuk melewati sistem peristiwa sintetis hari ini juga berarti perlu membuat heuristik untuk memetakan nama peristiwa dari JSX ke addEventListener .

// should this listen for: 'foobar', 'FooBar', or 'fooBar'?
onFooBar={handleFooBar}

Namun, jika sintaks diperluas untuk mengizinkan atribut, itu juga dapat diperluas untuk memungkinkan acara juga:

const bar = 'baz';
const hello = 'World';
const SquidChanged = e => console.log('yo');
const ReactElement = <Test
  foo={bar}
  attrs={{ hello }}
  events={{ SquidChanged}} // addEventListener('SquidChanged', …)
/>;

Dalam model ini nama variabel digunakan sebagai nama event. Tidak diperlukan heuristik.

Kontra

Ini sintaks baru

Pengembang perlu diajari cara menggunakannya dan perlu diuji secara menyeluruh untuk memastikannya kompatibel.

Ini mungkin perubahan yang menghancurkan

Jika ada komponen yang mengandalkan properti bernama attrs atau events , itu bisa merusaknya.

Ini mungkin perubahan yang lebih besar daripada proposal sebelumnya

Untuk React 17 mungkin lebih mudah untuk membuat perubahan tambahan (seperti salah satu proposal sebelumnya) dan memposisikan proposal ini sebagai sesuatu yang perlu dipertimbangkan untuk refactor yang lebih besar nanti.

Opsi 5: API untuk menggunakan elemen khusus

Proposal ini ditawarkan oleh @sophiebits dan @gaearon dari tim React

React dapat membuat API baru untuk menggunakan elemen kustom yang memetakan perilaku elemen dengan objek konfigurasi.

Contoh kode semu:

const XFoo = ReactDOM.createCustomElementType({
  element: ‘x-foo’,
  ‘my-attr’: // something that tells React what to do with it
  someRichDataProp: // something that tells React what to do with it
});

Kode di atas mengembalikan komponen proxy, XFoo yang mengetahui cara meneruskan data ke elemen khusus tergantung pada konfigurasi yang Anda berikan. Anda akan menggunakan komponen proxy ini di aplikasi Anda alih-alih menggunakan elemen khusus secara langsung.

Contoh penggunaan:

<XFoo someRichDataProp={...} />

kelebihan

Sistemnya eksplisit

Pengembang dapat memberi tahu React perilaku persis yang mereka inginkan.

Perubahan tanpa putus

Pengembang dapat memilih untuk menggunakan objek atau melanjutkan menggunakan sistem saat ini.

Idiomatik untuk Bereaksi

Perubahan ini tidak memerlukan sintaks JSX baru, dan lebih terasa seperti API lain di React. Misalnya, PropTypes (meskipun sedang dipindahkan ke dalam paketnya sendiri) memiliki pendekatan yang agak mirip.

Kontra

Bisa jadi banyak pekerjaan untuk komponen yang kompleks

Elemen input kertas polimer memiliki 37 properti, sehingga akan menghasilkan konfigurasi yang sangat besar. Jika pengembang menggunakan banyak elemen khusus di aplikasi mereka, itu mungkin sama dengan banyak konfigurasi yang perlu mereka tulis.

Mungkin mengasapi ukuran bundel

Terkait dengan poin di atas, setiap kelas elemen kustom sekarang dikenakan biaya definisinya + ukuran objek konfigurasinya.

Catatan: Saya tidak 100% yakin apakah ini benar.

Konfigurasi perlu mengikuti komponen

Setiap kali komponen melakukan revisi versi minor yang menambahkan properti baru, konfigurasi juga perlu diperbarui. Itu tidak sulit, tetapi itu menambah perawatan. Mungkin jika konfigurasi dihasilkan dari sumber, ini tidak terlalu membebani, tetapi itu mungkin berarti perlu membuat alat baru untuk menghasilkan konfigurasi untuk setiap pustaka komponen web.

cc @sebmarkbage @gaearon @developit @treshugart @justinfagnani

DOM Discussion

Komentar yang paling membantu

Hai teman-teman, sementara kami menunggu, saya membuat shim untuk membungkus komponen web Anda di React https://www.npmjs.com/package/reactify-wc

import React from "react";
import reactifyWc from "reactify-wc";

// Import your web component. This one defines a tag called 'vaadin-button'
import "@vaadin/vaadin-button";

const onClick = () => console.log('hello world');

const VaadinButton = reactifyWc("vaadin-button");

export const MyReactComponent = () => (
  <>
    <h1>Hello world</h1>
    <VaadinButton onClick={onClick}>
      Click me!
    </VaadinButton>
  </>
)

Saya harap ini terbukti bermanfaat

(Ini adalah perampokan pertama saya ke OSS, dan salah satu open-source pertama dari sesuatu di luar kantor saya. Kritik membangun lebih dari diterima )

Semua 129 komentar

Maaf untuk bacaan yang panjang, tetapi saya ingin memastikan bahwa saya benar-benar menjelajahi setiap opsi. Saya tidak ingin terlalu membiaskan banyak hal dengan pendapat saya sendiri, tetapi jika saya berada dalam posisi untuk memilih, saya pikir saya akan memilih opsi 3.

Opsi 3 kompatibel ke belakang, deklaratif, dan eksplisit. Tidak perlu mempertahankan heuristik fallback, dan perpustakaan lain sudah menyediakan sigil/pengubah serupa.

Maaf untuk bacaan yang panjang, tetapi saya ingin memastikan bahwa saya benar-benar menjelajahi setiap opsi. Saya tidak ingin terlalu membiaskan banyak hal dengan pendapat saya sendiri, tetapi jika saya berada dalam posisi untuk memilih, saya pikir saya akan memilih opsi 3.
Opsi 3 kompatibel ke belakang, deklaratif, dan eksplisit. Tidak perlu mempertahankan heuristik fallback, dan perpustakaan lain sudah menyediakan sigil/pengubah serupa.

Saya berada di antara opsi 2 dan opsi 3, saya pikir React telah menangani perilaku dan perubahan API dengan sangat baik di masa lalu. Memperkenalkan peringatan dan tautan ke dokumen mungkin berfungsi dengan baik untuk membantu pengembang memahami apa yang terjadi di balik layar.

Opsi 3 terlihat menarik karena sifatnya yang deklaratif, saat membaca kode JSX, pengembang baru akan segera mengetahui apa yang akan dilakukan React saat merender elemen.

Komentar pada opsi 2

Pengembang mungkin bingung ketika React menetapkan atribut alih-alih properti tergantung pada bagaimana mereka memilih untuk memuat elemen mereka.

Apakah konsumen dari elemen kustom perlu memahami perbedaan ini? Atau apakah itu hanya penting bagi penulis elemen kustom? Sepertinya pembuat elemen perlu menangani atribut untuk apa pun yang digunakan dalam HTML (karena itulah satu-satunya cara data diteruskan dari penggunaan HTML) dan properti jika mereka ingin mendukung nilai kompleks atau properti yang didapat/ditetapkan dari DOM. Bahkan mungkin seorang penulis dapat memiliki sesuatu yang awalnya diimplementasikan sebagai atribut dan kemudian menambahkan properti dengan nama yang sama untuk mendukung tipe data yang lebih fleksibel dan masih mendukung properti dengan nilai yang disimpan dalam atribut.

Tabrakan penamaan dengan atribut dan properti HTMLElement masa depan tampaknya seperti kelemahan dalam standar Komponen Web secara umum karena hal itu dapat menyebabkan kesalahan terlepas dari pendekatan pengikatannya.

Jika suatu elemen memiliki properti yang tidak terdefinisi, dan React mencoba untuk meneruskannya ke objek/array, ia akan menetapkannya sebagai properti. Ini karena some-attr="[object Object]" tidak berguna.

Tampaknya membingungkan untuk mengikat secara berbeda berdasarkan nilainya. Jika pembuat elemen belum menentukan pengambil/penyetel properti untuk menangani nilai, maka menyetel properti akan menyebabkan elemen berperilaku seperti nilai yang tidak pernah ditentukan yang mungkin lebih sulit untuk di-debug.

Komentar pada opsi 3

Kontra potensial lainnya dengan opsi 3 adalah mengharuskan konsumen elemen kustom untuk mengetahui apakah elemen tersebut telah menerapkan sesuatu sebagai properti atau sebagai atribut. Jika Anda menggunakan campuran komponen React dan elemen kustom, mungkin membingungkan untuk mengatur props React menggunakan satu sintaks dan properti elemen kustom menggunakan sintaks yang berbeda.

Apakah konsumen dari elemen kustom perlu memahami perbedaan ini? Atau apakah itu hanya penting bagi penulis elemen kustom?

Saya ragu ini sebenarnya masalah besar karena, seperti yang Anda tunjukkan, pembuat elemen harus mendefinisikan atribut dan properti untuk nilai yang mendasarinya dan menerima data dari keduanya. Saya juga akan menambahkan bahwa mereka harus menjaga atribut dan properti tetap sinkron (jadi pengaturan yang satu mengatur yang lain).

Tabrakan penamaan dengan atribut dan properti HTMLElement masa depan tampaknya seperti kelemahan dalam standar Komponen Web secara umum karena hal itu dapat menyebabkan kesalahan terlepas dari pendekatan pengikatannya.

Saya setuju tetapi saya tidak yakin apakah ini adalah sesuatu yang React perlu coba selesaikan di perpustakaan mereka. Rasanya seperti masalah yang perlu dipecahkan sebagai bagian dari spesifikasi elemen kustom. Saya dapat melihat apakah kita dapat mendiskusikannya sebagai bagian dari pertemuan standar TPAC yang akan datang.

Saya harus menambahkan, untuk properti ini tidak _as_ buruk karena properti yang ditentukan elemen akan membayangi properti masa depan yang ditambahkan ke HTMLElement. Jadi, jika Anda meneruskan data ke elemen khusus sebagai properti js, itu akan terus berfungsi. Masalah utama tampaknya seputar atribut karena bersifat global.

Tampaknya membingungkan untuk mengikat secara berbeda berdasarkan nilainya. Jika pembuat elemen belum menentukan pengambil/penyetel properti untuk menangani nilai, maka menyetel properti akan menyebabkan elemen berperilaku seperti nilai yang tidak pernah ditentukan yang mungkin lebih sulit untuk di-debug.

Dalam kasus di mana elemen khusus dimuat dengan lambat dan "ditingkatkan", awalnya akan memiliki properti yang tidak ditentukan. Ini menangani kasus penggunaan dengan memastikan elemen-elemen tersebut masih menerima datanya dan mereka dapat menggunakannya setelah pemutakhiran.

Memang benar bahwa jika penulis tidak mendefinisikan pengambil/penyetel untuk suatu nilai, ini tidak akan terlalu berguna. Tetapi juga tidak berguna untuk memiliki my-attr=[object Object] . Dan karena Anda tidak tahu apakah properti tersebut benar-benar tidak terdefinisi atau jika definisinya hanya sedang dimuat malas, tampaknya paling aman untuk mengatur properti.

Kontra potensial lainnya dengan opsi 3 adalah mengharuskan konsumen elemen kustom untuk mengetahui apakah elemen tersebut telah menerapkan sesuatu sebagai properti atau sebagai atribut.

Saya pikir Anda pada dasarnya berada di kapal yang sama hari ini karena tidak ada yang memaksa penulis elemen khusus untuk mendefinisikan atribut alih-alih properti. Jadi saya dapat memiliki elemen dengan API properti saja yang tidak akan menerima data apa pun dari sistem React saat ini dan saya perlu tahu untuk menggunakan ref untuk secara langsung mengatur properti js.

Karena elemen khusus dimaksudkan sebagai primitif, tidak ada yang memaksa pembuatan atribut dan properti yang sesuai. Tapi kami berusaha sangat keras untuk mendorong melakukannya sebagai praktik terbaik, dan semua perpustakaan yang saya tahu hari ini membuat properti pendukung untuk atributnya.

[sunting]

Seperti yang Anda nyatakan di poin Anda sebelumnya:

Sepertinya pembuat elemen perlu menangani atribut untuk apa pun yang digunakan dalam HTML (karena itulah satu-satunya cara data diteruskan dari penggunaan HTML) dan properti jika mereka ingin mendukung nilai kompleks atau properti yang didapat/ditetapkan dari DOM.

Karena Anda tidak pernah tahu bagaimana pengguna akan mencoba meneruskan data ke elemen Anda, Anda akhirnya harus memiliki korespondensi atribut-properti. Saya membayangkan jika opsi 3 dikirimkan bahwa kebanyakan orang hanya akan mengikat semuanya menggunakan sigil @ karena itu akan lebih mudah. Begitulah cara saya bekerja dengan elemen kustom di Vue hari ini karena mereka mengekspos pengubah .prop .

itu mengharuskan konsumen elemen kustom untuk mengetahui apakah elemen tersebut telah menerapkan sesuatu sebagai properti atau sebagai atribut

Itu bukan sesuatu yang React harus khawatirkan seperti yang dikatakan Rob menurut pendapat saya, itu adalah tanggung jawab pembuat elemen kustom untuk memberi tahu pengguna cara kerja elemen.

Dan itu sebenarnya cara yang perlu kita lakukan hari ini, misalnya pikirkan tentang elemen <video> , katakanlah Anda perlu menonaktifkannya atau mengubah waktu saat ini di dalam sebuah komponen.

muted berfungsi sebagai atribut boolean

render() {
  return (
    <div className="video--wrapper">
      <video muted={ this.state.muted } />
    </div>
  );
}

Untuk saat ini Anda perlu membuat ref menunjuk ke elemen video dan mengubah propertinya.

render() {
  return (
    <div className="video--wrapper">
      <video ref={ el => this.video = el } muted={ this.state.muted } />
    </div>
  );
}

Kemudian buat event handler, metode instance dan setel properti secara manual ke elemen DOM.

onCurrenTimeChange(e) {
  this.video.currentTime = e.value;
}

Jika Anda memikirkannya, itu agak merusak model deklaratif yang diterapkan oleh React sendiri dengan lapisan abstrak API dan JSX-nya karena currentTime jelas merupakan status dalam komponen pembungkus, dengan pengikatan properti, kita masih memerlukan pengendali acara tetapi Model abstraksi JSX akan lebih deklaratif dan referensi tidak diperlukan hanya untuk ini:

render() {
  return (
    <div className="video--wrapper">
      <video muted={ this.state.muted } @currentTime={ this.state.currentTime } />
    </div>
  );
}

Maksud saya adalah apakah Anda mengandalkan elemen asli atau khusus, Anda masih perlu mengetahui cara mengatasinya berdasarkan dokumentasi, perbedaannya dalam kasus kedua itu harus berasal dari pembuat elemen kustom.

@cjorasch dua sen saya :)

Jika kami merancang ini dari awal, tanpa perlu mempertimbangkan kompatibilitas mundur, saya pikir opsi 1 akan menjadi yang paling idiomatis per "JavaScript-centric API to the DOM" React.

Berkenaan dengan rendering sisi server, dapatkah masalah itu diselesaikan dengan menyediakan API untuk kode aplikasi untuk memberi tahu React tentang cara memetakan properti elemen kustom ke atribut? Mirip dengan peta yang React sudah pertahankan untuk atribut yang ditentukan platform? API ini hanya perlu dipanggil sekali per nama elemen khusus (bukan untuk setiap instance-nya), dan hanya untuk properti yang tidak mengikuti korespondensi 1:1 langsung dengan atributnya, yang diharapkan relatif jarang terjadi.

Jika kita khawatir tentang perubahan yang terlalu besar ini, maka saya pikir opsi 3 juga cukup menarik. Jika sigil menandakan sebuah properti, saya akan menyarankan ".", karena itu sudah menjadi pengakses properti JavaScript. Namun, saya pikir sangat disayangkan untuk membuat setiap contoh di mana elemen kustom digunakan dalam aplikasi bertanggung jawab untuk mengetahui kapan harus menggunakan atribut vs. kapan harus menggunakan properti. Apa yang saya sukai tentang opsi 1 adalah bahwa bahkan jika properti untuk mengatribusikan peta diperlukan, kode pemetaan itu dapat diisolasi dari semua penggunaan BEJ.

Dalam kasus di mana elemen khusus dimuat dengan lambat dan "ditingkatkan", awalnya akan memiliki properti yang tidak ditentukan. Ini menangani kasus penggunaan dengan memastikan elemen-elemen tersebut masih menerima datanya dan mereka dapat menggunakannya setelah pemutakhiran.

Mungkin saya tidak mengerti proses peningkatan. Elemen biasanya memiliki properti yang didefinisikan sebagai getter/setter dalam prototipe kelas. Memeriksa propName in element akan mengembalikan nilai true karena keberadaan pengambil/penyetel meskipun nilai properti masih belum ditentukan. Selama pemutakhiran, apakah nilai properti ditetapkan pada beberapa instans sementara dan kemudian disalin ke instans aktual setelah pemuatan malas selesai?

Upgrade adalah proses dimana elemen kustom menerima kelasnya. Sebelum itu, ini bukan turunan dari kelas itu, jadi pengambil/penyetel properti tidak tersedia.

@jeremenichelli

diredam berfungsi sebagai atribut boolean

baru saja diperiksa dan juga memiliki properti yang sesuai meskipun tampaknya tidak didokumentasikan di MDN: P

Untuk saat ini Anda perlu membuat referensi yang menunjuk ke elemen video dan mengubah properti.

Ya, terkadang Anda akan menemukan API khusus properti pada elemen HTML modern. currentTime memperbarui pada frekuensi tinggi sehingga tidak masuk akal untuk mencerminkannya ke atribut HTML.

Maksud saya adalah apakah Anda mengandalkan elemen asli atau khusus, Anda masih perlu mengetahui cara mengatasinya berdasarkan dokumentasi

Ya, sayangnya tidak ada aturan atribut/properti satu ukuran untuk semua. Tapi saya pikir secara umum Anda dapat sangat bergantung pada properti dan menyediakan sintaks sehingga pengembang dapat menggunakan atribut dalam kasus khusus.

@robdodson ya , saya juga tahu tentang properti yang dibungkam Saya baru saja menggunakan keduanya untuk membuktikan bahwa sudah _di alam liar_ tidak ada aturan satu ukuran untuk semua seperti yang Anda sebutkan.

Kami harus mengandalkan dokumentasi pada elemen asli dan khusus, jadi saya tidak keberatan dengan keputusan ini.

Saat menulis cuplikan kode terakhir, saya agak menyukai pengikatan properti

@effulgentsia

Namun, saya pikir sangat disayangkan untuk membuat setiap contoh di mana elemen kustom digunakan dalam aplikasi bertanggung jawab untuk mengetahui kapan harus menggunakan atribut vs. kapan harus menggunakan properti.

Saya pikir ini sudah terjadi hari ini. Karena pustaka elemen kustom utama (polimer, skate, mungkin yang lain?) secara otomatis membuat properti pendukung untuk semua atribut yang terbuka, pengembang cukup menggunakan sigil untuk setiap properti pada elemen kustom. Mungkin akan menjadi kejadian langka bagi mereka untuk perlu beralih menggunakan atribut.

@cjorasch

RE: peningkatan. Seperti yang disebutkan @effulgentsia , Anda dapat memiliki elemen khusus di halaman tetapi memuat definisinya di lain waktu. <x-foo> awalnya akan menjadi turunan dari HTMLElement dan ketika saya memuat definisinya nanti, ia "meningkatkan" dan menjadi turunan dari kelas XFoo . Pada titik ini semua panggilan balik siklus hidupnya dieksekusi. Kami menggunakan teknik ini dalam proyek Polimer Starter Kit. Seperti ini:

<app-router>
  <my-view1></my-view1>
  <my-view2></my-view2>
</app-router>

Dalam contoh di atas, kita tidak akan memuat definisi untuk my-view2 sampai router mengubahnya.

Sangat mungkin untuk menyetel properti pada elemen sebelum dimutakhirkan, dan setelah definisi dimuat, elemen dapat mengambil data tersebut selama salah satu panggilan balik siklus hidupnya.

pengembang hanya bisa menggunakan sigil untuk setiap properti pada elemen khusus

Jika pengembang mulai melakukan itu, lalu bagaimana hal itu membedakan menggunakan properti karena Anda "bisa" dari menggunakan properti karena "harus"? Dan bukankah itu perbedaan yang diperlukan untuk rendering sisi server?

Jika pengembang mulai melakukan itu, lalu bagaimana hal itu membedakan menggunakan properti karena Anda "bisa" dari menggunakan properti karena "harus"?

Maaf, mungkin saya salah mengartikannya. Maksud saya pengembang kemungkinan akan menggunakan sigil karena akan memberikan hasil yang paling konsisten. Anda dapat menggunakannya untuk meneruskan data primitif atau data kaya seperti objek dan array dan itu akan selalu berfungsi. Saya pikir bekerja dengan properti saat runtime umumnya lebih disukai daripada bekerja dengan atribut karena atribut cenderung lebih banyak digunakan untuk konfigurasi awal.

Dan bukankah itu perbedaan yang diperlukan untuk rendering sisi server?

Mungkin saja di server sigil akan mundur ke pengaturan atribut.

Mungkin saja di server sigil akan mundur ke pengaturan atribut.

Saya tidak berpikir itu akan berhasil jika alasan sigil adalah karena itu adalah properti yang tidak ada sebagai atribut, seperti video's currentTime .

membedakan menggunakan properti karena Anda "bisa" dari menggunakan properti karena Anda "harus"

Saya pikir diferensiasi ini penting, karena ada alasan yang sama sekali berbeda untuk memilih menggunakan atribut atau properti sebagai pengoptimalan (misalnya, atribut preferensi SSR vs. properti preferensi rendering sisi klien) vs. sesuatu yang ada hanya sebagai atribut atau hanya sebuah properti.

Berkenaan dengan rendering sisi server, dapatkah masalah itu diselesaikan dengan menyediakan API untuk kode aplikasi untuk memberi tahu React tentang cara memetakan properti elemen kustom ke atribut?

Untuk lebih spesifik, saya menyarankan sesuatu seperti ini:

ReactDOM.defineCustomElementProp(elementName, propName, domPropertyName, htmlAttributeName, attributeSerializer)

Contoh:

// 'muted' can be set as either a property or an attribute.
ReactDOM.defineCustomElementProp('x-foo', 'muted', 'muted', 'muted')

// 'currentTime' can only be set as a property.
ReactDOM.defineCustomElementProp('x-foo', 'currentTime', 'currentTime', null)

// 'my-attribute' can only be set as an attribute.
ReactDOM.defineCustomElementProp('x-foo', 'my-attribute', null, 'my-attribute')

// 'richData' can be set as either a property or an attribute.
// When setting as an attribute, set it as a JSON string rather than "[object Object]".
ReactDOM.defineCustomElementProp('x-foo', 'richData', 'richData', 'richdata', JSON.stringify)

Untuk sesuatu yang hanya dapat berupa properti (di mana htmlAttributeName adalah null), SSR akan melewati rendering dan kemudian menghidrasinya pada klien.

Untuk sesuatu yang hanya dapat berupa atribut (di mana domPropertyName adalah null), React akan memanggil setAttribute() seperti saat ini di v16.

Untuk sesuatu yang bisa menjadi keduanya, React bisa memilih strategi apa pun yang paling optimal. Mungkin itu berarti selalu menetapkan sebagai properti di sisi klien, tetapi sebagai atribut sisi server. Mungkin itu berarti pengaturan sebagai atribut saat pertama kali membuat elemen, tetapi pengaturan sebagai properti saat nanti menambal dari vdom. Mungkin itu berarti hanya menetapkan sebagai atribut ketika nilainya adalah tipe primitif. Idealnya, React harus dapat mengubah strategi kapan pun diinginkan sebagai detail implementasi internal.

Ketika React menemukan prop yang defineCustomElementProp() belum dipanggil dan yang tidak didefinisikan oleh spesifikasi HTML sebagai properti atau atribut global, maka React dapat mengimplementasikan beberapa logika default. Misalnya, mungkin:

  • Di versi 17, pertahankan BC dengan v16 dan tetapkan sebagai atribut.
  • Di versi 18, asumsikan itu bisa salah satunya dan ikuti strategi paling optimal untuk itu.

Tetapi bagaimanapun juga, dengan menjaga ini sebagai API terpisah, objek JSX dan props tetap bersih dan dalam satu namespace, seperti halnya untuk komponen React dan elemen HTML non-kustom.

Maaf atas komentar yang berlebihan, tetapi saya memikirkan manfaat lain dari proposal saya di atas yang ingin saya bagikan:

Panggilan ReactDOM.defineCustomElementProp() tersebut dapat disediakan dalam file JS yang dikelola oleh pembuat elemen kustom (dalam repositori yang sama dengan tempat elemen kustom dipertahankan/didistribusikan). Itu tidak akan diperlukan untuk elemen khusus dengan korespondensi properti/atribut 1: 1 yang ketat, yang menurut pernyataan Latar Belakang masalah ini adalah rekomendasi dan kasus mayoritas. Jadi hanya pembuat elemen kustom yang tidak mengikuti rekomendasi ini yang perlu menyediakan file integrasi React. Jika pembuatnya tidak menyediakannya (misalnya, karena pembuat elemen kustom tidak peduli dengan React), maka komunitas orang yang menggunakan elemen kustom tersebut dalam aplikasi React dapat mengatur sendiri repositori pusat untuk menampung file integrasi tersebut.

Saya pikir kemungkinan sentralisasi seperti itu lebih disukai daripada solusi yang mengharuskan setiap pengguna elemen kustom untuk selalu eksplisit dengan sigil.

Opsi 3 akan menjadi pilihan saya, tetapi itu adalah perubahan yang sangat besar... Bagaimana dengan kebalikannya? Atribut memiliki awalan bukan alat peraga?

Sigils di React, saya tidak tahu bagaimana perasaan saya tentang hal itu. Spesifikasi BEJ harus dianggap universal, tidak terlalu bergantung atau bergantung pada spesifikasi browser, terutama tidak pada ketidakteraturan karena kompatibilitas ke belakang. obj[prop] = value dan obj.setAttributes(props, value) berperilaku berbeda sangat disayangkan tetapi melihat api browser secara keseluruhan, tidak mengejutkan. @ : [] akan membuat detail implementasi bocor ke permukaan dan bertentangan dengan pendekatan javascript centric. Jadi, kecuali kami memiliki spesifikasi yang melakukan hal berikut, saya pikir itu ide yang buruk: const data = <strong i="8">@myFunction</strong> // -> "[object Object]"

Jika saya harus bergantung pada komponen web, saya akan senang jika semantik disembunyikan dari React dan JSX serta memastikan mereka tidak memperkenalkan perubahan yang melanggar. Dari semua opsi, meninggalkan ref => ... di tempatnya tampaknya menguntungkan saya. ref dirancang khusus untuk mengakses objek. Dan setidaknya pengembang tahu persis apa yang terjadi, tidak ada kebocoran sigil, tidak ada atribut baru yang dapat merusak proyek yang ada.

@LeeCheneler

Opsi 3 akan menjadi pilihan saya, tetapi itu adalah perubahan yang sangat besar... Bagaimana dengan kebalikannya? Atribut memiliki awalan bukan alat peraga?

Mengapa itu akan menjadi perubahan yang menghancurkan? Perilaku atribut saat ini sebagai default akan tetap ada. Sigil akan ikut serta dan pengembang akan menggunakannya untuk menggantikan tempat dalam kode mereka di mana mereka saat ini menggunakan ref untuk meneruskan data ke elemen khusus sebagai properti JS.

@drcmda

tidak ada atribut baru yang dapat merusak proyek yang sudah ada.

Bisakah Anda menjelaskan apa yang Anda maksud dengan ini?

FYI untuk siapa pun yang mengikuti diskusi, saya telah memperbarui RFC dengan opsi ke-5 yang disarankan oleh anggota tim React.

@robdodson

Saya mengacu pada ini:

Opsi 4: Tambahkan objek atribut
Kontra
Ini mungkin perubahan yang menghancurkan

Opsi 5 tampaknya paling aman bagi kami. Ini memungkinkan kami menambahkan fitur tanpa harus membuat keputusan tentang API "implisit" sekarang karena ekosistem masih dalam fase "mencari tahu". Kami selalu dapat mengunjunginya kembali dalam beberapa tahun.

Elemen input kertas polimer memiliki 37 properti, sehingga akan menghasilkan konfigurasi yang sangat besar. Jika pengembang menggunakan banyak elemen khusus di aplikasi mereka, itu mungkin sama dengan banyak konfigurasi yang perlu mereka tulis.

Kesan saya adalah bahwa pengguna elemen kustom di React pada akhirnya akan ingin membungkus beberapa elemen kustom ke dalam komponen React untuk perilaku/kustomisasi khusus aplikasi. Ini adalah strategi migrasi yang lebih bagus untuk kasus ini jika semuanya sudah merupakan Bereaksi komponen, misalnya

import XButton from './XButton';

dan itu kebetulan dihasilkan oleh

export default ReactDOM.createCustomElementType(...)

Ini memungkinkan mereka mengganti komponen React dengan komponen kustom yang menggunakan (atau bahkan tidak menggunakan) elemen kustom kapan saja.

Jadi, jika orang akan membuat komponen React pada titik interop, kami mungkin juga menyediakan helper yang kuat untuk melakukannya. Kemungkinan juga orang akan membagikan konfigurasi tersebut untuk elemen khusus yang mereka gunakan.

Dan akhirnya, jika kita melihat ekosistem stabil, kita dapat mengadopsi pendekatan tanpa konfigurasi.

Saya pikir langkah selanjutnya di sini adalah menulis proposal terperinci tentang bagaimana konfigurasi akan terlihat untuk memenuhi semua kasus penggunaan umum. Itu harus cukup menarik untuk elemen kustom + pengguna Bereaksi, karena jika tidak menjawab kasus penggunaan umum (seperti penanganan acara) kita akan berakhir di limbo di mana fitur tidak memberikan manfaat yang cukup untuk mengimbangi verbositas .

Membangun dari komentar saya sebelumnya , bagaimana dengan:

const XFoo = ReactDOM.createCustomElementType('x-foo', {
  propName1: {
    propertyName: string | null,
    attributeName: string | null,
    attributeSerializer: function | null,
    eventName: string | null,
  }
  propName2: {
  }
  ...
});

Logikanya adalah, untuk setiap prop React pada instance XFoo:

  1. Jika eventName untuk prop tersebut bukan null, daftarkan sebagai event handler yang memanggil nilai prop (diasumsikan sebagai fungsi).
  2. Lain jika rendering sisi klien dan propertyName bukan null, setel properti elemen ke nilai prop.
  3. Lain jika attributeName bukan null, setel atribut elemen ke nilai prop string. Jika attributeSerializer bukan null, gunakan itu untuk merangkai nilai prop. Jika tidak, lakukan saja '' + propValue .

Elemen input kertas polimer memiliki 37 properti, sehingga akan menghasilkan konfigurasi yang sangat besar.

Saya ingin menyarankan bahwa konfigurasi hanya diperlukan untuk alat peraga outlier. Untuk prop apa pun pada instance XFoo yang tidak disertakan dalam konfigurasi, default ke:

  • jika nilainya adalah fungsi:
eventName: the prop name,
  • lain:
propertyName: the prop name,
attributeName: camelCaseToDashCase(the prop name),

Atau, mungkin masuk akal untuk menyimpan acara di ruang nama terpisah, dalam hal ini, hapus semua yang berkaitan dengan eventName dari komentar terakhir, dan alih-alih biarkan acara didaftarkan sebagai:

<XFoo prop1={propValue1} prop2={propValue2} events={event1: functionFoo, event2: functionBar}>
</XFoo>

@gaearon @effulgentsia apa pendapat Anda tentang kombinasi opsi 1 dan opsi 5?

Opsi 1 akan memudahkan pengguna biasa dari elemen khusus untuk meneruskan data yang kaya. Saya membayangkan skenario di mana saya membuat aplikasi dan saya hanya ingin menggunakan beberapa elemen khusus. Saya sudah tahu cara kerjanya dan saya tidak begitu tertarik sehingga saya ingin menulis konfigurasi untuk mereka.

Opsi 5 adalah untuk orang-orang yang ingin menggunakan sesuatu seperti input kertas di seluruh aplikasi mereka dan benar-benar ingin mengekspos seluruh API-nya kepada semua orang di tim mereka.

Untuk SSR opsi 1 heuristik bisa selalu menggunakan atribut jika rendering di server. Properti camelCase dikonversi menjadi atribut dash-case. Itu tampaknya menjadi pola yang cukup umum di seluruh pustaka komponen web.

Saya sangat menyukai ide kombinasi option1 + option5. Artinya untuk sebagian besar elemen khusus:

<x-foo prop1={propValue1}>

akan berfungsi seperti yang diharapkan: prop1 ditetapkan sebagai sisi klien properti dan sebagai sisi server atribut (dasbor).

Dan orang-orang dapat beralih ke opsi5 untuk apa pun yang tidak sesuai dengan hal di atas.

Ini akan menjadi perubahan besar dari cara kerja React 16. Bagi siapa saja yang mengalami kerusakan itu (misalnya, mereka menggunakan elemen khusus dengan atribut yang tidak didukung oleh properti), mereka dapat beralih ke opsi5, tetapi masih merupakan jeda. Saya menyerahkannya kepada tim React untuk memutuskan apakah itu dapat diterima.

Ah, inilah yang saya dapatkan karena membaca ini dengan cepat di kereta @robdodson ️ ... Tidak terlalu menyukai opsi 3 sekarang Saya membacanya sebagai alat peraga all in on yang diawali, maka saya ragu-ragu.

Opsi 5 tampaknya masuk akal dan lugas.

Saya suka arah tujuan @effulgentsia . Apakah ada alasan mengapa itu tidak bisa:

const XFoo = ReactDOM.createCustomElementType('x-foo', {
  propName1: T.Attribute,
  propName2: T.Event,
  propName3: T.Prop
})

Atau apakah mendukung banyak jenis pada satu prop berharga?

Saya ragu dengan aliran ini @effulgentsia :

jika nilainya adalah fungsi:
eventName: nama prop,
lain:
propertyName: nama prop,
atributName: camelCaseToDashCase(nama prop),

Saya rasa saya tidak ingin prop fungsi menjadi default ke suatu acara, dan apakah menetapkan propertyName dan attributeName masuk akal? Kapan Anda ingin keduanya didukung untuk meniru pertanyaan di atas? 🙂

@LeeCheneler :

Mengutip dari kelebihan Opsi 1 ringkasan masalah:

Elemen apa pun yang dibuat dengan pustaka seperti Polymer atau Skate akan secara otomatis menghasilkan properti untuk mendukung atribut yang terbuka. Semua elemen ini harus "berfungsi" dengan pendekatan di atas. Pengembang komponen vanilla yang ditulis tangan didorong untuk mendukung atribut dengan properti karena mencerminkan betapa modernnya (yaitu tidak eksentrik seperti <input> ) elemen HTML5 ( <video> , <audio> , dll.) telah dilaksanakan.

Jadi itulah alasan mengapa menetapkan propertyName dan attributeName masuk akal: karena ini mencerminkan apa yang sebenarnya terjadi untuk elemen yang mengikuti praktik terbaik. Dan dengan membuat React sadar akan hal itu, ini memungkinkan React untuk memutuskan mana yang akan digunakan berdasarkan situasi: seperti menggunakan properti untuk rendering sisi klien dan atribut untuk rendering sisi server. Untuk elemen kustom yang tidak mengikuti praktik terbaik dan memiliki beberapa atribut tanpa properti yang sesuai dan/atau beberapa properti tanpa atribut yang sesuai, React perlu menyadari hal itu, sehingga properti tanpa atribut tidak dirender selama SSR dan properti -less-attributes dapat diatur dengan setAttribute() selama rendering sisi klien.

Dengan proposal Anda, itu berpotensi dilakukan dengan menggabungkan bendera, seperti:

propName1: T.Property | T.Attribute,

Namun, itu tidak akan memberikan cara untuk menyatakan bahwa nama atribut berbeda dari nama properti (misalnya, camelCase ke dash-case). Juga tidak akan memberikan cara untuk mengekspresikan cara membuat serial objek kaya ke atribut selama SSR (perilaku "[objek objek]" saat ini tidak berguna).

Saya tidak berpikir saya ingin prop fungsi menjadi default ke suatu acara

Ya, saya pikir saya juga setuju dengan itu, maka komentar lanjutannya . Terima kasih telah memvalidasi keraguan saya dengan itu!

Berikut ini adalah pemikiran untuk versi yang kurang bertele-tele dari saran saya sebelumnya :

const XFoo = ReactDOM.createCustomElementType('x-foo', {
  UNREFLECTED_ATTRIBUTES: [
    'my-attr-1',
    'my-attr-2',
  ],
  UNREFLECTED_PROPERTIES: [
    'myProp1',
    'myProp2',
  ],
  REFLECTED_PROPERTIES: {
    // This is default casing conversion, so could be omitted.
    someVeryLongName1: 'some-very-long-name-1',

    // In case anyone is still using all lowercase without dashes.
    someVeryLongName2: 'someverylongname2',

    // When needing to define a function for serializing a property to an attribute.
    someRichData: ['some-rich-data', JSON.stringify],
  },
});

Dan per komentar kode di atas, saya sangat mendesak untuk tidak mengharuskan setiap properti yang direfleksikan untuk didefinisikan, melainkan default apa pun yang tidak didefinisikan sebagai secara otomatis menjadi properti yang direfleksikan yang nama atributnya adalah versi dasbor.

Masuk akal @effulgentsia 👍

Saya suka contoh kedua Anda tetapi apakah itu tidak terbuka untuk ledakan kombinatorial jika lebih banyak jenis ditambahkan, ala acara + apa pun yang masuk akal?

- UNREFLECTED_ATTRIBUTES
- UNREFLECTED_PROPERTIES
- UNREFLECTED_EVENTS
- REFLECTED_PROPERTIES_ATTRIBUTES
- REFLECTED_PROPERTIES_EVENTS
- REFLECTED_ATTRIBUTES_EVENTS
- REFLECTED_PROPERTIES_ATTRIBUTES_EVENTS
...

Meskipun saya kira Anda tidak ingin mencampur acara dengan prop atau atribut Atribut & prop mungkin adalah satu-satunya hal yang ingin Anda tiru.

Saya pikir ada peluang di sini untuk komunitas React dan Web Component untuk menyelaraskan praktik terbaik. Bereaksi memiliki pendapat di sini akan sangat membantu penulis elemen kustom dipandu ke arah yang benar karena adopsi yang luas dan bobot yang dibawa oleh pendapatnya.

Meskipun saya telah menulis implementasi opsi 4, saya selalu terjebak dengan keharusan memisahkan atribut dan peristiwa dari properti. Idealnya, saya lebih suka opsi 1. Secara praktis, saya pikir saya lebih suka opsi 2 dengan pintu keluar.

Opsi 1 ideal tetapi ada banyak jenis atribut yang tidak memiliki properti yang sesuai (aria / data), jadi itu akan memerlukan heuristik ekstra di sekitar ini dan jika ada kasus tepi di mana elemen mungkin memiliki atribut yang seharusnya memiliki properti, tetapi jangan menerapkannya karena alasan apa pun. Saya merasa ini adalah pilihan yang harus dipertimbangkan dengan hati-hati, tetapi mungkin layak untuk jangka panjang.

Opsi 2 lebih disukai karena ini adalah perubahan yang tidak melanggar. Ini akan berfungsi untuk semua situasi di mana definisi elemen kustom didaftarkan sebelum instance dibuat (atau dimuat sebelum properti ditetapkan). Seni sebelumnya untuk opsi ini adalah Preact (cc @developit) dan sejauh ini berfungsi dengan baik. Turun ke jalur ini memberikan implementasi yang cukup kuat dan tidak melanggar yang telah dibuktikan oleh varian React yang sukses dan berfungsi di sebagian besar situasi. Jika ada, itu memberi React solusi jangka pendek sementara solusi yang lebih baik dinilai untuk jangka panjang.

Untuk situasi (situasi s ?) di mana itu tidak berfungsi - pemuatan definisi elemen khusus yang ditangguhkan dan lainnya yang belum kami bahas - pintu keluar seperti apa yang telah dilakukan Incremental DOM , dapat diimplementasikan. Ini mirip dengan apa yang @effulgentsia usulkan, tetapi akan menskalakan lebih baik ke x jumlah elemen khusus. Jika konsumen ingin melakukannya per elemen kustom, mereka masih bisa, karena itu hanya fungsi. Hal ini memungkinkan React untuk memiliki pendapat, keluar dari lubang dan memenuhi semua kasus penggunaan dengan menyerahkan tanggung jawab kepada konsumen untuk semua kasus tepi. Ini juga sesuatu yang sebelumnya sudah saya diskusikan dengan @developit tentang implementasi di Preact. Keselarasan antara Preact / React di sini akan menjadi kemenangan besar.

Tentang perhatian dengan atribut HTML masa depan, ini adalah sesuatu yang tidak dapat kita selesaikan, jadi saya tidak berpikir kita harus terjebak dalam hal itu di sini.

Panggilan ReactDOM.defineCustomElementProp() itu dapat disediakan dalam file JS yang dikelola oleh pembuat elemen khusus

Ini akan mengikat implementasi elemen kustom ke implementasi khusus perpustakaan (dalam hal ini Bereaksi). Menurut saya itu terlalu membebani elemen kustom penulis. Selain itu, bagi penulis yang tidak menggunakan React, meyakinkan mereka untuk mengirimkan definisi tersebut ke dalam diskusi politik yang tidak diinginkan oleh siapa pun.

Mendefinisikan pemanggilan API semacam itu oleh pengguna elemen khusus dengan hanya properti/atribut yang sebenarnya digunakan pengguna adalah lebih sedikit kode untuk dipelihara dan lebih ekspresif.

Bahkan jika penulis perpustakaan tidak menggunakan React, saya berpendapat bahwa ini adalah UX yang lebih baik bagi klien komponen web tersebut untuk menentukan konfigurasi properti sekali dan kemudian menggunakannya.

Pertama kali Anda menggunakan komponen web yang membutuhkan properti, sama sulitnya dengan menambahkan sigil (lebih bertele-tele, tetapi juga lebih eksplisit) tetapi kemudian lebih mudah untuk penggunaan selanjutnya karena Anda tidak perlu memikirkannya untuk setiap situs panggilan dari komponen itu. Dalam kedua kasus tersebut, Anda perlu memahami perbedaan properti/atribut saat mengadopsi komponen web baru, tetapi dengan konfigurasi bersama tunggal, Anda tidak perlu setiap pengguna komponen itu dalam aplikasi yang sama untuk memikirkannya.

Kami berpotensi mengizinkan pemetaan ulang nama properti dalam konfigurasi itu untuk memungkinkan membuat lebih banyak nama React-idiomatik di sana. Jalur pemutakhiran ke pembungkus yang lebih canggih, jika diperlukan, juga lebih lancar karena Anda dapat mengganti XFoo dengan komponen React kustom yang melakukan logika terjemahan mewah apa pun yang dibutuhkan.

Pada dasarnya: jika mungkin orang tidak memikirkan konfigurasi properti setiap kali mereka menggunakan komponen, saya lebih suka pendekatan itu. Itu sebabnya saya menyarankan opsi 5. Saya pikir ini lebih ergonomis daripada 3 dan 4 sementara sama-sama fleksibel.

Opsi 1 dan 2 tidak bekerja dengan baik dengan rendering server (pembuatan HTML), dan opsi 2 juga menciptakan bahaya peningkatan untuk pembuat komponen web di mana sekarang menambahkan properti dengan nama yang sama dengan atribut yang ada merupakan perubahan yang melanggar. Jika kami memutuskan bahwa SSR tidak berguna maka opsi 1 cukup menarik dari perspektif React. Saya tidak tahu apakah itu akan cukup komprehensif dalam praktiknya - apakah penulis komponen mengekspos semuanya melalui properti?

@treshugart tanpa terlalu jauh ke dalam bikeshedding, apakah Anda pikir Anda bisa menunjukkan bagaimana Anda mengharapkan "escape hatch" bekerja? Kode semu baik-baik saja. Hanya agar kita semua berada di halaman yang sama.

Maaf @sophiebits baru melihat balasan Anda. Saya ingin menanggapi beberapa poin setelah membacanya beberapa kali lagi tetapi ingin segera menanggapi yang ini:

Saya tidak tahu apakah itu akan cukup komprehensif dalam praktiknya - apakah penulis komponen mengekspos semuanya melalui properti?

Setiap komponen yang dibuat dengan Polymer atau Skate akan mengekspos semuanya melalui properti. Mungkin ada beberapa outlier langka (mungkin menyetel atribut hanya untuk gaya atau sesuatu) tetapi sebaliknya saya pikir semuanya selalu didukung oleh properti. Saya cukup yakin bahwa sebagian besar komponen web dalam produksi dibuat menggunakan salah satu dari dua perpustakaan ini.

Jika seseorang menulis tangan komponen web vanilla, tidak ada yang memaksa mereka untuk mengekspos semuanya melalui properti, tetapi kami mendorong mereka melakukannya dalam dokumen dan contoh praktik terbaik kami .

Untuk apa nilainya, tidak ada yang memaksa mereka untuk menggunakan atribut. Definisi elemen khusus hanyalah sebuah kelas sehingga pengembang dapat melakukan apa pun yang mereka inginkan. Namun dalam praktiknya kebanyakan orang lebih suka menggunakan abstraksi seperti Polymer atau Skate untuk mencetak komponen mereka, jadi mereka mendapatkan API properti secara gratis.

Mungkin pendekatan terbaik adalah melakukan properti selalu di sisi klien dan kemudian mendukung peta konfigurasi gaya Opsi 5 dari nama properti primitif untuk mengatribusikan nama bagi orang-orang yang ingin mendukung SSR di aplikasi mereka.

@sophiebits : Saya pikir itu ide yang bagus, kecuali sejauh ini merupakan perubahan besar bagi orang-orang yang telah menulis aplikasi React mereka menggunakan nama atribut. Sebagai contoh:

<x-foo long-name={val} />

Tapi bagaimana dengan aturan untuk "melakukan properti" jika nama prop tidak memiliki tanda hubung dan "melakukan atribut" jika ada?

@robdodson : apakah Anda mengetahui kerangka atau praktik elemen khusus di luar sana di mana orang akan memiliki casing atribut yang berbeda dari properti yang sesuai, tanpa mengandung tanda hubung? Yaitu, atribut longname dengan properti longName ? Itu sebenarnya tampaknya menjadi pola yang jauh lebih umum dengan elemen HTML bawaan dan atribut global (mis., contenteditable => contentEditable ), tetapi saya tidak jelas apakah sekarang cukup berkecil hati untuk atribut elemen khusus berkat Polymer dan Skate. Jika masih bermasalah, maka BEJ yang ada dengan:

<x-foo longname={val} />

akan gagal sebagai set properti jika propertinya longName .

@effulgentsia Saya hanya bisa berbicara untuk Skate, tetapi kami hanya menyarankan menggunakan atribut API jika menulis HTML, yang - untuk semua maksud dan tujuan - juga dapat diklasifikasikan sebagai rendering server. Jika Anda melakukan sesuatu melalui JS, Anda harus mengatur alat peraga. API props secara otomatis melakukan sinkronisasi / deserialisasi satu arah dari atribut, dan menurunkan nama atribut dengan membuat tanda hubung nama properti (camelCase menjadi camel-case, dll). Perilaku ini secara keseluruhan dapat dikonfigurasi tetapi kami mendorong praktik terbaik untuk menjadi yang disebutkan di atas.

Seperti yang dinyatakan oleh banyak orang, alat peraga membuat SSR sulit, dan ini adalah kekhawatiran yang valid. Karena sepertinya sebagian besar lebih memilih opsi 1, mungkin kami mencoba dan mendorong dengan proposal @sophiebits untuk mengatur alat peraga pada klien sambil memberikan fallback/pemetaan? Saya berasumsi ini berarti bahwa atribut akan ditetapkan di server?

Sebagai contoh, inilah cara Anda dapat mengimplementasikan carry over state dan props dari server ke klien dengan Skate (dan elemen kustom apa pun yang mengimplementasikan renderedCallback() dan props dan / atau state setter. Melakukannya pada level elemen kustom adalah hal yang sepele. Jika React melakukan pengaturan atribut di server, rehidrasi pada dasarnya akan sama. Pembuat komponen skate sebenarnya tidak perlu melakukan apa pun seperti yang kita lakukan 'd sudah memberikan logika deserialisasi untuk mereka.

@robdodson Saya akan melakukan hal yang mirip dengan apa yang dilakukan DOM Inkremental. Ini akan terlihat seperti:

const isBrowser = true; // this would actually do the detection
const oldAttributeHook = ReactDOM.setAttribute;

// This is much like the IDOM impl but with an arguably more clear name.
ReactDOM.setAttribute = (element, name, value) => {
  // This is essentially option 2, but with the added browser check
  // to keep attr sets on the server.
  if (isBrowser && name in element) {
    element[name] = value;
  } else {
    oldAttributeHook(element, name, value);
  }
};

@sophiebits

opsi 2 juga menciptakan bahaya pemutakhiran untuk pembuat komponen web di mana sekarang menambahkan properti dengan nama yang sama dengan atribut yang ada merupakan perubahan yang melanggar.

Saya pikir ini mungkin tidak dapat dihindari mengingat cara atribut bekerja di platform. Jika Anda SSR elemen kustom, dan karena itu harus menulis ke atribut, Anda juga berisiko bahwa platform akan mengirimkan atribut bernama serupa di masa mendatang. Seperti yang disebutkan @treshugart sebelumnya , saya tidak berpikir itu adalah sesuatu yang React (atau perpustakaan apa pun) yang diberdayakan untuk dipecahkan. Ini adalah sesuatu yang ingin saya bahas dengan penulis spesifikasi komponen web di TPAC untuk melihat apakah kami dapat memperbaikinya di ruang elemen khusus.

Saya tidak yakin apakah itu mengubah pikiran Anda sama sekali tentang opsi 2 😁 tapi saya ingin menyebutkannya karena opsi 2 memiliki beberapa bonus bagus dan Preact tampaknya membuktikannya dalam praktik.

Mungkin pendekatan terbaik adalah melakukan properti selalu di sisi klien dan kemudian mendukung peta konfigurasi gaya Opsi 5 dari nama properti primitif untuk mengatribusikan nama bagi orang-orang yang ingin mendukung SSR di aplikasi mereka.

+1, saya mendukung untuk terus menuju ke arah ini.


@effulgentsia

Saya pikir itu ide yang bagus, kecuali sejauh itu merupakan perubahan besar bagi orang-orang yang telah menulis aplikasi React mereka menggunakan nama atribut.

Opsi 2 akan menyelesaikannya :)
Kalau tidak, mungkin perlu ada heuristik yang digabungkan dengan opsi 1 yang memetakan atribut dasbor ke properti camelCased.

Tapi bagaimana dengan aturan untuk "melakukan properti" jika nama prop tidak memiliki tanda hubung dan "melakukan atribut" jika ada?

Sepertinya Preact akan mengatur atribut jika ada tanda hubung di namanya. Saya berasumsi itu karena mereka menggunakan opsi 2 dan long-name tidak lulus pemeriksaan in sehingga jatuh kembali ke atribut ( source ).

Saya pribadi menyukai perilaku ini, tetapi itu kembali ke ranah pengaturan atribut dan kemungkinan konflik di masa depan, jadi saya pikir @sophiebits harus mempertimbangkan.

apakah Anda mengetahui kerangka atau praktik elemen khusus di luar sana di mana orang akan memiliki casing atribut yang berbeda dari properti yang sesuai, tanpa mengandung tanda hubung?

Tidak yang saya tahu. Tanda hubung adalah cara mudah bagi perpustakaan untuk mengetahui di mana harus membawa tas unta. Jika Anda sedang menulis komponen web Vanilla, Anda dapat melakukan longname/longName dan hanya opsi 2 yang akan menyelamatkan Anda karena tidak akan menemukan properti longname , tetapi akan mundur ke yang digunakan sebelumnya longname atribut.

Untuk apa nilainya, sepertinya Preact, sebagai upaya terakhir, akan memanggil toLowerCase() pada properti yang tidak dikenalinya sebelum menyetel atribut. Jadi jika Anda melakukan SSR <x-foo longName={bar}/> itu juga akan kembali dengan benar ke atribut longname="" .


@treshugart

mungkin kita mencoba dan mendorong maju dengan proposal @sophiebits untuk mengatur alat peraga pada klien sambil memberikan fallback/pemetaan? Saya berasumsi ini berarti bahwa atribut akan ditetapkan di server?

ya, dan ya.

Saya akan melakukan hal yang mirip dengan apa yang dilakukan DOM Inkremental

Apakah gagasan bahwa setiap elemen (atau kelas dasarnya) perlu melakukan campuran ini?

btw, terima kasih semua untuk terus berpartisipasi dalam diskusi, saya tahu ini sudah cukup lama ❤️

Tidak yakin saya memahami contoh terakhir di https://github.com/facebook/react/issues/11347#issuecomment -339858314 tetapi sangat tidak mungkin kami menyediakan kait global yang dapat ditimpa seperti ini.

@gaearon Saya pikir Trey baru saja menunjukkan perubahan bersih sebagai patch monyet, mungkin itu akan ditulis ke dalam implementasi ReactDOM itu sendiri.

Berdasarkan komentar baru-baru ini, apa pendapat Anda semua tentang proposal ini?

  1. Untuk BC, jangan ubah apa pun tentang cara kerja elemen kustom huruf kecil di React. Dengan kata lain, JSX seperti <x-foo ... /> akan terus bekerja dengan cara yang sama di React 17 seperti pada 16. Atau, jika perbaikan bug _minor_ diinginkan, buka edisi terpisah untuk membahasnya.

  2. Tambahkan API tanpa konfigurasi untuk membuat komponen React dengan semantik elemen kustom yang lebih baik. Misalnya, const XFoo = ReactDOM.customElement('x-foo'); .

  3. Untuk komponen yang dibuat di atas, gunakan semantik berikut:

  4. Untuk prop apa pun di XFoo yang merupakan nama prop React yang dicadangkan ( children , ref , yang lain?), terapkan semantik React yang biasa padanya (jangan atur sebagai atribut atau properti pada simpul DOM elemen khusus).
  5. Untuk atribut atau properti global HTMLElement apa pun yang ditentukan oleh spesifikasi HTML (termasuk data-* dan aria-* ), lakukan hal yang sama dengan props tersebut seperti yang akan dilakukan React dengan mereka jika mereka berada di div elemen. Dengan kata lain, bagaimana React menerapkan props pada <XFoo data-x={} className={} contentEditable={} /> ke node DOM harus identik dengan bagaimana ia melakukannya untuk <div data-x={} className={} contentEditable={} /> (baik untuk sisi klien dan untuk SSR).
  6. Untuk prop apa pun di XFoo yang berisi tanda hubung (selain atribut global yang diizinkan di atas), berikan peringatan (untuk memberi tahu pengembang bahwa XFoo adalah API yang berpusat pada properti, bukan yang berpusat pada atribut) dan tidak melakukan apa pun dengannya (tidak mengaturnya sebagai properti atau atribut).
  7. Untuk prop apa pun di XFoo yang dimulai dengan garis bawah atau huruf ASCII atas, jangan lakukan apa pun dengannya (dan mungkin berikan peringatan?). Tidak ada cara yang disarankan untuk memberi nama properti untuk elemen khusus, jadi simpan ruang nama tersebut untuk semantik di masa mendatang (misalnya, lihat #4 di bawah).
  8. Untuk semua props lain di XFoo, saat merender sisi klien, atur pada simpul DOM sebagai properti. Untuk SSR, jika nilainya primitif, buat sebagai atribut; jika non-primitif, lewati rendering dan tetapkan sebagai properti sisi klien selama hidrasi. Untuk rendering SSR sebagai atribut, camelCaseToDashCase namanya.

  9. Untuk komponen yang dibuat melalui API di #2 di atas, pesan nama prop yang akan digunakan untuk pendengar acara. Misalnya, 'events' atau 'eventListeners' . Atau, jika tidak ingin bertentangan dengan potensi nama properti elemen kustom tersebut, maka '_eventListeners' atau 'EventListeners' . Implementasi XFoo dibuat oleh ReactDom akan secara otomatis mendaftarkan event listener ini pada node DOM.

  10. Untuk kasus tepi (misalnya, menggunakan elemen kustom yang implementasi di atas tidak diinginkan atau tidak memadai), pengembang aplikasi dapat mengimplementasikan komponen React mereka sendiri untuk melakukan hal khusus apa pun yang mereka perlukan. Yaitu, mereka tidak perlu menggunakan ReactDOM.customElement() atau mereka dapat memperpanjangnya.

  11. Untuk orang-orang yang menginginkan semua perilaku di atas, tetapi ingin BEJ mereka menggunakan nama elemen kustom huruf kecil ( <x-foo /> daripada <XFoo /> , untuk alasan serupa yang lebih disukai orang yang terbiasa menulis HTML <div> lebih dari <Div> ), mereka dapat melakukan monkey-patch React.createElement(). Ini akan menjadi tambalan monyet yang cukup sederhana: ambil saja argumen pertama dan jika cocok dengan nama elemen khusus yang Anda inginkan (apakah itu daftar tertentu atau string apa pun dengan semua huruf kecil dan setidaknya satu tanda hubung), lalu panggil ReactDOM.customElement() pada nama itu dan meneruskan hasil dan argumen yang tersisa ke React.createElement() .

@developit @gaearon bisa juga. Jika "pemetaan" diperlukan, saya pikir kail lebih berkelanjutan. Namun, itu juga dimaksudkan untuk menunjukkan perubahan bersih jika diterapkan di inti ReactDOM, seperti yang ditunjukkan Jason.

Untuk BC, jangan ubah apa pun tentang cara kerja elemen kustom huruf kecil di React. Dengan kata lain, BEJ menyukai akan terus bekerja dengan cara yang sama di React 17 seperti di 16. Atau, jika perbaikan bug kecil diinginkan untuk itu, buka edisi terpisah untuk membahasnya.

Secara pribadi saya lebih suka untuk dapat menggunakan elemen <x-foo> , apa adanya, dan dengan mudah meneruskan propertinya tanpa perlu membungkusnya terlebih dahulu.

Jika memungkinkan, saya lebih suka menggunakan saran @sohpiebits dari opsi 1 (properti sisi klien) dan 5 (konfigurasi untuk SSR). Saya masih berharap bahwa mungkin orang akan mempertimbangkan kembali opsi2 (mungkin opsi 2 + 5?) untuk bonus kompatibilitas mundur.

@gaearon apakah pendapat Anda berubah pada proposal Trey jika itu adalah bagian dari inti ReactDOM? Mungkin kita bisa menyempurnakan contoh lebih banyak jika itu akan membantu?

Perhatian utama saya dengan Opsi 5 adalah menciptakan banyak boilerplate untuk memungkinkan interoperabilitas, melanggar DX, akan memalukan bagi semua tim inti React dan kontributor untuk menghabiskan banyak waktu dalam perubahan yang tidak akan memiliki dampak yang diinginkan.

Saya sangat menyukai bagaimana tim React menangani perubahan terakhir dalam repo, seperti _PropTypes_, akan lebih baik untuk memikirkan rencana yang melibatkan lebih dari satu sakelar, untuk mendidik pengembang tentang kemungkinan perubahan yang harus dilakukan di masa depan untuk kustom dan bukan kustom elemen.

Saya pikir solusi yang akan memuaskan kita semua adalah menggabungkan beberapa opsi ini sebagai _steps_, penambahan API, peringatan dan penghentian atau perubahan perilaku.

Mungkin opsi 5, dengan peringatan, kemudian opsi 2 dengan penghentian pembungkus yang dibutuhkan.

Mungkin opsi 5, dengan peringatan, kemudian opsi 2 dengan penghentian pembungkus yang dibutuhkan.

Saya sebenarnya berpikir bahwa melakukan yang sebaliknya akan menjadi serangkaian langkah yang lebih baik. Opsi 1 atau 2 karena perubahannya tidak terlalu dramatis. Dan mengukur bagaimana kelanjutannya dan seperti apa kisah SSR mulai terlihat untuk komponen web. Kemudian menindaklanjuti dengan opsi 5 karena menambahkan API baru dan gagasan tentang komponen proxy/wrapper.

Masalah utama dengan opsi 1 adalah bahwa ini adalah jeda BC yang cukup besar. Masalah utama dengan opsi 2 adalah ia memiliki kondisi balapan tergantung kapan elemen tersebut selesai ditingkatkan. Saya tidak yakin bahwa salah satu dari itu benar-benar dapat diterima untuk proyek yang banyak digunakan seperti React.

Mengingat ketersediaan opsi 5, saya ingin tahu apakah kami dapat membuat peningkatan yang jauh lebih aman, tetapi tetap bermanfaat, untuk penggunaan non-opsi-5. Misalnya, bagaimana dengan kebalikan dari opsi 4: cukup perkenalkan domProperties dan eventListeners props, sehingga Anda dapat melakukan hal-hal seperti:

<x-foo 
  my-attr1={...} 
  domProperties={{myRichDataProperty: ...}} 
  eventListeners={{'a-custom-element-event':  e => console.log('yo')}} 
/>

Ini sepenuhnya kompatibel, karena berdasarkan huruf besar mereka, domProperties dan eventListeners bukan nama atribut yang valid . Kecuali untuk itu React 16 saat ini memanggil setAttribute() bahkan untuk nama prop dengan alfa atas, mengandalkan browser untuk huruf kecil nama secara internal; namun, dapatkah rilis minor React 16 di masa mendatang mengeluarkan peringatan saat menemukan properti elemen kustom yang bukan nama atribut yang valid, sehingga orang dapat memperbaiki kesalahan casing mereka sebelum meningkatkan ke React 17?

Selain melestarikan BC, pendekatan ini mudah dipahami: ini adalah atribut-sentris (artinya props React diperlakukan sebagai atribut elemen), yang cocok mengingat nama elemen itu sendiri semuanya huruf kecil dan memiliki tanda hubung dan karena itu HTML-sentris. Namun, domProperties disediakan untuk kasus yang relatif jarang terjadi di mana Anda harus meneruskan properti, seperti meneruskan data yang kaya.

Bagi orang yang ingin mengubah model mental mereka menjadi properti-sentris (ala Opsi 1), di situlah opsi 5 gaya API bisa masuk:

const XFoo = ReactDOM.customElement('x-foo');
<XFoo prop1={} prop2={} data-foo={} aria-label={} />

Dengan sintaks ini, setiap prop diperlakukan sebagai properti (opsi 1). Yang cocok, karena elemen "nama" (XFoo) juga mengikuti konvensi JS-sentris. Saya pikir kami masih ingin setidaknya mendukung data-* dan aria-* props diperlakukan sebagai atribut, yang dapat kami batasi hanya untuk itu, atau menggeneralisasi untuk memperlakukan prop apa pun dengan tanda hubung sebagai atribut.

Sedangkan untuk mendukung konfigurasi SSR opsi 5, kita bisa menambahkan config API ke ReactDOM.customElement , seperti:

const XFoo = ReactDOM.customElement('x-foo', ssrConfiguration);

Mungkin ssrConfiguration bisa menjadi fungsi panggilan balik yang mirip dengan ReactDOM.setAttribute ada di komentar @treshugart ?

Bagaimana menurutmu?

@effulgentsia Saya suka kemana pikiran Anda pergi. Bikeshed sedikit nama: domProps / domEvents . Ini sangat dekat dengan opsi 4.

WRT SSR, saya pikir SSR dapat ditangani oleh elemen kustom itu sendiri selama React dapat menghormati atribut yang dimutasi komponen ke dirinya sendiri jika tidak melacaknya. Saya memposting Intisari sebelumnya, tetapi ini dia lagi, untuk kenyamanan: https://Gist.github.com/treshugart/6eff0da3c0bea886bb56589f743b78a6. Pada dasarnya komponen menerapkan atribut setelah rendering di server dan merehidrasinya di klien. SSR untuk komponen web dimungkinkan, tetapi solusi masih didiskusikan di tingkat standar, jadi mungkin lebih baik menunggu bagian proposal ini.

@effulgentsia Saya juga suka tujuan Anda. @sophiebits , @gaearon do
Anda memiliki pemikiran tentang arah ini?

Pada Selasa, 31 Oktober 2017, 19:33 Trey Shugart [email protected] menulis:

@effulgentsia https://github.com/effulgentsia Saya suka di mana Anda
pikiran pergi. Bikeshedding nama sedikit, mungkin berguna untuk
menyelaraskan penamaan mereka: domProps / domEvents, atau sesuatu.

Opsi WRT 2, setidaknya kompatibel ke belakang dan menyelesaikan sebagian besar kasus penggunaan,
tapi aku datang sekitar untuk alternatif.

Saya pikir SSR dapat ditangani oleh elemen khusus itu sendiri selama
React dapat menghormati atribut yang dimutasi komponen ke dirinya sendiri jika itu
tidak melacak mereka. Saya memposting inti sebelumnya, tetapi ini dia lagi, untuk
kenyamanan:
https://Gist.github.com/treshugart/6eff0da3c0bea886bb56589f743b78a6.
Pada dasarnya komponen menerapkan atribut setelah rendering di server
dan rehidrasi mereka pada klien. SSR untuk komponen web dimungkinkan, tetapi
solusi masih dibahas di tingkat standar, jadi mungkin
terbaik untuk menunggu bagian dari proposal di sini.


Anda menerima ini karena Anda disebutkan.
Balas email ini secara langsung, lihat di GitHub
https://github.com/facebook/react/issues/11347#issuecomment-340960798 ,
atau matikan utasnya
https://github.com/notifications/unsubscribe-auth/ABBFDeiQhBWNGXNplbVV1zluYxT-ntFvks5sx9hngaJpZM4QD3Zn
.

Bikeshedding nama sedikit: domProps / domEvents.

Saya suka itu. Saya juga sedang melakukan brainstorming jika ada cara untuk membuat mereka lebih idiomatis untuk Bereaksi dengan mengganti konsep "dom" dengan konsep "ref". Jadi dengan kata lain: refProps / refEvents , karena ini tentang melampirkan alat peraga dan pendengar acara ke "ref".

Dan kemudian saya berpikir, bagaimana jika alih-alih memperkenalkan nama khusus baru di dalam this.props , kita hanya membebani atribut JSX ref . Saat ini, "ref" adalah fungsi yang dipanggil ketika komponen React dipasang dan dilepas. Bagaimana jika kita mengizinkannya juga menjadi objek seperti ini:

<x-foo my-attr-1={}
  ref={{
    props: ...
    events: ...
    mounted: ...
    unmounted: ...
  }}
/>

Hanya sebuah ide.

Saya sangat suka pendekatan ini :)

Ping ramah ini. @gaearon @sophiebits apakah kalian punya pendapat tentang proposal terbaru

Kami baru saja membuka proses RFC. Bisakah kami meminta salah satu dari Anda untuk mengirimkannya sebagai RFC?
https://github.com/reactjs/rfcs

Saya lebih suka tidak menambahkan domProperties dan eventListeners "props" (atau yang setara dalam objek ref={{}}) karena itu membuat penggunaan elemen khusus menjadi sangat tidak wajar dan tidak seperti semua komponen React lainnya. Jika pengguna komponen harus benar-benar mengetahui perbedaan antara properti dan atribut, dll, maka saya lebih suka melakukannya sebagai solusi gaya ReactDOM.createCustomElementType. Kemudian jika Anda menggunakan komponen tepat sekali itu adalah jumlah pekerjaan yang sebanding (menentukan konfigurasi dan kemudian menggunakannya sekali), tetapi jika Anda menggunakan komponen berkali-kali maka Anda tidak perlu memikirkan objek konfigurasi setiap saat. Mengharuskan konfigurasi ditentukan setiap kali tampaknya mengalahkan tujuan memiliki integrasi elemen kustom yang bersih kecuali saya melewatkan sesuatu.

@sophiebits OK, saya bisa mencoba menulis RFC untuk sesuatu seperti itu. Apa pendapat Anda tentang gagasan yang Anda ajukan kembali pada 26 Oktober tentang properti pertama di sisi klien dan juga memungkinkan orang untuk menulis ReactDOM.createCustomElementType untuk SSR dan/atau jika mereka ingin kontrol berbutir sangat halus atas bagaimana klien memetakan attrs/properti ?

Setidaknya dengan gaya createCustomElementType , perpustakaan dapat dengan mudah memetakan API mereka ke dalamnya. Yaitu, skatejs/renderer-react kita dapat dengan mudah mengambil props dan mengonfigurasi elemen kustom untuk React. Jenis ini membuat orang-orang vanilla tinggi dan kering tanpa abstraksi atau melakukan sedikit pekerjaan. Saya suka saran Rob tentang default yang aman, sambil memungkinkan kontrol yang halus. Apakah itu sesuatu yang akan berhasil?

@robdodson saya pikir saya

Opsi 3 adalah opsi terbaik sejauh ini, dan dapat bekerja dengan SSR, saya akan menjelaskan bagaimana caranya.

Sejauh ini semua opsi sendiri, kecuali 3,

  • baik membuat beban pemeliharaan tinggi untuk semua orang di luar sumber Bereaksi
  • atau mereka memaksa semua pembuat elemen kustom di seluruh alam semesta untuk mematuhi aturan khusus React.

Inilah aturan universal yang kita semua setujui:

  • menyetel atribut dengan setAttribute adalah cara paling standar di alam semesta untuk meneruskan data ke elemen dengan cara yang cocok 1-ke-1 dengan atribut HTML Deklaratif. Ini harus bekerja 100% sepanjang waktu sebagai hukum alam semesta, oleh karena itu ini adalah satu-satunya cara yang dijamin 100% untuk meneruskan data ke elemen.
  • beberapa orang tidak senang bahwa itu dirancang hanya untuk string.
  • Beberapa elemen (saya ulangi, _only some elements_ ), menerima nilai melalui properti objek yang memetakan ke atribut tertentu. Ini adalah _bukan_ sesuatu yang dapat diandalkan 100% setiap saat.
  • beberapa orang menyukai properti objek karena mereka dapat menerima non-string

Jadi, minimal, jika React ingin bekerja 100% dengan _setiap elemen kustom di alam semesta dan tidak menjadi beban bagi orang_ , maka:

  • Bereaksi perlu menyadari itu bukan Tuhan, ada banyak perpustakaan lain yang digunakan orang selain reaksi,
  • oleh karena itu Bereaksi harus _secara default_ hanya meneruskan data melalui setAttribute karena itu adalah standar 100%.
  • Bereaksi harus menerima kenyataan bahwa penulis Elemen Kustom dapat memperluas/mengganti metode setAttribute dalam definisi kelas mereka, membuat setAttribute menerima hal-hal selain string. Contoh utama adalah perpustakaan seperti A-frame.
  • React harus menerima bahwa jika pembuat elemen kustom menginginkan elemen kustom untuk bekerja dengan setiap perpustakaan yang memungkinkan, _tidak hanya dengan React_ maka penulis itu akan bergantung pada setAttribute untuk membuat elemennya secara default kompatibel dengan semuanya, dan jika secara default semua perpustakaan bergantung pada atribut, maka seluruh alam semesta akan bekerja satu sama lain. _Tidak ada jika, dan, atau tetapi tentang ini!_ (kecuali w3c/whatwg membuat beberapa perubahan besar)

Soooooooo , begitulah, setidaknya kita harus

Kemudian, kita dapat memikirkan implikasi elemen yang terkadang memiliki API objek-properti:

  • pengembang memiliki pilihan untuk menggunakan setAttribute karena mengetahui itu akan berfungsi sepanjang waktu.
  • pengembang terkadang dapat memanfaatkan properti objek.
  • pengembang selalu harus menyadari apakah antarmuka objek-properti ada untuk elemen tertentu (kustom atau tidak).
  • antarmuka objek-properti adalah antarmuka alternatif yang tidak harus memetakan 1-ke-1 dengan atribut.

Jadi, dengan pengetahuan tentang atribut vs properti ini, solusi dalam React yang _ingin meningkatkan standar 100% dan menghormati hukum alam semesta_ harus:

  1. memungkinkan atribut untuk bekerja 100% dari waktu secara default. Ini berarti bahwa <x-foo blah="blah" /> harus _secara default_ dipetakan ke setAttribute dan meneruskan nilainya bersama _unchanged_ . Ini adalah perubahan yang tidak melanggar. Faktanya, ini adalah perubahan perbaikan yang jika tidak akan menghasilkan string "[object Object]" tidak berarti yang diteruskan.
  2. Munculkan cara alternatif untuk membiarkan pengguna Bereaksi _opsional_ menggunakan alat peraga jika pengguna sadar tentang antarmuka objek-properti mana yang ada dan ingin secara eksplisit menggunakan antarmuka tersebut.

Sepertinya Opsi 3, menggunakan sigil (yang sintaks tambahannya sejujurnya tidak sulit dipelajari), adalah solusi yang paling mendekati ideal. Berdasarkan pertanyaan SO ini , maka satu-satunya simbol yang tersedia adalah = , meskipun menetapkan sesuatu seperti & (dengan bentuk yang dapat dihindari, mungkin seperti \& ) lebih mudah dibaca. Misalnya, jika saya menginginkan prop secara khusus:

<x-foo &blah="blah" />

Sebagian besar karakter lain yang dicakup oleh spesifikasi sintaks HTML WHATWG seharusnya berfungsi, dan saya harap mereka melakukannya, tetapi itu topik lain.

Opsi 3 adalah opsi terbaik sejauh ini.

Jika hidrasi tidak digunakan pada klien dan karena itu alat peraga tidak masuk akal di SSR, maka, oh well. Itu tidak pernah berhasil sebelumnya, dan tidak perlu bekerja sekarang. PHP-style atau Java-style SSR mengirimkan HTML statis tanpa hidrasi dan mereka bergantung 100% pada atribut. Dikatakan, jika kita menggunakan React SSR, kita mungkin akan menggunakan hidrasi sisi klien, dan jika kita tidak menginginkan hidrasi, maka kita harus menyadari fakta bahwa kita tidak boleh menggunakan alat peraga dalam kasus ini. _Ini sederhana. Semua reaksi yang harus dilakukan adalah membuat peringatan ini jelas dalam dokumentasi._

Tetapi!!! Itu tidak semua! Kami masih dapat menyertakan fitur Opsi 5 untuk memberi orang lebih banyak kontrol. Dengan API seperti Opsi 5,

  • Beberapa orang dapat mengonfigurasi bagaimana beberapa atribut dapat dipetakan ke props
  • DAN bagaimana beberapa alat peraga dapat memetakan ke atribut. Ini dapat membantu orang membuat SSR bekerja bahkan untuk jenis SSR yang tidak menghidrasi!
  • kita dapat membiarkan orang mendefinisikan "jika atribut ini ditulis, benar-benar meneruskannya ke prop ini, tetapi jika SSR, jangan berikan ke prop", atau "teruskan prop ini ke atribut ini hanya selama SSR, jika tidak lakukan apa Saya tentukan menggunakan sigil", dll

Pada akhirnya, berikut ini sepertinya solusi yang akan berhasil:

  • Opsi 3 dengan setAttribute digunakan secara default di belakang layar,
  • dengan perbaikan untuk #10070 sehingga React tidak menghalangi orang,
  • dan API seperti di Opsi 5 untuk penyetelan lebih lanjut bagi mereka yang benar-benar membutuhkannya, termasuk cara menyetel SSR, klien, atau keduanya.

Selamat Tahun Baru!

Saya ingin menanggapi beberapa poin di atas, tetapi takut bahwa utas ini sudah _luar biasa_ panjang. Jadi maaf kalau kepanjangan :P

Inilah aturan universal yang kita semua setujui:

menyetel atribut dengan setAttribute adalah cara paling standar di alam semesta untuk meneruskan data ke elemen dengan cara yang cocok 1-ke-1 dengan atribut HTML Deklaratif. Ini harus bekerja 100% sepanjang waktu sebagai hukum alam semesta, oleh karena itu ini adalah satu-satunya cara yang dijamin 100% untuk meneruskan data ke elemen.

Ini tidak sepenuhnya benar. Tidak ada dalam platform untuk menegakkan bahwa elemen kustom mengekspos antarmuka atribut. Anda dapat dengan mudah membuat yang hanya menerima properti JS. Jadi ini bukan "cara yang dijamin untuk melewatkan data". Kurangnya mekanisme penegakan berarti Anda tidak dapat mengandalkan salah satu gaya (atribut HTML atau properti JS) dengan kepastian 100%.

beberapa orang tidak senang bahwa itu dirancang hanya untuk string.
Beberapa elemen (saya ulangi, hanya beberapa elemen), menerima nilai melalui properti objek yang dipetakan ke atribut tertentu. Ini bukan sesuatu yang dapat diandalkan 100% setiap saat.

Kami mendorong orang-orang untuk tidak repot-repot membuat atribut untuk properti yang menerima data kaya seperti objek/array. Ini karena beberapa data tidak dapat diserialisasi kembali ke string atribut. Misalnya, jika salah satu properti objek Anda adalah referensi ke Node DOM, itu sebenarnya tidak bisa dirangkai. Juga, ketika Anda merangkai dan menguraikan kembali suatu objek, ia kehilangan identitasnya. Artinya, jika memiliki referensi ke POJO lain, Anda tidak dapat benar-benar menggunakan referensi itu karena Anda telah membuat objek yang sama sekali baru.

beberapa orang menyukai properti objek karena mereka dapat menerima non-string

oleh karena itu Bereaksi harus secara default hanya meneruskan data melalui setAttribute karena itu adalah standar 100%.

Properti JavaScript sama-sama standar. Sebagian besar elemen HTML mengekspos atribut dan antarmuka properti yang sesuai. Misalnya, <img src=""> atau HTMLImageElement.src .

Bereaksi harus menerima kenyataan bahwa penulis Elemen Kustom dapat memperluas/mengganti metode setAttribute dalam definisi kelas mereka, membuat setAttribute menerima hal-hal selain string.

Penulis bisa melakukan itu, tetapi itu sebenarnya tampak jauh lebih "non-standar" daripada hanya menggunakan properti JS. Ini juga dapat memaparkan Anda pada masalah aneh yang terkait dengan penguraian dan kloning elemen .

React harus menerima bahwa jika penulis elemen kustom menginginkan elemen kustom untuk bekerja dengan setiap perpustakaan yang memungkinkan, tidak hanya dengan React maka penulis tersebut akan bergantung pada setAttribute untuk membuat elemennya secara default kompatibel dengan semuanya, dan jika secara default semua perpustakaan bergantung pada atribut , maka seluruh alam semesta akan saling bekerja sama. Tidak ada jika, dan, atau tetapi tentang ini! (kecuali w3c/whatwg membuat beberapa perubahan besar)

Saya tidak yakin bagaimana Anda sampai pada kesimpulan ini karena ada perpustakaan lain yang lebih suka mengatur properti JS pada elemen khusus (Angular, misalnya). Untuk kompatibilitas maksimum, penulis harus mendukung atribut mereka dengan properti JS. Itu akan mencakup area permukaan terbesar dari kemungkinan penggunaan. Semua elemen yang dibuat dengan Polymer melakukan ini secara default.

memungkinkan atribut untuk bekerja 100% dari waktu secara default. Ini berarti bahwa harus secara default memetakan ke setAttribute dan meneruskan nilainya tidak berubah. Ini adalah perubahan yang tidak melanggar. Faktanya, ini adalah perubahan perbaikan yang sebaliknya akan menghasilkan string "[objek objek]" yang tidak berarti yang diteruskan.

Saya pikir React sebenarnya _is_ memberikan nilai yang tidak berubah. Memanggil setAttribute('foo', {some: object}) menghasilkan [object Object] . Kecuali Anda mengusulkan agar mereka memanggil JSON.stringify() pada objek? Tapi kemudian objek itu tidak "tidak berubah." Saya pikir mungkin Anda mengandalkan penulis untuk mengganti setAttribute() ? Mungkin lebih masuk akal untuk mendorong mereka membuat properti JS yang sesuai daripada menambal DOM dengan monyet.

Saya pikir React sebenarnya _is_ memberikan nilai yang tidak berubah. Memanggil setAttribute('foo', {some: object}) menghasilkan [object Object]

Bereaksi memaksa nilai ke string sebelum meneruskan ke setAttribute :

https://github.com/facebook/react/blob/4d6540893809cbecb5d7490a77ec7ad32e2aeeb3/packages/react-dom/src/client/DOMPropertyOperations.js#L136

dan

https://github.com/facebook/react/blob/4d6540893809cbecb5d7490a77ec7ad32e2aeeb3/packages/react-dom/src/client/DOMPropertyOperations.js#L166

Saya pada dasarnya setuju dengan semua yang Anda katakan.

Kami setuju bahwa orang melakukan sesuatu dengan dua cara, dan tidak ada standar yang memaksa setiap orang untuk melakukannya hanya dengan satu atau lain cara, jadi saya masih berpikir

  • Opsi 3 dengan setAttribute digunakan secara default dan sigil untuk menentukan penggunaan properti instans,
  • dengan perbaikan untuk #10070 sehingga React tidak memaksa argumen ke string,
  • dan Opsi 5, API untuk fine tuning

Jika Opsi 5 dilakukan dengan baik, maka hidrasi untuk solusi SSR dapat memetakan data ke atribut atau props seperti yang dapat ditentukan dengan menggunakan API Opsi 5.

React memaksa nilai ke string sebelum diteruskan ke setAttribute

Jadi begitu. Karena kebanyakan orang tidak mendefinisikan toString() kustom, defaultnya adalah [object Object] .

Karena kebanyakan orang tidak mendefinisikan toString() kustom, defaultnya adalah [object Object] .

Sama seperti jika saya melakukannya

const div = document.createElement('div')
div.setAttribute('foo', {a:1, b:2, c:3})

hasilnya adalah

<div foo="[object Object]"></div>

Jelas sebagai pengembang web kita harus menyadari apa yang terjadi ketika kita memasukkan non-string ke atribut elemen. Misalnya saya sadar bahwa saya dapat meneruskan non-string ke elemen A-Frame, dan saya harus bebas melakukannya tanpa perpustakaan menghalangi.

React perlu menyadari bahwa itu bukan Tuhan, ada banyak perpustakaan lain yang digunakan orang selain react

Ini tidak perlu snarky. Anda akan mencatat di utas ini bahwa kami peduli dengan hal ini tetapi ada banyak opsi dan visi berbeda untuk mengambil desain elemen kustom. Jelas tidak jelas apa yang harus dilakukan.

@sebmarkbage Maaf tentang itu, saya tidak bermaksud sombong sama sekali, dan saya pikir React adalah lib yang bagus. Seharusnya saya memikirkan kata-kata saya lebih hati-hati di sana (terutama karena tidak semua orang memiliki agama yang sama).

Yang saya maksud adalah, React sangat populer, jadi React berpotensi mempengaruhi orang untuk melakukan hal-hal dengan cara tertentu yang mungkin tidak berfungsi di tempat lain (jika itu bisa memberi tahu orang untuk mengandalkan properti instan untuk semua Elemen Kustom yang akan' t bekerja dengan semua Elemen Kustom).

React saat ini mengonversi semua nilai yang diteruskan ke atribut elemen menjadi string. Seandainya React tidak melakukan ini, misalnya, tidak perlu ada aframe-react (yang mengatasi masalah string) bahkan ada.

Jika React membiarkan kita memiliki kemampuan untuk membuat pilihan tentang bagaimana kita meneruskan data ke elemen, seperti dalam JavaScript biasa, itu akan membuat saya menjadi pengguna yang paling puas. 😊

Sekali lagi, maaf tentang pilihan kata-kata saya di sana. Saya akan berpikir dua kali lain kali.

Saya telah menambahkan komentar ke RFC PR untuk ini. Saya pikir ini layak untuk didiskusikan karena mencakup apa yang diusulkan serta model yang lebih sederhana untuk secara andal menyimpulkan elemen khusus dan propertinya. Ini mengubahnya kembali menjadi pendekatan hybrid, tetapi menawarkan cara integrasi tanpa konfigurasi untuk sebagian besar kasus penggunaan.

Saya ingin melihat fitur ini diimplementasikan di React. Terima kasih banyak atas upaya Anda membuat React hebat.

Adakah pembaruan pada RFC ini?

Pustaka Elemen Kustom menjadi sangat bagus dan saya ingin menggunakannya di aplikasi Bereaksi saya. Ada berita tentang ini belum? Membungkus elemen khusus dan merangkai kontennya untuk kemudian menguraikannya lagi adalah solusi yang cukup tidak bisa diterapkan mengingat Vue dan Angular menangani komponen secara asli dengan mudah

Setiap pembaruan tentang masalah ini?

Saya juga, ingin menggunakan pustaka elemen khusus tanpa menggunakan peretasan. Saya ingin masalah ini diselesaikan.

@mgolub2 Tim React tidak peduli dengan apa yang diinginkan komunitas web. Komponen Web sekarang menjadi standar yang didukung secara luas, dan tidak ada sinyal apa pun dari tim untuk mendukung standar ini, setelah 2 tahun.

Hai semuanya, saya memulai permintaan tarik untuk memperbaiki masalah ini dengan mengubah dua baris: https://github.com/facebook/react/pull/16899

Ini memungkinkan pembuat elemen khusus untuk melakukan sesuatu seperti berikut:

class MyElement extends HTMLElement {
  setAttribute(name, value) {
    // default to existing behavior with strings
    if (typeof value === 'string')
      return super.setAttribute(name, value)

    // but now a custom element author can decide what to do with non-string values.
    if (value instanceof SomeCoolObject) { /*...*/ }
  }
}

Ada banyak variasi tentang seperti apa tampilan metode setAttribute diperluas, itu hanya satu contoh kecil.

Tim React, Anda mungkin berpendapat bahwa pembuat elemen kustom tidak boleh melakukan itu, karena mereka mengabaikan penanganan atribut asli DOM dalam beberapa kasus (fe ketika nilai bukan string). Jika Anda memiliki pendapat itu, itu tetap tidak berarti Anda harus menghalangi apa yang dapat dilakukan oleh pembuat elemen kustom dengan elemen __ kustom __ mereka.

React tidak boleh membuat opini tentang bagaimana DOM API yang ada digunakan. React adalah alat untuk memanipulasi DOM, dan tidak boleh beropini tentang apa yang dapat kita lakukan terhadap DOM, hanya dengan cara apa data mengalir ke DOM. Maksud saya "cara data mengalir ke DOM" yang saya maksud adalah rute yang diambil data untuk sampai ke sana, tanpa mutasi ke data (mengubah objek penulis menjadi string berarti mengubah data penulis).

Mengapa Anda ingin mengubah data penulis? Mengapa Anda tidak bisa berasumsi bahwa orang yang ingin memanipulasi DOM tahu data apa yang harus diteruskan ke DOM?

@trusktr Saya pikir ini telah dibahas di https://github.com/facebook/react/issues/10070

Saya benar-benar akan memperingatkan orang-orang agar tidak memberi tahu penulis elemen khusus untuk mengganti metode bawaan seperti setAttribute . Saya tidak berpikir itu dimaksudkan bagi kita untuk menambal monyet itu. cc @gaearon

Tidak berbahaya untuk mengganti setAttribute di subclass seperti itu (itu bukan patching monyet). Tapi seperti yang saya sebutkan, mengapa React harus mendikte itu, jika itu belum tentu tugas lib React. Kami ingin menggunakan React untuk memanipulasi DOM (tanpa halangan).

Jika saya harus menggunakan el.setAttribute() secara manual untuk meningkatkan kinerja, itu juga hanya memperburuk pengalaman pengembang.

Saya tidak berpikir tim React menyelamatkan banyak orang dari bahaya besar dengan mengubah apa pun yang diteruskan ke setAttribute menjadi string.

Saya setuju solusi lain mungkin lebih baik. Misalnya, memperbarui spesifikasi JSX agar memiliki beberapa sintaks baru, tetapi tampaknya memakan waktu lama.

Apa kerugian komunitas jika kita menghapus konversi string otomatis? Apa yang hilang dari tim React?

Tim React bisa memperbaiki situasi nanti, dengan solusi yang lebih baik...

Mengapa tidak setidaknya memberi kami opsi untuk melewati stringifikasi? Apakah itu sesuatu yang mungkin ingin Anda pertimbangkan?

Saya benar-benar akan memperingatkan orang-orang agar tidak memberi tahu penulis elemen khusus untuk mengganti metode bawaan seperti setAttribute .

Bisakah Anda memberikan alasan yang bagus mengapa?

Ini tampak seperti ikan haring merah. "Meyakinkan semua orang yang menulis elemen khusus untuk melampirkan metode dengan perilaku tertentu ke elemen mereka" bukanlah solusi untuk masalah ini, yaitu tentang cara menyetel properti pada elemen DOM.

@trusktr

Bisakah Anda memberikan alasan yang bagus mengapa?

Komponen web adalah standar. Jadi, turunan dari standar harus sesuai standar juga.

Namun, mengganti setAttribute tidak sesuai dengan kondisi ini: ini hanya membuat peretasan untuk React sementara ada banyak kerangka kerja lain yang bekerja dengan komponen web di luar kotak. Jadi, mereka perlu menggunakan hack React bahkan ketika mereka tidak bekerja dengan React sama sekali. Saya tidak berpikir itu adalah solusi yang tepat.

Selanjutnya, diketahui bahwa menambal metode standar adalah pendekatan yang salah. Mengganti setAttribute mengubah perilaku asli yang dapat membuat pengguna akhir bingung ketika mereka mencoba menggunakannya. Semua orang mengharapkan standar berfungsi sebagai standar, dan elemen kustom tidak terkecuali karena mewarisi perilaku HTMLElement . Dan sementara itu mungkin bekerja dengan React, itu menciptakan jebakan untuk semua pengguna lain. Misalnya, ketika komponen web digunakan tanpa kerangka kerja, setAttribute mungkin disebut banyak. Saya ragu pengembang elemen khusus akan setuju untuk mengambil langkah dengan pendekatan ini.

Secara pribadi, saya pikir semacam pembungkus React terlihat jauh lebih menjanjikan.

Hai teman-teman, sementara kami menunggu, saya membuat shim untuk membungkus komponen web Anda di React https://www.npmjs.com/package/reactify-wc

import React from "react";
import reactifyWc from "reactify-wc";

// Import your web component. This one defines a tag called 'vaadin-button'
import "@vaadin/vaadin-button";

const onClick = () => console.log('hello world');

const VaadinButton = reactifyWc("vaadin-button");

export const MyReactComponent = () => (
  <>
    <h1>Hello world</h1>
    <VaadinButton onClick={onClick}>
      Click me!
    </VaadinButton>
  </>
)

Saya harap ini terbukti bermanfaat

(Ini adalah perampokan pertama saya ke OSS, dan salah satu open-source pertama dari sesuatu di luar kantor saya. Kritik membangun lebih dari diterima )

Hai teman-teman, sementara kami menunggu, saya membuat shim untuk membungkus komponen web Anda di React https://www.npmjs.com/package/reactify-wc

import React from "react";
import reactifyWc from "reactify-wc";

// Import your web component. This one defines a tag called 'vaadin-button'
import "@vaadin/vaadin-button";

const onClick = () => console.log('hello world');

const VaadinButton = reactifyWc("vaadin-button");

export const MyReactComponent = () => (
  <>
    <h1>Hello world</h1>
    <VaadinButton onClick={onClick}>
      Click me!
    </VaadinButton>
  </>
)

Saya harap ini terbukti bermanfaat

(Ini adalah perampokan pertama saya ke OSS, dan salah satu open-source pertama dari sesuatu di luar kantor saya. Kritik membangun lebih dari diterima )

Pembungkus yang bagus :)

Perlu juga disebutkan bahwa membangun komponen web dengan Stencil memperbaiki masalah ini dengan React: https://stenciljs.com/docs/faq#can -data-be-passed-to-web-components-

@matsgm Saya senang membangun dengan Stensil telah berhasil untuk Anda. Namun, sebagai peringatan, dalam pengalaman kami Stencil telah terbukti tidak cocok dengan kerangka kerja komponen web lainnya, khususnya Polymer, dan kami telah terganggu dengan setengah lusin masalah lain antara alat pembuatan, dukungan, dan fungsionalitas umum mereka. Mileage Anda Bisa Bervariasi :)

Hanya mencoba untuk mendapatkan up-to-date dengan thread ini. Apa solusi akhirnya?

Di satu sisi saya adalah penggemar berat mendefinisikan attr, prop, acara daripada heuristik ajaib yang bisa sangat membingungkan.

Misalnya snabbdom menggunakan onClick => click masih merupakan hit perf.

<input attrs={{placeholder: `heyo`}} style={{color: `inherit`}} class={{hello: true, world: false}} on={{click: this.handleClick}} props={{value: `blah`}} />
attr = (attr, val) => elem.setAttribute(attr, val);
prop = (prop, val) => elem[prop] = val;
on  = (event, handler) => elem.addEventListener(event, handler)
style = (prop, val) => elem.style[prop] = val;
class = (name, isSet) => isSet ? elem.classList.add(name) : elem.classList.remove(val)
dataset = (key, val) => elem.dataset[key] = val;

Saya berharap JSX mendukung namespace dengan sintaks titik. Ini berarti props akan menjadi namespace default dan kita cukup menulis

<div tabIndex={-1} attr.title={"abcd"} on.click={handler} style.opacity={1} class.world={true} />`

fyi @sebmarkbage ^

const whatever = 'Whatever';
const obj = { a: 1, b: 2 };
const reactComponent = (props) => (
<div>
  ...
  <custom-element attr="{whatever}" someProp={obj} />
  { /* double quotes for attributes */ }
  { /* no quotes for properties */ }
</div>
);

Ini dapat dicapai dengan memodifikasi parser React JSX Pragma.

Opsi tambahan adalah untuk menjaga propeties (atau props untuk reaksi penggemar) sebagai kata yang ditunjuk untuk melewati properti

Sejak 17.0 dirilis hari ini, dapatkah kami memperbarui masalah ini untuk mencerminkan status kapan masalah ini akan ditangani?

Ya. Kami awalnya merencanakan React 17 menjadi rilis dengan lebih banyak penghentian yang dihapus (dan dengan fitur baru). Namun, tidak terlalu realistis bagi basis kode lama untuk memperbarui semua kode mereka, dan inilah mengapa kami memutuskan untuk mengeluarkan React 17 yang hanya berfokus pada satu perubahan pemutusan yang signifikan (event dilampirkan ke elemen root daripada dokumen ). Ini agar aplikasi lama dapat tetap berada di React 17 selamanya dan hanya memperbarui sebagian ke 18+.

Saya tahu ini membuat frustrasi karena kami telah mengatakan bahwa fitur khusus ini akan masuk ke 17, tetapi Anda akan melihat hampir semua hal yang awalnya kami rencanakan untuk 17 dipindahkan ke 18 juga. 17 adalah rilis batu loncatan khusus. Yang memungkinkan kami membuat perubahan terobosan yang lebih agresif di 18. Berpotensi termasuk yang ini jika ada jalur yang jelas ke depan.

Saya tidak yakin apa konsensus terbaru dari komunitas WC tentang opsi mana yang lebih disukai. Akan sangat membantu jika semuanya ditulis (alat bantu besar untuk @robdodson untuk melakukan pekerjaan itu). Saya ingin tahu apakah pendapat orang tentang opsi ini telah berkembang sejak utas ini ditulis, dan jika ada informasi baru yang dapat membantu kami memilih arah.

Saya tidak berpikir komunitas WC telah mengubah opsi pilihan mereka, yang masih merupakan opsi 3. @developit dapat berbicara lebih banyak tentang bagaimana Preact kompatibel dengan elemen kustom, yang mungkin juga menarik untuk React. Untuk gambaran umum tentang bagaimana kerangka kerja kompatibel dengan meneruskan data (kompleks) ke dalam elemen khusus, https://custom-elements-everywhere.com/ memiliki semua detailnya.

Perhatikan bahwa di https://github.com/vuejs/vue/issues/7582 , Vue memilih untuk menggunakan sigil, dan mereka memilih "." sebagai awalan (bukan "@") Glimmer.

Di https://github.com/vuejs/vue/issues/7582#issuecomment -362943450 , @trusktr menyarankan bahwa implementasi SSR yang paling benar adalah tidak merender properti sigil sebagai atribut dalam HTML SSR, dan untuk alih-alih atur sebagai properti melalui JS selama hidrasi.

Saya pikir sangat tidak mungkin bahwa kami akan memperkenalkan sintaks JSX baru demi fitur khusus ini saja.

Ada juga pertanyaan apakah layak untuk melakukan opsi (3) jika versi yang lebih umum dari opsi (5) mungkin ada di atas meja. Yaitu opsi (5) bisa menjadi mekanisme level rendah untuk mendeklarasikan node React level rendah kustom dengan perilaku mount/update/unmount/hydration kustom. Bahkan tidak spesifik untuk Elemen Kustom per se (walaupun mereka akan menjadi salah satu kasus penggunaan).

Daripada memperkenalkan sintaks JSX yang sepenuhnya baru untuk fitur khusus ini, bagaimana dengan memperkenalkan JSX yang lebih umum dan menggunakannya untuk mendefinisikan properti kustom?

Saya mengusulkan untuk menambahkan sintaks properti terkomputasi ECMAScript ke JSX sejak lama (facebook/jsx#108) dan berpikir itu akan menjadi tambahan yang berguna untuk sintaks secara umum.

Jika sintaks properti yang dihitung tersedia yang akan membuka kemungkinan untuk mendefinisikan properti menggunakan sintaks properti yang dihitung dan Simbol atau string awalan.

Contohnya:

import {property} from 'react';
// ...
<custom-img [property('src')]="corgi.jpg" [property('hiResSrc')]="[email protected]" width="100%">

@dantman Bagaimana proposal ini menangani rendering dan hidrasi server?

Saya tidak berpikir siapa pun di komunitas WC menginginkan opsi 5.

Ini benar-benar tidak berbeda dengan praktik menambal menulis pembungkus React kustom untuk elemen kustom saat ini. Kelemahan besar dari pendekatan itu adalah membebani pembuat komponen ke React kasus khusus atau konsumen komponen ke elemen kustom kasus khusus, yang keduanya tidak diperlukan.

Apa pendapat Anda tentang rendering dan hidrasi server? Jika tidak ada konfigurasi eksplisit, heuristik mana yang diinginkan? Apakah sudah ada konsolidasi tentang bagaimana hal ini biasanya dilakukan di komunitas WC? Saya membaca ulang RFC ini dan sepertinya tidak membahas detail tentang topik ini. Tapi itu cukup penting, terutama karena React bergerak ke arah yang lebih menekankan pada rendering server (seperti yang sering dikritik karena default yang terlalu berpusat pada klien).

@gaearon Saya tidak tahu cukup hidrasi dan properti khusus untuk mengetahui apa yang diperlukan, ini terutama proposal sintaksis.

Ide umumnya adalah bahwa property(propertyName) dapat, tergantung pada bagaimana Anda ingin mengimplementasikannya, menghasilkan string awalan (misalnya '__REACT_INTERNAL_PROP__$' + propertyName ) atau membuat Simbol dan menyimpan asosiasi "symbol => propertyName" di sebuah peta.

Nanti bisa bermasalah jika Anda perlu mengomunikasikan peta itu ke klien.

Namun untuk pemahaman kasar saya, properti bukanlah sesuatu yang dapat Anda tangani di server dan hidrasi melibatkan kode klien, jadi saya tidak yakin apa rencananya. Adapun proposal saya, itu mungkin dapat disesuaikan dengan rencana apa pun yang Anda miliki untuk menyelesaikan masalah itu. Jika ada sesuatu yang Anda rencanakan untuk bereaksi dengan properti di server maka itu bisa dilakukan ketika melihat salah satu properti yang dibuat oleh property .

Sebagai penulis pustaka komponen web, opsi 5 bukanlah pilihan yang nyaman. Saya ingin membuat elemen khusus tanpa harus secara eksplisit mendefinisikan skema untuk setiap kerangka kerja dan komponen. Dan banyak pembuat elemen kustom tidak akan melakukan ini, membebani pengembang Bereaksi.

Tidak ada yang menang dengan opsi 5.

@claviska Apakah Anda memiliki pendapat tentang bagaimana rendering dan hidrasi server harus bekerja dengan pendekatan yang lebih implisit?

@gaearon SSR akan dibagi menjadi dua situasi: situasi di mana elemen kustom mendukung SSR dan situasi di mana tidak.

Untuk elemen yang tidak mendukung SSR, pengaturan properti di server tidak masalah. Kecuali untuk properti refleksi bawaan seperti id dan className , mereka dapat dihapus dan hanya ditulis pada klien.

Untuk elemen yang mendukung properti SSR akan menjadi masalah, tetapi hanya agar elemen tersebut dapat memicu hasil apa pun yang ditimbulkannya di DOM. Ini memerlukan instance elemen atau semacam proxy/stand-in SSR, dan beberapa protokol untuk mengomunikasikan status DOM SSR. Belum ada antarmuka sisi server yang umum untuk proses ini, jadi sebenarnya tidak ada yang bisa dilakukan di sini untuk saat ini. Penulis komponen web dan pengelola perpustakaan perlu memikirkan beberapa hal sebelum React dapat membangun jembatan apa pun di sana.

Dalam pekerjaan tim saya di SSR, kami telah terintegrasi dengan React dengan menambal createElement dan menggunakan dangerouslySetInnerHTML . Saya pikir itulah tingkat integrasi/eksperimen yang akan kita capai sebentar. Pada titik tertentu, saya berharap kita dapat bertemu pada beberapa protokol pengguna-lahan untuk interop dalam sistem SSR. Sampai saat itu, sangat aman dan bijaksana untuk memiliki properti elemen khusus dan dukungan acara tanpa _deep_ SSR. Tag elemen akan tetap menjadi SSR sebagai anak dari komponen React seperti sekarang ini.

Kecuali untuk properti refleksi bawaan seperti id dan className, mereka dapat dihapus dan hanya ditulis pada klien.

Bisakah Anda membantu saya memahami cara kerjanya? Misalnya katakan ada <github-icon iconname="smiley" /> . Apakah maksud Anda SSR hanya memasukkan <github-icon /> dalam respons HTML, dan kemudian React akan menetapkan domNode.iconname = ... selama hidrasi? Dalam hal ini, saya tidak yakin saya mengerti apa yang terjadi jika implementasi elemen kustom dimuat sebelum hidrasi React terjadi. Bagaimana implementasi github-icon mengetahui ikon mana yang akan dirender jika iconname tidak ada dalam HTML?

Belum ada antarmuka sisi server yang umum untuk proses ini, jadi sebenarnya tidak ada yang bisa dilakukan di sini untuk saat ini. Penulis komponen web dan pengelola perpustakaan perlu memikirkan beberapa hal sebelum React dapat membangun jembatan apa pun di sana.

Saya ingin tahu apakah ada sesuatu yang khusus yang harus terjadi bagi komunitas untuk membentuk konsensus di sini. Apakah React yang menahannya? Saya sangat memahami rasa frustrasi yang terkait dengan masalah ini yang terbuka sejak 2017. Di sisi lain, sudah tiga tahun, dan saya pikir Anda mengatakan konsensus ini belum terbentuk. Apa prasyarat untuk itu terjadi? Apakah ini hanya masalah eksperimen lagi?

@gaearon jika implementasi elemen kustom dimuat sebelum hidrasi React terjadi, ia akan menetapkan nilai dafault apa pun dari atribut iconname . Apa yang anda maksud dengan if _iconname_ does not exist in the HTML ? Jika tipe HTMLElement tidak memiliki atribut yang ditentukan, itu akan mengabaikannya. setelah definisi elemen kustom dimuat, itu akan memperluas jenis HTMLElement dan mendefinisikan iconname dan dapat bereaksi terhadap nilai baru yang diteruskan.

Saya mencoba memahami ini dari sudut pandang pengguna. Kami sedang merender halaman di server. Ini memiliki ikon di tengah teks. Ikon itu diimplementasikan sebagai elemen khusus. Apa urutan hal-hal yang harus dialami pengguna akhir?

Pemahaman saya sejauh ini adalah:

  1. Mereka melihat hasil render awal. Ini akan mencakup semua markup normal, tetapi mereka tidak akan melihat elemen kustom <github-icon> sama sekali. Agaknya itu akan menjadi lubang, seperti div kosong. Tolong koreksi saya jika saya salah (?). Implementasinya belum dimuat.

  2. Implementasi elemen kustom <github-icon> dimuat dan didaftarkan. Jika saya mengerti dengan benar, ini adalah proses yang disebut "peningkatan". Namun, meskipun JS-nya sudah siap, tetap tidak dapat menampilkan apa pun karena kami belum menyertakan iconname dalam HTML. Jadi kami tidak memiliki informasi ikon mana yang akan dirender. Ini karena kami mengatakan sebelumnya bahwa "properti non-builtin dapat dijatuhkan dari HTML". Jadi pengguna masih melihat "lubang".

  3. Bereaksi dan kode aplikasi dimuat. Hidrasi terjadi. Selama hidrasi, React menetapkan properti .iconname = sesuai dengan heuristik. Pengguna dapat melihat ikon sekarang.

Apakah ini perincian yang benar untuk kasus di mana implementasi JS elemen kustom dimuat terlebih dahulu? Apakah ini perilaku yang diinginkan oleh komunitas WC?

@gaearon ya itulah yang saya harapkan terjadi dalam situasi ini.

Di sisi lain, sudah tiga tahun, dan saya pikir Anda mengatakan konsensus ini belum terbentuk

Saya tidak mengatakan konsensus belum terpenuhi. Saya katakan Anda tidak perlu khawatir tentang _deep_ SSR sekarang, dan jangan biarkan kekhawatiran yang cukup kabur tentang hal itu menghalangi interoperabilitas sisi klien paling dasar yang dapat dicapai dan sangat berguna saat ini.

Saya belum pernah melihat perbedaan ini sebelumnya (dalam vs dangkal) jadi izinkan saya mencoba menyatakan kembali untuk memeriksa apakah saya memahami Anda.

Dengan SSR "dalam", saya pikir maksud Anda SSR mirip dengan cara kerjanya di komponen Bereaksi. Artinya, merender CE akan menghasilkan output yang dapat ditampilkan sebelum logika CE dimuat. Ini adalah sesuatu yang Anda katakan, kami tidak perlu khawatir untuk mendukungnya sekarang. Itu masuk akal bagi saya.

Dengan SSR "tidak dalam", saya pikir Anda mengatakan bahwa kami hanya memasukkan tag CE itu sendiri ke dalam HTML. Tanpa mengkhawatirkan apa yang diputuskannya. Itu masuk akal bagi saya juga. Pertanyaan saya adalah tentang aliran _this_ — bukan tentang SSR "dalam".

Secara khusus, https://github.com/facebook/react/issues/11347#issuecomment -713230572 menjelaskan situasi di mana bahkan ketika kami _sudah memiliki_ logika CE diunduh, kami masih tidak dapat menunjukkan apa pun kepada pengguna hingga hidrasi. Menjadi propertinya tidak diketahui sampai kode klien JS seluruh aplikasi dimuat dan hidrasi terjadi. Saya bertanya apakah ini memang perilaku yang diinginkan.

Saya tidak berpikir itu kekhawatiran yang kabur dari sudut pandang saya. Saya tidak ingin salah memahami permintaan fitur. Jadi mendapatkan semantik yang tepat yang ditentukan akan membantu saya mengevaluasi proposal ini. Misalnya satu perhatian praktis adalah bahwa React sebenarnya tidak membedakan atribut/properti dalam produksi selama hidrasi hari ini karena tidak ada komponen bawaan yang membutuhkannya. Tapi itu sesuatu yang bisa kami tambahkan untuk kasus khusus ini jika benar-benar dibutuhkan.

@gaearon

Saya pikir https://github.com/facebook/react/issues/11347#issuecomment -713230572 mungkin bukan contoh kasus terbaik di mana fitur ini diperlukan.

Setidaknya dalam pengalaman saya, pengaturan properti daripada atribut tidak semua yang diperlukan untuk tipe yang lebih sederhana seperti string, angka, atau boolean.

Kasus yang Anda gambarkan dapat dengan mudah dicapai hanya dengan menggunakan iconname sebagai atribut secara langsung dan sebagian besar masih akan menjadi hasil akhir yang sama tanpa menunggu hidrasi.

NSimplementasi elemen kustom dimuat dan itu didaftarkan. Jika saya mengerti dengan benar, ini adalah proses yang disebut "peningkatan". Namun, meskipun JS-nya sudah siap, tetap tidak dapat menampilkan apa pun karena kami belum menyertakan nama ikon di HTML. Jadi kami tidak memiliki informasi ikon mana yang akan dirender. Ini karena kami mengatakan sebelumnya bahwa "properti non-builtin dapat dijatuhkan dari HTML". Jadi pengguna masih melihat "lubang".

Adapun apa yang Anda sebutkan di sini, tergantung pada bagaimana komponen diimplementasikan, Anda dapat menghindari masalah melihat "lubang" ini.

Itu dapat dicapai baik hanya dengan menyetel default biasa dalam kasus ini atau dengan menerima sebagian atau bahkan sebagian besar konten melalui slot sehingga konten ditampilkan bahkan sebelum komponen ditingkatkan.


Saya pikir fitur ini akan sangat berguna untuk menggunakan komponen yang lebih kompleks yang memiliki properti yaitu Objek, Array, Fungsi, dll.

Ambil contoh, komponen scroller virtual lit-virtualizer .

Untuk ini untuk bekerja dengan baik itu membutuhkan items array dan sebuah renderItem fungsi dan Anda bahkan dapat opsional mengatur scrollTarget Element, yang semuanya hanya bisa diatur dalam Bereaksi menggunakan ref sekarang.

Untuk kasus seperti ini, Anda mungkin akan memuat konten dengan semacam pagination atau lazy loading sehingga tidak memiliki konten apa pun sampai langkah hidrasi pada kasing SSR mungkin tidak terlalu bermasalah.

@gaearon Harap dicatat bahwa elemen kustom adalah standar DOM dan oleh karena itu tidak ada "komunitas WC" dalam arti bahwa setiap orang yang menggunakan elemen kustom menggunakannya dengan cara yang sama. Elemen khusus diintegrasikan dengan caranya sendiri untuk setiap pengembang, karena pada dasarnya merupakan primitif tingkat rendah yang dibangun orang.

Yang mengatakan, seiring waktu banyak pola telah muncul dan semua kerangka kerja populer (kecuali React) menerapkan beberapa solusi untuk menyediakan kompatibilitas untuk standar DOM ini. Seperti yang Anda lihat di https://custom-elements-everywhere.com/ , semua frameworks/libraries (kecuali React) telah memilih opsi yang berbeda. Dalam edisi ini, opsi yang dipilih terdaftar sebagai opsi 1, 2 dan 3. Tidak ada kerangka kerja/pustaka yang saat ini mengimplementasikan opsi 4 atau 5 dan saya rasa tidak perlu untuk mengimplementasikannya.

Oleh karena itu, saya mengusulkan agar React mengikuti kerangka kerja/pustaka lain dan memilih opsi yang terbukti berhasil, misalnya dari opsi 1-3. Saya tidak berpikir React perlu menemukan kembali roda di sini dengan memilih opsi 4 atau 5, yang kami tidak memiliki datanya adalah solusi jangka panjang yang dapat dipelihara baik untuk React atau yang dibangun di atas standar DOM.

Jadi, dengan proses eliminasi (dengan komentar tertaut di bawah), karena opsi 3 tidak akan dilakukan ke BEJ dan opsi 4 dan 5 telah ditandai tidak diinginkan oleh orang-orang WC di utas ini, kami terjebak dengan 1 atau 2 .

Dan karena 1 sepertinya memiliki kekurangan yang tidak dapat dipertahankan, sepertinya Opsi 2 adalah salah satunya? Ikuti saja bagaimana Preact melakukannya?


Tidak ada kerangka kerja/perpustakaan yang saat ini mengimplementasikan opsi 4 atau 5 dan saya rasa tidak diinginkan untuk mengimplementasikannya.

( @TimvdLippe di https://github.com/facebook/react/issues/11347#issuecomment-713474037)

Saya pikir sangat tidak mungkin bahwa kami akan memperkenalkan sintaks JSX baru demi fitur khusus ini saja.

( @gaearon di https://github.com/facebook/react/issues/11347#issuecomment-713210204)

Itu akan masuk akal bagi saya ya. Terima kasih untuk ringkasannya! 😄

Setidaknya dalam pengalaman saya, pengaturan properti daripada atribut tidak semua yang diperlukan untuk tipe yang lebih sederhana seperti string, angka, atau boolean. Kasus yang Anda gambarkan dapat dengan mudah dicapai hanya dengan menggunakan iconname sebagai atribut secara langsung dan sebagian besar masih akan menjadi hasil akhir yang sama tanpa menunggu hidrasi.

Saya kurang mengikuti. Skenario hipotetis saya adalah respons terhadap https://github.com/facebook/react/issues/11347#issuecomment -713223628 yang terdengar seperti saran bahwa kita tidak boleh memancarkan atribut dalam HTML yang dihasilkan server sama sekali, kecuali id dan class . Saya tidak tahu apa artinya "hanya menggunakan nama ikon sebagai atribut" — maksud Anda, Anda ingin melihat HTML yang dihasilkan server _include_ atribut lain? Hal ini tampaknya bertentangan dengan apa yang baru saja dikatakan sebelumnya. Saya pikir akan sangat membantu jika setiap tanggapan menyajikan gambaran yang lengkap karena jika tidak, kita akan terus berputar-putar. Pertanyaan saya kepada Anda adalah:

  1. Apa sebenarnya yang diserialkan dalam HTML yang dihasilkan server dalam skenario yang saya jelaskan
    A. Jika <github-icon iconname="smiley" />
    B. Dalam kasus Anda dibesarkan, misalnya <github-icon icon={{ name: "smiley" }} />
  2. Apa DOM API yang dipanggil pada klien selama hidrasi dalam salah satu dari kasus tersebut

Terima kasih!

Apakah itu dianggap sebagai opsi untuk membuat shim, mengganti React.createElement() dengan implementasi khusus, yang memetakan properti di dalamnya?

Contoh penggunaan:

/** <strong i="8">@jsx</strong> h */
import { h } from 'react-wc-jsx-shim';

function Demo({ items }) {
   return <my-custom-list items={items} />
}

Implementasi draf:

export function h(element, props, children) {
   if(typeof element === 'string' && element.includes('-')) {
      return React.createElement(Wrapper, { props, customElementName: element }, children)
   }
   return React.createElement(element, props, children);

}

function Wrapper({customElementName, props}) {
   const ref = React.useRef();
   React.useEffect(() => {
      for(const prop in props) {
         ref.current[prop] = props[prop];
      }
   });
   return React.createElement(customElementName, { ref, ...props });
}

Saya tahu bahwa ini bukan fitur bawaan, tetapi saya pikir harus membuka blokir pengguna dengan overhead yang sangat rendah.

@just-boris pada dasarnya itulah yang dilakukan aplikasi atau perpustakaan sekarang, dengan patch createElement atau pembungkus. Anda juga perlu mengecualikan nama properti dengan kasus khusus di React. Saya tidak berpikir ada daftar yang diekspor, jadi mereka hanya mengkodekan daftar yang ditolak seperti ['children', 'localName', 'ref', 'elementRef', 'style', 'className'] .

Karena berbasis ref, properti tidak disetel di server. Inilah mengapa saya menyebut kekhawatiran itu samar-samar. Tidak ada cara untuk mengatur properti sama sekali di React, jadi semuanya rusak sekarang. Solusi yang tersedia sudah hanya bekerja pada klien. Jika ada cara bawaan untuk mengatur properti di klien dan bukan di server, itu tidak tiba-tiba memperbaiki atau merusak SSR.

Saya sebenarnya akan lebih peduli dengan peristiwa daripada SSR. React tidak memiliki cara untuk menambahkan event handler, dan itu adalah lubang besar dalam interoperabilitas dengan DOM API dasar.

Apakah itu dianggap sebagai opsi untuk membuat shim, menggantikan React.createElement() dengan implementasi khusus, yang memetakan properti di dalamnya?

Seperti yang disebutkan oleh Rob dalam edisi asli, saya telah bereksperimen dengan ini di masa lalu melalui https://github.com/skatejs/val , jadi memiliki pragma JSX khusus yang membungkus React.createElement adalah layak - mungkin jangka pendek - solusi.

Saya juga memiliki cabang WIP Skate yang mengimplementasikan keduanya yang disebut sebagai SSR dalam dan dangkal, khusus untuk React. Pelajaran dari pekerjaan ini sejauh ini, adalah bahwa Anda tidak dapat memiliki satu pembungkus JSX untuk semua perpustakaan jika Anda ingin melakukan SSR mendalam karena setiap perpustakaan bergantung pada API dan algoritme mereka sendiri untuk melakukannya. (Untuk konteks, Skate memiliki bagian elemen kustom inti dari perpustakaannya dan lapisan kecil yang dibuat untuk mengintegrasikan setiap perpustakaan populer di pasar untuk membuat konsumsi dan penggunaan konsisten di seluruh papan.)


Saya tidak banyak beroperasi di open source lagi, dan juga tidak menggunakan Twitter lagi, jadi jangan ragu untuk mengambil pendapat saya dengan sebutir garam.

Opsi 1 terasa seperti ada sebagai pendukung iblis untuk Opsi 2.

Opsi 2 terasa seperti jalan yang harus ditempuh. Ini dekat dengan apa yang telah dilakukan Preact, jadi ada preseden dan kemungkinan standar komunitas (yang menurut saya akan luar biasa untuk dilakukan; JSX telah menunjukkan ini dapat berhasil), dan ini juga merupakan langkah pragmatis untuk React agar mudah ditingkatkan (sebagai lawan dari Opsi 1).

Opsi 3 terlihat bagus di atas kertas, tetapi saya pikir secara logistik itu akan jauh lebih sulit daripada Opsi 2 karena overhead kognitif, mendokumentasikan sekitar overhead tersebut, dan tidak diketahui dengan SSR.

Seperti yang disebutkan, saya awalnya menyajikan opsi 4 tetapi setelah refleksi, saya tidak yakin saya menyukainya lagi. Anda dapat mengubahnya menjadi lebih memilih, di mana Anda menentukan props dan events eksplisit (bukan attrs ), tetapi meskipun demikian Opsi 2 membutuhkan lebih sedikit pengetahuan tentang detail implementasi dan tidak ada yang harus diubah oleh siapa pun untuk mengadopsinya.

Opsi 5 terasa seperti kita akan mengabaikan masalah inti sepenuhnya.


Selain itu, saya sangat senang melihat daya tarik ini dan berharap Anda semua baik-baik saja!

Jika ada solusi yang memungkinkan di userland, apakah bisa dikonsolidasikan dan direkomendasikan oleh komunitas untuk saat ini?

Akan jauh lebih mudah untuk meyakinkan tim inti React untuk menambahkan fitur jika sudah ada sebagai modul pihak ketiga yang populer dan layak.

Jika ada solusi yang memungkinkan di userland, apakah bisa dikonsolidasikan dan direkomendasikan oleh komunitas untuk saat ini?

Saya tidak percaya ini adalah sesuatu yang bisa [rapi] ditambal dari luar. Sebagian besar solusi userland adalah pembungkus seperti this dan this . Tanpa memodifikasi Bereaksi, saya tidak bisa memikirkan alternatif yang masuk akal untuk pendekatan ini, dan membungkus jelas bukan solusi yang ideal. 😕

Perhatikan bahwa di vuejs/vue#7582, Vue memilih untuk menggunakan sigil, dan mereka memilih "." sebagai awalan (bukan "@") Glimmer.

Saya tidak memiliki tautan ke pernyataan otoritatif tentang ini (dan mungkin seseorang yang lebih dekat dengan Vue dapat mengonfirmasi secara eksplisit), tetapi tampaknya Vue telah pindah ke Opsi 2 pada Vue 3.0, artinya ia berperilaku mirip dengan Preact. (Lihat masalah ini untuk konteksnya.)

Karena berbasis ref, properti tidak disetel di server. Inilah mengapa saya menyebut kekhawatiran itu samar-samar. Tidak ada cara untuk mengatur properti sama sekali di React, jadi semuanya rusak sekarang. Solusi yang tersedia sudah hanya bekerja pada klien. Jika ada cara bawaan untuk mengatur properti di klien dan bukan di server, itu tidak tiba-tiba memperbaiki atau merusak SSR.

Bisakah Anda menjawab pertanyaan spesifik di https://github.com/facebook/react/issues/11347#issuecomment -713514984? Aku merasa seperti kita sedang berbicara melewati satu sama lain. Saya hanya ingin memahami seluruh perilaku yang dimaksudkan — dengan cara tertentu. Apa yang disetel kapan, dan apa yang diserialisasikan dalam kasus apa.

Sebagai pengembang Preact+WC acak yang tersandung di sini, saya ingin menunjukkan bahwa "Opsi 2" tidak hanya _melanggar perubahan_, tetapi juga _solusi tidak lengkap_ (Preact masih hanya dapat berinteraksi secara deklaratif dengan subset Komponen Web yang valid).

Bahkan sebagai pengguna heuristik saat ini, kedengarannya tidak diinginkan dalam jangka panjang.


Heuristik Preact ("opsi 2") tidak dapat mengatur properti yang memiliki arti khusus dalam React (key, children, dll.) atau Preact (apa pun yang dimulai dengan on ).

Yaitu setelah rendering di bawah BEJ:

<web-component key={'key'} ongoing={true} children={[1, 2]} />

properties key , ongoing dan children semuanya akan menjadi undefined (atau apa pun nilai defaultnya) pada instance web-component .

Juga, bertentangan dengan OP, opsi ini juga merupakan perubahan yang melanggar. Sebagian besar komponen web (misalnya dibuat dengan lit-element ) menawarkan kemampuan untuk melewatkan data kaya serial melalui atribut, untuk tujuan digunakan dengan HTML murni. Komponen seperti itu dapat dirender dari React seperti itu

<web-component richdata={JSON.stringify(something)} />

yang akan rusak jika "opsi 2" dipilih. Tidak yakin seberapa umum penggunaan komponen web seperti itu di React, tetapi pasti ada beberapa basis kode yang melakukannya, kurang efisien daripada referensi tetapi juga terser.

Akhirnya, penulis Komponen Web bebas untuk melampirkan semantik yang agak berbeda ke atribut dan properti dengan nama yang sama. Contohnya adalah Komponen Web yang meniru perilaku elemen input - memperlakukan atribut value sebagai nilai awal, dan hanya mengamati perubahan pada properti value . Komponen tersebut tidak dapat sepenuhnya berinteraksi melalui jsx dengan pendekatan heuristik, dan juga dapat mengalami kerusakan halus jika diperkenalkan.

Saya pikir sangat tidak mungkin bahwa kami akan memperkenalkan sintaks JSX baru demi fitur khusus ini saja.

Bagaimana dengan menggunakan namespace? https://github.com/facebook/jsx/issues/66 mengusulkan untuk menambahkan ruang nama react untuk key dan ref . Sejalan dengan itu, akankah sesuatu seperti react-dom menjadi namespace yang baik untuk dicetak untuk mengidentifikasi properti DOM? Menggunakan contoh opsi 3 OP, itu adalah:

<custom-img react-dom:src="corgi.jpg" react-dom:hiResSrc="[email protected]" width="100%">

Itu bukan yang paling ergonomis. Hanya dom akan lebih baik, tetapi tidak yakin apakah React ingin membuat ruang nama yang tidak dimulai dengan react . Juga, ergonomi yang buruk dalam hal ini bukanlah akhir dunia, jika idenya adalah bahwa pengaturan sebagai properti seharusnya menjadi kasus yang kurang umum. Menggunakan atribut lebih baik, karena memberikan paritas dengan SSR. Menetapkan sebagai properti adalah ketika atribut bermasalah (seperti untuk meneruskan objek atau untuk properti yang tidak didukung oleh atribut), dan justru untuk properti bermasalah itulah kita tidak dapat melakukan SSR ke atribut, dan perlu menghidrasinya melalui JS.

_solusi tidak lengkap_

(Preact masih hanya dapat berinteraksi secara deklaratif dengan subset Komponen Web yang valid)

@brainlessbadger dapatkah Anda juga mengedit komentar Anda di atas untuk memasukkan apa sebenarnya subset ini? Misalnya. Komponen Web/Elemen Kustom mana yang terpengaruh (dengan contoh)? Dan bagaimana tepatnya mereka terpengaruh?

@karlhorky saya menambahkan penjelasan. Maaf karena tidak jelas.

Mengenai acara Komponen Web. Apakah ada konsensus tentang bagaimana menghindari pemblokiran di masa depan dengan menabrak nama acara?

Ini adalah masalah untuk atribut dan properti juga karena atribut baru dapat ditambahkan ke HTMLElement seperti semua ini: https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes Sepertinya ada beberapa yang baru ditambahkan juga jadi masih ada yang baru ditambahkan.

Saya pikir sebenarnya Anda harus menggunakan - atas nama atribut khusus atau acara khusus apa pun.

Hal lain adalah kompromi yang menimbang risiko komponen yang memblokir spesifikasi masa depan dari menggunakan nama yang bagus.

Peristiwa membuat saya ekstra gugup karena itu bukan hanya risiko komponen itu memiliki perilaku yang tidak sesuai. Jika peristiwa baru menggelembung, itu akan memicu semua Komponen Web yang ada di jalur pohon itu.

Jika atribut dan peristiwa khusus diharuskan menggunakan - dalam namanya yang dapat digunakan sebagai heuristik untuk menentukan apa yang akan digunakan. Kemudian kami akan membuat kasus khusus yang built-in. Itu sudah bagaimana kita tahu apakah itu elemen kustom di tempat pertama.

Properti kemudian dapat digunakan sebagai kemudahan untuk memberikan short hand yang lebih bagus. Setidaknya itu bisa membayangi properti bawaan dan tidak bertabrakan dengan properti masa depan.

Saya pikir secara tegas Anda harus menggunakan - atas nama atribut khusus atau acara khusus apa pun.

Spesifikasi elemen kustom tidak menyertakan batasan seperti itu, jadi menerapkannya di React akan secara signifikan memengaruhi interoperabilitas.

Penulis elemen khusus tidak boleh diharapkan untuk berlangganan persyaratan sewenang-wenang kerangka kerja. Bayangkan setiap kerangka melakukan ini dengan berbagai pendapat dan konvensi. Ini mengalahkan tujuan menggunakan komponen web. 😕

Idealnya, kerangka kerja harus beradaptasi untuk mengakomodasi standar.

Memang. setAttribute() dan dispatchEvent() hanyalah API khusus non-komponen web yang mengizinkan nama arbitrer sejak awal. Elemen apa pun dapat memiliki atribut apa pun dan memicu peristiwa apa pun - itu hanya kebenaran dasar DOM.

Namespace data- ditambahkan karena suatu alasan. Ada perbedaan antara apa yang secara teknis dapat Anda lakukan dan praktik terbaik. Anda juga dapat menambal prototipe secara teknis, tetapi kemudian Anda mendapatkan situasi berisi/termasuk.

Saya tidak akan menyarankan bahwa React saja yang menambahkan ini tetapi komunitas beralih ke konvensi ini untuk membantu melindungi namespace di masa depan. Saya hanya berpikir sangat disayangkan bahwa masalah ini tidak dianggap serius. Tapi mungkin web ditakdirkan untuk hanya menambahkan nama canggung ke API baru.

Saya menyukai gagasan untuk mengecualikan non-builtin dari SSR dan lebih memilih properti selama hidrasi karena dengan DOM bayangan deklaratif, konten sebenarnya dapat diperluas di dalamnya.

Konkretnya meskipun saya percaya itu akan menyebabkan masalah untuk pendekatan saat ini yang digunakan orang dengan SSR + AMP karena itu menggunakan atribut dan Anda dapat mengasumsikan bahwa runtime AMP telah dimuat.

Dengan asumsi pintu tidak tertutup pada opsi 3, ini memiliki keunggulan signifikan dibandingkan opsi 2, tidak tercantum dalam kontra di atas -- Masalah yang saya temukan dengan opsi 2 adalah jika pustaka komponen web dimuat secara tidak sinkron , preact mungkin tidak tahu, untuk elemen yang tidak diketahui, bahwa "properti" akan menjadi properti. Karena tidak menemukan properti yang ada di elemen yang tidak dikenal, defaultnya adalah atribut. Solusinya adalah tidak merender komponen itu, hingga pustaka komponen web yang bergantung dimuat, yang tidak terlalu elegan (atau dari segi kinerja yang ideal). Karena grup saya menggunakan asp.net, bukan node.js, saya belum pernah explore SSR banget, jadi pengamatan di bawah ini spekulatif.

Ini adalah isyarat yang bagus, saya pikir, di pihak tim React, untuk menyarankan melampaui dan melampaui apa yang didukung oleh kerangka kerja lain (sepengetahuan saya), sejauh SSR, memungkinkan properti objek diturunkan selama rendering awal, yang dapat melayani pengguna lebih baik.

Aku tidak tahu apakah aku menyatakan yang sudah jelas atau tidak, tapi saya pikir ada sedikit konsensus dengan komponen web yang untuk beberapa properti, akan lebih mudah untuk kadang-kadang mengatur nilai awal dari atribut melalui string JSON , dibungkus dengan tanda kutip tunggal.

AMP menggunakan konvensi lain -- AMP menggunakan script type=application.json untuk melakukan ini, yang merupakan alternatif yang masuk akal (tetapi bertele-tele).

Tetapi tetap dengan pendekatan atribut:

Pustaka komponen web kemudian dapat mengurai atribut, atau diteruskan dalam nilai melalui properti.

Jadi untuk menghindari penundaan hidrasi, akan lebih mudah untuk mengatur:

<github-icon icon='{"name":"smiley"}'></github-icon>

selama RSK. Kemudian github-icon dapat segera melakukan tugasnya, melakukan JSON.parse atribut secara internal, dan tidak perlu menunggu React untuk meneruskan nilai objek (lebih lengkap?).

Jadi sekarang kita memiliki situasi yang rumit -- jika rendering di server, kita ingin "ikon" diperlakukan sebagai atribut, tetapi dapat meneruskan nilai sebagai objek, yang idealnya mekanisme SSR akan dirangkai menjadi atribut. Pada klien kami ingin dapat mengirimkan objek secara langsung, dan tidak melalui overhead stringifying dan parsing.

Tentu saja, beberapa properti adalah objek yang tidak dapat dirangkai/diuraikan, jadi ini tidak berlaku, dan properti tersebut perlu menunggu hingga hidrasi selesai.

Jika semua properti dan atribut mengikuti konvensi penamaan pilihan tim React (mungkin) -- semua atribut memiliki tanda hubung, dan semua properti adalah nama majemuk menggunakan camelCase, mungkin keberadaan tanda hubung dapat membantu membedakan antara atribut dan properti:

<github-icon my-icon={myStringifiedProperty} myIcon={myObjectProperty}></github-icon>

Masalahnya tidak ada dalam sintaks di atas yang menunjukkan apa yang harus dilakukan di server versus klien, dan idealnya kita dapat menggunakan satu pengikatan untuk keduanya, dan React akan cukup pintar untuk mencari tahu mana yang akan digunakan.

React hanya bisa berasumsi bahwa jika atribut/kunci properti adalah case unta, untuk selalu meneruskannya sebagai objek di sisi klien, dan serialisasi objek yang dirangkai JSON jika disetel selama SSR. Demikian juga, tanda hubung pada kunci dapat (dengan aman, menurut saya) menganggapnya sebagai atribut, dan hanya meneruskan .toString() dari nilai tersebut. Tapi saya pikir ini mengasumsikan terlalu banyak. Dan tidak mendukung atribut dan properti kata tunggal, yang dianggap HTML valid jika atribut diterapkan ke komponen web yang memperluas HTMLElement, akan terlalu dibatasi. Saya mendukung W3C mengeluarkan daftar nama atribut "cadangan" yang mungkin digunakan di masa depan, mirip dengan kata kunci yang dicadangkan untuk JS, dan kerangka kerja menemukan cara untuk memperingatkan pengembang jika mereka menggunakan nama atribut yang dicadangkan secara tidak benar.

Tapi saya pikir opsi 3 adalah pendekatan terbaik. Namun, jika dapat ditingkatkan, seperti yang disarankan oleh @gaearon , untuk pengalaman pengguna yang lebih baik, itu akan sangat bagus.

Saran saya adalah:

<github-icon icon={myDynamicIcon}/>

berarti atribut (toString()).

<github-icon icon:={myDynamicIcon}/>

berarti -- selama SSR, abaikan, tetapi ikat klien ke properti objek (setelah menghidrasi).

Sekarang bagaimana dengan skenario (beberapa?) Tim React tertarik untuk memecahkannya? Pikiran pertama saya hanyalah beberapa sigil lain, seperti dua titik dua:

<github-icon icon::={myDynamicIcon}/> //Not my final suggestion!

akan berarti, selama SSR, JSON.stringify properti, ditetapkan sebagai atribut dalam HTML yang dirender, dan diteruskan sebagai objek pada klien saat properti yang diikatnya berubah setelah hidrasi.

Ini meninggalkan situasi rumit tentang apa yang harus dilakukan dengan nama majemuk. Yaitu jika kita mengatur:

<github-icon iconProps::={myDynamicIconProp}/>  //Not my final suggestion!

tidak kontroversial di masa lalu bahwa atribut yang sesuai untuk nama properti iconProps harus icon-props.

Mungkin ini menjadi lebih kontroversial, karena momok bahwa beberapa komponen web ini dapat, tanpa perubahan, menjadi terpasang ke dalam platform, di mana atribut tidak boleh memiliki tanda hubung (tetapi properti dapat berupa camelCase). Sepengetahuan saya, belum ada elemen asli yang memungkinkan meneruskan objek kompleks melalui deserializing JSON, tetapi saya tidak akan terkejut jika kebutuhan muncul di masa mendatang. Jadi bagaimana Bereaksi tahu kapan harus memasukkan tanda hubung atau tidak?

Satu-satunya saran (jelek?) yang bisa saya berikan adalah:

<github-icon icon-props:iconProps={myDynamicIconProp}/>

yang berarti, di server, gunakan atribut icon-props setelah membuat serial, dan pada klien gunakan property iconProps, meneruskan objek secara langsung.

Manfaat potensial lain (long shot?) dari notasi yang lebih verbose, memungkinkan untuk atribut hybrid / pasangan properti, adalah ini: Mungkin sedikit lebih cepat untuk mengatur properti elemen asli secara berulang, daripada atribut yang sesuai, terutama untuk properti yang bukan string. Jika demikian, apakah React saat ini menggunakan atribut di server, dan properti di klien? Jika tidak, apakah karena masalah kesulitan penerjemahan penamaan yang sama, notasi mana yang akan dipecahkan?

@bahrus saya pikir itu bisa disederhanakan

<my-element attr='using-quotes' property={thisIsAnObject} />

Saya pikir mungkin lebih baik untuk mengilustrasikan masalah ini dengan contoh konkret.

Elemen HTML Form memiliki sejumlah atribut. Yang dengan "nama majemuk" tampaknya tidak semuanya mengikuti pola penamaan yang konsisten -- umumnya tetap dengan huruf kecil semua, tanpa pemisah, tetapi terkadang ada pemisah tanda hubung -- "terima-charset" misalnya, terkadang tidak - - "tidak memvalidasi".

Nama properti JS yang sesuai juga tidak cocok dengan pola universal yang bagus -- acceptCharset, noValidate. Properti noValidate / atribut novalidate adalah boolean, jadi pada klien, akan sia-sia (saya bayangkan) untuk melakukan myForm.setAttribute('novalidate', '') sebagai lawan dari myForm.noValidate = true.

Namun, di server, tidak masuk akal untuk menyetel myForm.noValidate = true, karena kami ingin mengirim representasi string dari DOM, jadi kami perlu menggunakan atribut:

<form novalidate={shouldNotValidate}>

Sebenarnya, tidak jelas bagi saya bahwa React/JSX memiliki cara universal untuk menetapkan atribut boolean secara kondisional , mengandalkan, mungkin, pada tabel pencarian statis yang tetap, yang tampaknya(?) terlalu kaku . Jika saya berani, ini sepertinya area lain yang dapat ditingkatkan React/JSX, agar sepenuhnya kompatibel dengan cara kerja (berantakan) DOM, sebagai bagian dari RFC ini?

Bagaimana kita bisa mewakili semua skenario ini, sehingga pengembang memiliki kontrol penuh pada server (melalui atribut) dan klien (melalui properti), tanpa mengorbankan kinerja? Dalam kasus boolean seperti novalidate, saya akan mengusulkan:

<form novalidate:noValidate?={shouldNotValidate}/>

Jika Bereaksi sepenuhnya mendukung DOM, berantakan seperti itu, dengan kinerja sebaik mungkin, saya pikir itu akan sangat membantu untuk mendukung elemen khusus, yang juga mungkin tidak terlalu konsisten dalam pola penamaan.

Menambahkan dukungan untuk membuat serial properti objek secara opsional ke atribut melalui JSON.stringify di server, menurut saya akan menjadi win-win tambahan yang besar untuk React dan komponen web, menurut saya.

Atau apakah saya melewatkan sesuatu? ( @eavichay , bagaimana Anda menyarankan skenario ini paling baik diwakili, tidak mengikuti contoh Anda).

Apakah halaman ini membantu?
0 / 5 - 0 peringkat