Saya datang dari dunia sudut di mana saya dapat mengekstrak logika ke layanan / pabrik dan mengkonsumsinya dalam pengontrol saya.
Saya mencoba memahami bagaimana saya dapat mencapai hal yang sama dalam aplikasi Bereaksi.
Katakanlah saya memiliki komponen yang memvalidasi input kata sandi pengguna (kekuatannya). Logikanya cukup rumit sehingga saya tidak ingin menuliskannya di komponen itu sendiri.
Di mana saya harus menulis logika ini? Di toko jika saya menggunakan fluks? Atau ada opsi yang lebih baik?
reactjs
reactjs-flux
Dennis Nerush
sumber
sumber
Jawaban:
Jawaban pertama tidak mencerminkan paradigma Container vs Presenter saat ini .
Jika Anda perlu melakukan sesuatu, seperti memvalidasi kata sandi, kemungkinan Anda memiliki fungsi yang melakukannya. Anda akan meneruskan fungsi itu ke tampilan yang dapat digunakan kembali sebagai penyangga.
Wadah
Jadi, cara yang benar untuk melakukannya adalah dengan menulis ValidatorContainer, yang akan memiliki fungsi itu sebagai properti, dan membungkus formulir di dalamnya, meneruskan alat peraga yang tepat kepada anak. Ketika datang ke tampilan Anda, wadah validator Anda membungkus tampilan Anda dan tampilan mengkonsumsi logika kontainer.
Validasi dapat dilakukan semua di properti penampung, tetapi jika Anda menggunakan validator pihak ketiga, atau layanan validasi sederhana apa pun, Anda dapat menggunakan layanan ini sebagai properti komponen kontainer dan menggunakannya dalam metode penampung. Saya telah melakukan ini untuk komponen yang tenang dan bekerja dengan sangat baik.
Penyedia
Jika ada sedikit konfigurasi yang diperlukan, Anda dapat menggunakan model Penyedia / Konsumen. Penyedia adalah komponen tingkat tinggi yang membungkus di suatu tempat dekat dan di bawah objek aplikasi teratas (yang Anda pasang) dan memasok bagian dari dirinya sendiri, atau properti yang dikonfigurasi di lapisan atas, ke konteks API. Saya kemudian mengatur elemen wadah saya untuk mengkonsumsi konteksnya.
Hubungan konteks orang tua / anak tidak harus dekat satu sama lain, hanya saja anak harus diturunkan dengan cara tertentu. Redux menyimpan dan Bereaksi fungsi Router dengan cara ini. Saya telah menggunakannya untuk memberikan konteks root restful untuk wadah istirahat saya (jika saya tidak menyediakan sendiri).
(catatan: API konteks ditandai eksperimental dalam dokumen, tapi saya rasa itu tidak lagi, mengingat apa yang menggunakannya).
Middleware
Cara lain yang belum saya coba, tetapi terlihat digunakan, adalah menggunakan middleware bersamaan dengan Redux. Anda menentukan objek layanan Anda di luar aplikasi, atau setidaknya, lebih tinggi dari toko redux. Selama pembuatan toko, Anda menyuntikkan layanan ke middleware dan middleware menangani tindakan apa pun yang memengaruhi layanan.
Dengan cara ini, saya bisa menyuntikkan objek restful.js saya ke middleware dan mengganti metode wadah saya dengan tindakan independen. Saya masih membutuhkan komponen kontainer untuk memberikan tindakan ke lapisan tampilan formulir, tetapi terhubung () dan mapDispatchToProps telah saya bahas di sana.
Misalnya, v4 react-router-redux menggunakan metode ini untuk memengaruhi keadaan sejarah, misalnya.
sumber
Masalahnya menjadi sangat sederhana ketika Anda menyadari bahwa layanan Angular hanyalah objek yang memberikan serangkaian metode konteks-independen. Hanya mekanisme DI Sudut yang membuatnya terlihat lebih rumit. DI berguna karena menangani pembuatan dan pemeliharaan instance untuk Anda, tetapi Anda tidak benar-benar membutuhkannya.
Pertimbangkan perpustakaan AJAX populer bernama axios (yang mungkin pernah Anda dengar):
Bukankah itu berperilaku sebagai layanan? Ini memberikan seperangkat metode yang bertanggung jawab untuk beberapa logika tertentu dan independen dari kode utama.
Contoh kasus Anda adalah tentang membuat seperangkat metode terisolasi untuk memvalidasi input Anda (misalnya memeriksa kekuatan kata sandi). Beberapa menyarankan untuk meletakkan metode ini di dalam komponen yang bagi saya jelas merupakan anti-pola. Bagaimana jika validasi melibatkan membuat dan memproses panggilan backend XHR atau melakukan perhitungan kompleks? Apakah Anda akan mencampur logika ini dengan penangan klik mouse dan hal-hal khusus UI lainnya? Omong kosong. Sama dengan pendekatan container / HOC. Membungkus komponen Anda hanya untuk menambahkan metode yang akan memeriksa apakah nilainya memiliki angka di dalamnya? Ayolah.
Saya hanya akan membuat file baru bernama say 'ValidationService.js' dan mengaturnya sebagai berikut:
Kemudian di komponen Anda:
Gunakan layanan ini dari mana saja Anda inginkan. Jika aturan validasi berubah, Anda harus fokus hanya pada file ValidationService.js.
Anda mungkin memerlukan layanan yang lebih rumit yang tergantung pada layanan lain. Dalam hal ini, file layanan Anda dapat mengembalikan konstruktor kelas alih-alih objek statis sehingga Anda dapat membuat instance objek sendiri di komponen. Anda juga dapat mempertimbangkan penerapan singleton sederhana untuk memastikan bahwa selalu ada hanya satu contoh objek layanan yang digunakan di seluruh aplikasi.
sumber
Saya membutuhkan beberapa logika format untuk dibagikan di beberapa komponen dan sebagai pengembang Angular juga secara alami condong ke layanan.
Saya membagikan logika dengan meletakkannya di file terpisah
dan kemudian mengimpornya sebagai modul
sumber
Perlu diingat bahwa tujuan Bereaksi adalah untuk pasangan yang lebih baik hal-hal yang secara logis harus digabungkan. Jika Anda merancang metode "validasi kata sandi" yang rumit, di mana harus ditambah?
Anda harus menggunakannya setiap kali pengguna perlu memasukkan kata sandi baru. Ini bisa di layar pendaftaran, layar "lupa kata sandi", administrator "setel ulang kata sandi untuk pengguna lain", dll.
Tetapi dalam kasus-kasus tersebut, itu akan selalu terikat pada beberapa bidang input teks. Jadi disitulah harus ditambah.
Buat komponen Bereaksi yang sangat kecil yang hanya terdiri dari bidang input dan logika validasi yang terkait. Masukkan komponen itu ke dalam semua formulir yang mungkin ingin memiliki input kata sandi.
Ini pada dasarnya hasil yang sama dengan memiliki layanan / pabrik untuk logika, tetapi Anda memasangkannya langsung ke input. Jadi, Anda sekarang tidak perlu memberi tahu fungsi itu di mana harus mencari input validasinya, karena ia terikat secara permanen.
sumber
Saya juga berasal dari daerah Angular.js dan layanan serta pabrik di React.js lebih sederhana.
Anda dapat menggunakan fungsi atau kelas sederhana, gaya panggilan balik dan acara Mobx seperti saya :)
Ini adalah contoh sederhana:
sumber
Situasi yang sama: Setelah melakukan banyak proyek Sudut dan pindah ke React, tidak memiliki cara sederhana untuk menyediakan layanan melalui DI sepertinya adalah bagian yang hilang (rincian layanan samping).
Menggunakan dekorator konteks dan ES7 kita dapat mendekati:
https://jaysoo.ca/2015/06/09/react-contexts-and-dependency-injection/
Sepertinya orang-orang ini telah mengambil langkah maju / ke arah yang berbeda:
http://blog.wolksoftware.com/dependency-injection-in-react-powered-inversifyjs
Masih terasa seperti bekerja melawan keinginan. Akan meninjau kembali jawaban ini dalam waktu 6 bulan setelah melakukan proyek Bereaksi besar.
EDIT: Kembali 6 bulan kemudian dengan beberapa pengalaman Bereaksi lagi. Pertimbangkan sifat logika:
Beberapa juga meraih HOC untuk digunakan kembali tetapi bagi saya hal di atas mencakup hampir semua kasus penggunaan. Juga, pertimbangkan untuk menskalakan manajemen negara menggunakan bebek untuk menjaga agar perhatian tetap terpisah dan berpusat pada UI.
sumber
Saya dari Angular juga dan mencoba Bereaksi, seperti yang sekarang, satu cara yang direkomendasikan (?) Tampaknya menggunakan Komponen Orde Tinggi :
Katakanlah Anda memiliki
input
dantextarea
dan ingin menerapkan logika validasi yang sama:Kemudian tulis HOC yang melakukan validasi dan komponen yang dibungkus gaya:
Sekarang HOC tersebut memiliki perilaku validasi yang sama:
Saya membuat demo sederhana .
Sunting : Demo lain menggunakan alat peraga untuk melewati array fungsi sehingga Anda dapat berbagi logika yang disusun oleh beberapa fungsi validasi di
HOC
s seperti:Edit2 : Bereaksi 16.8+ menyediakan fitur baru, Hook , cara lain yang baik untuk logika saham.
https://stackblitz.com/edit/react-share-validation-logic-using-hook?file=index.js
sumber
HOC
, lihat edit saya untuk demo lain.Layanan tidak terbatas pada Angular, bahkan dalam Angular2 + ,
Layanan hanyalah kumpulan fungsi pembantu ...
Dan ada banyak cara untuk membuatnya dan menggunakannya kembali di aplikasi ...
1) Mereka dapat semua fungsi yang dipisahkan yang diekspor dari file js, mirip seperti di bawah ini:
2) Kita juga dapat menggunakan metode pabrik seperti, dengan koleksi fungsi ... dengan ES6 dapat berupa kelas daripada konstruktor fungsi:
Dalam hal ini Anda perlu membuat instance dengan kunci baru ...
Juga dalam hal ini, setiap instance memiliki kehidupannya sendiri, jadi berhati-hatilah jika Anda ingin membagikannya, dalam hal ini Anda harus mengekspor hanya instance yang Anda inginkan ...
3) Jika fungsi dan utilitas Anda tidak akan dibagikan, Anda bahkan dapat meletakkannya dalam komponen Bereaksi, dalam hal ini, sama seperti fungsi dalam komponen reaksi Anda ...
4) Cara lain Anda dapat menangani hal-hal, bisa menggunakan Redux , ini adalah toko sementara untuk Anda, jadi jika Anda memilikinya dalam aplikasi Bereaksi Anda , itu dapat membantu Anda dengan banyak fungsi pengambil getter setter Anda gunakan ... Ini seperti toko besar yang melacak negara Anda dan dapat membagikannya di seluruh komponen Anda, sehingga dapat menghilangkan banyak rasa sakit untuk barang-barang pengambil pengambil yang kami gunakan dalam layanan ...
Itu selalu baik untuk melakukan kode KERING dan tidak mengulangi apa yang perlu digunakan untuk membuat kode dapat digunakan kembali dan dibaca, tetapi jangan mencoba untuk mengikuti cara Angular dalam aplikasi Bereaksi , sebagaimana disebutkan dalam item 4, menggunakan Redux dapat mengurangi kebutuhan Anda akan layanan dan Anda membatasi menggunakannya untuk beberapa fungsi pembantu yang dapat digunakan kembali seperti item 1 ...
sumber
Saya di boot yang sama seperti Anda. Dalam kasus yang Anda sebutkan, saya akan menerapkan komponen UI validasi input sebagai komponen Bereaksi.
Saya setuju implementasi logika validasi itu sendiri tidak boleh digabungkan. Karena itu saya akan memasukkannya ke dalam modul JS terpisah.
Yaitu, untuk logika yang tidak harus digabungkan menggunakan modul JS / kelas dalam file terpisah, dan menggunakan memerlukan / impor untuk memisahkan komponen dari "layanan".
Ini memungkinkan untuk injeksi ketergantungan dan pengujian unit keduanya secara independen.
sumber
atau Anda bisa menyuntikkan kelas warisan "http" ke Komponen Bereaksi
melalui objek alat peraga.
perbarui:
Cukup edit React Component ReactApp seperti ini:
sumber
Nah pola yang paling sering digunakan untuk logika yang dapat digunakan kembali yang saya temui adalah menulis hook atau membuat file utils. Itu tergantung pada apa yang ingin Anda capai.
Seperti jika Anda ingin memvalidasi data formulir maka saya akan membuat kait kustom bernama useForm.js dan memberikannya formulir data dan sebagai gantinya akan mengembalikan saya sebuah objek yang berisi dua hal:
Anda pasti dapat mengembalikan lebih banyak hal darinya saat Anda maju.
Contoh lain akan seperti Anda ingin mengekstrak beberapa informasi dari URL maka saya akan membuat file utils untuknya yang berisi fungsi dan mengimpornya di mana diperlukan:
sumber