Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. React

Cara Membuat Feed Real-Time Menggunakan Phoenix dan React

by
Difficulty:IntermediateLength:LongLanguages:

Indonesian (Bahasa Indonesia) translation by Muhammad Gufron (you can also view the original English article)

Final product image
What You'll Be Creating

Dalam tutorial ini, saya akan menunjukkan kepada anda bagaimana kami dapat menggunakan kekuatan React and Phoenix untuk membuat aplikasi feed yang akan direfresh real time saat kami menambahkan feed baru ke database kami.

Pengenalan

Elixir dikenal karena stabilitas dan fitur real-time, dan Phoenix memanfaatkan kemampuan Erlang VM untuk menangani jutaan koneksi bersama sintaks yang indah dan perkakas produktif Elixir. Ini akan membantu kami dalam menghasilkan pembaruan data secara real-time melalui API yang akan digunakan oleh aplikasi React kami untuk menampilkan data pada user interface.

Persiapan

Anda harus menginstal Elixir, Erlang, dan Phoenix. Lebih lanjut tentang itu dapat ditemukan di situs web framework Phoenix. Selain itu, kita akan menggunakan bare-bones React boilerplate karena dipelihara dengan baik dan didokumentasikan dengan baik.

Membuat API Ready

Di bagian ini, kami akan mem-bootstrap aplikasi Phoenix API-only kami dan menambahkan saluran untuk memperbarui API secara real time. Kami hanya akan bekerja dengan feed (ini akan berisi judul dan deskripsi), dan setelah nilainya diubah dalam database, API akan mengirim nilai yang diperbarui ke aplikasi front-end kami.

Bootstrap App

Pertama mari kita bootstrap aplikasi Phoenix.

mix phoenix.new realtime_feed_api--no-html--no-brunch

Ini akan membuat aplikasi Phoenix bare-bones di dalam folder bernama realtime_feed_api. Opsi --no-html tidak akan membuat semua file statis (yang berguna jika anda membuat aplikasi khusus API), dan opsi --no-brunch tidak akan menyertakan bundel statis Phoenix, Brunch. Pastikan anda menginstal dependensi ketika ia meminta.

Mari kita masuk ke dalam folder dan membuat database kita.

cd realtime_feed_api

Kami harus menghapus username dan password dari file config/dev.exs kami karena kami akan membuat database kami tanpa username atau password. Ini hanya untuk menjaga hal-hal sederhana untuk posting ini. Untuk aplikasi anda, pastikan anda membuat database terlebih dahulu, dengan username dan password.

mix ecto.create

Perintah di atas akan menciptakan database kita. Sekarang, kita dapat menjalankan server Phoenix kami dan menguji jika semuanya berjalan normal saat ini.

mix phoenix.server

Perintah di atas akan menghidupkan server Phoenix kita, dan kami dapat mengakses http://localhost:4000 untuk melihatnya berjalan. Saat ini, tidak akan ada kesalahan yang ditemukan karena kami belum membuat rute apa pun!

Jangan ragu untuk memverifikasi perubahan dengan commit ku.

Tambahkan Model Feed

Pada langkah ini, kami akan menambahkan model Feed kami ke aplikasi Phoenix kami. Model Feed akan terdiri dari title dan description.

mix phoenix.gen.json Feed feeds title:string description:string

Perintah di atas akan menghasilkan model dan controller Feed kami. Ini juga akan menghasilkan spesifikasi (yang tidak akan kita modifikasi dalam tutorial ini, hanya untuk membuatnya singkat).

Anda perlu menambahkan route /feeds di file web/router.ex Anda di dalam lingkup api:

resources "/feeds", FeedController, except: [:new, :edit]

Kita juga perlu menjalankan migrasi untuk membuat tabel feeds di basis data kami:

mix ecto.migrate

Sekarang, jika kita pergi ke http://localhost:4000/api/feed, kita akan melihat bahwa API mengirimkan respon kosong karena tidak ada data di tabel feeds kita.

Anda dapat memeriksa commit saya untuk referensi.

Menambahkan Chanel Feed

Pada langkah ini, kami akan menambahkan saluran Feed kami ke aplikasi Phoenix kami. Saluran menyediakan sarana komunikasi dua arah dari klien yang terintegrasi dengan lapisan Phoenix.PubSub untuk fungsi waktu nyata yang mudah.

mix phoenix.gen.channel feed

Perintah di atas akan menghasilkan file feed_channel.ex di dalam folder web/chanels. Melalui file ini, aplikasi React kami akan menukarkan data yang diperbarui dari database menggunakan soket.

Kita perlu menambahkan saluran baru ke file web/channels/user_socket.ex:

channel "feeds", RealtimeFeedApi.FeedChannel

Karena kami tidak melakukan otentikasi apa pun untuk aplikasi ini, kami dapat memodifikasi file web/saluran/feed_channel.ex kami. Kami akan membutuhkan satu metode join untuk aplikasi React kami untuk bergabung dengan chanel feed, satu metode handles_out untuk mendorong payload melalui koneksi soket, dan satu metode broadcast_create yang akan menyiarkan payload setiap kali feed baru dibuat dalam database.

Tiga metode yang didefinisikan di atas. Dalam method broadcast_create, kami menggunakan app/FeedsPage/HAS_NEW_FEEDS karena kita akan menggunakan itu sebagai konstan untuk container Redux state, yang akan bertanggung jawab untuk membiarkan aplikasi front-end tahu bahwa ada feed baru dalam database. Kami akan membahas itu ketika kami membangun aplikasi front-end kami.

Pada akhirnya, kita hanya perlu memanggil metode broadcast_change melalui file feed_controller.ex kita setiap kali data baru dimasukkan dalam method create kita. Method create kami akan terlihat seperti ini:

Method create bertanggung jawab untuk memasukkan data baru dalam database. Anda dapat memeriksa commit saya untuk referensi.

Menambahkan CORS Support  untuk API

Kami perlu menerapkan support ini karena, dalam kasus kami, API dilayani dari http://localhost:4000 tetapi aplikasi front-end kami akan berjalan di http://localhost:3000. Menambahkan CORS support itu mudah. Kita hanya perlu menambahkan cors_plug ke file mix.exs kami:

Sekarang, kami stop server Phoenix kami menggunakan Control-C dan mengambil ketergantungan menggunakan perintah berikut:

mix deps.get

Kita perlu menambahkan baris berikut ke file lib/realtime_feed_api/endpoint.ex kami:

plug CORSPlug

Anda dapat memeriksa commit saya. Kami selesai dengan semua perubahan back-end kami. Mari sekarang fokus pada aplikasi front-end.

Update Data Front-End secara Real Time

Seperti yang disebutkan sebelumnya, kami akan menggunakan react-boilerplate untuk memulai dengan aplikasi front-end kami. Kami akan menggunakan Redux saga yang akan mendengarkan tindakan kami yang dikirim, dan berdasarkan itu, user interface akan memperbarui data.

Karena semuanya sudah dikonfigurasi di boilerplate, kami tidak perlu mengkonfigurasinya. Namun, kami akan menggunakan perintah yang tersedia di boiler untuk men-scaffold aplikasi kami. Pertama mari kita mengkloning repositori:

git clone https://github.com/react-boilerplate/react-boilerplate.git realtime_feed_ui

Bootstrap App

Sekarang, kita harus masuk ke folder realtime_feed_ui dan menginstal dependensi.

cd realtime_feed_ui && npm run setup

Ini menginisialisasi proyek baru dengan boiler ini, menghapus sejarah git react-boilerplate, menginstal dependensi, dan menginisialisasi repositori baru.

Sekarang, mari kita hapus contoh aplikasi yang disediakan oleh boilerplate, dan ganti dengan kode boilerplate terkecil yang diperlukan untuk mulai menulis aplikasi kita:

npm run clean

Kita sekarang dapat memulai aplikasi kita menggunakan npm run start dan melihatnya berjalan di  http://localhost:3000/.

Anda dapat merujuk ke commit saya.

Tambahkan Container yang Diperlukan

Pada langkah ini, kami akan menambahkan dua kontainer baru, FeedsPage dan AddFeedPage, ke aplikasi kami. Container FeedsPage akan menampilkan daftar feed, dan container AddFeedPage akan memungkinkan kita untuk menambahkan feed baru ke database kita. Kami akan menggunakan generator react-boilerplate untuk membuat container kami.

npm run generate container

Perintah di atas digunakan untuk men-scaffold sebuah container di aplikasi kami. Setelah anda mengetikkan perintah ini, ia akan meminta nama komponen, yang akan menjadi FeedsPage dalam kasus ini, dan kami akan menggunakan opsi Component pada langkah berikutnya. Kami tidak akan membutuhkan header, tetapi kami akan membutuhkan actions/constants/selectors/reducer serta sagas untuk arus asynchronous kami. Kita tidak perlu i18n messages untuk aplikasi kita. Kita juga perlu untuk mengikuti pendekatan yang sama untuk membuat container AddFeedPage kami.

Sekarang, kami memiliki banyak file baru untuk digunakan. Ini menghemat banyak waktu. Kalau tidak, kita harus membuat dan mengkonfigurasi semua file ini oleh diri kita sendiri. Juga, generator membuat file test, yang sangat berguna, tetapi kami tidak akan menulis test sebagai bagian dari tutorial ini.

Mari kita tambahkan container dengan cepat ke file routes.js kami:

Ini akan menambahkan wadah FeedsPage kami ke rute /feed kami. Kami dapat memverifikasi ini dengan mengunjungi http://localhost:3000 feed. Saat ini, ini akan benar-benar kosong karena kami tidak memiliki apa pun di containers kami, tetapi tidak akan ada kesalahan di konsol browser kami.

Kami akan melakukan yang sama untuk container AddFeedPage kami.

Anda dapat merujuk ke commit saya untuk semua perubahan.

Membangun Feeds Listing Page

Pada langkah ini kita akan membangun FeedsPage yang akan mencantumkan semua feed kami. Demi menjaga tutorial ini kecil, kami tidak akan menambahkan style apa pun di sini, tetapi di akhir aplikasi kami, saya akan membuat commit terpisah yang akan menambahkan beberapa desain ke aplikasi kami.

Mari mulai dengan menambahkan konstanta kami di file  app/containers/FeedsPage/constants.js kami:

Kami akan membutuhkan empat konstanta ini:

  • Konstanta FETCH_FEEDS_REQUEST akan digunakan untuk menginisialisasi permintaan pengambilan kami.
  • Konstanta FETCH_FEEDS_SUCCESS akan digunakan ketika permintaan mengambil berhasil.
  • Konstanta FETCH_FEEDS_ERROR akan digunakan ketika mengambil permintaan gagal.
  • Konstanta HAS_NEW_FEEDS akan digunakan ketika ada feed baru dalam database kami.

Mari kita menambahkan action kita dalam file app/containers/FeedsPage/actions.js kami:

Semua tindakan ini sudah cukup jelas. Sekarang, kami akan menyusun initialState dari aplikasi kami dan menambahkan reducer di file app/containers/FeedsPage/reducer.js kami:

Ini akan initialState dari aplikasi kita (state sebelum mengambil data dimulai). Karena kami menggunakan ImmutableJS, kami dapat menggunakan struktur data List untuk menyimpan data abadi kami. Fungsi reducer kami akan menjadi seperti berikut:

Pada dasarnya, apa yang kita lakukan di sini adalah mengubah state kita berdasarkan konstanta dari tindakan kita. Kami dapat menampilkan loader dan pesan kesalahan dengan sangat mudah dengan cara ini. Ini akan menjadi lebih jelas ketika kita menggunakan ini di user Interface kami.

Saatnya untuk membuat selector kami menggunakan reselect, yang merupakan perpustakaan selector untuk Redux. Kami dapat mengekstrak nilai status kompleks dengan sangat mudah menggunakan reselect. Mari tambahkan pemilih berikut ke file app/containers/FeedsPage/selectors.js kami:

Seperti yang Anda lihat di sini, kami menggunakan struktur initialState kami untuk mengekstrak data dari state kita. Anda hanya perlu ingat sintaks reselect.

Saatnya untuk menambahkan sagas kami menggunakan redux-saga. Di sini, ide dasarnya adalah bahwa kita perlu membuat sebuah fungsi untuk mengambil data dan fungsi yang lain untuk mengawasi fungsi awal sehingga setiap kali tindakan tertentu dikirim, kita perlu untuk memanggil fungsi awal. Mari kita menambahkan fungsi yang akan mengambil daftar feed dari aplikasi back-end di file app/containers/FeedsPage/sagas.js kami:

Di sini, request hanya fungsi util yang melakukan panggilan API kami ke back end kami. Seluruh file tersedia di react-boilerplate. Kami akan membuat sedikit perubahan setelah kami menyelesaikan file sagas.js kami.

Kita juga perlu untuk membuat satu lagi fungsi untuk mengawasi getFeeds fungsi:

Seperti yang bisa kita lihat di sini, fungsi getFeeds akan dipanggil ketika kita mengirim tindakan yang berisi konstanta FETCH_FEEDS_REQUEST.

Sekarang, mari salin file request.js dari react-boilerplate ke aplikasi kita di dalam folder app/utils dan kemudian ubah fungsi request:

Saya baru saja menambahkan beberapa default yang akan membantu kami dalam mengurangi kode di kemudian hari karena kami tidak perlu melewati metode dan header setiap kali. Sekarang, kita perlu membuat file util lain di dalam folder app/utils. Kita akan memanggil file ini socketSagas.js. Isinya empat fungsi: connectToSocket, joinChannel, createSocketChannel, dan handleUpdatedData.

Fungsi connectToSocket akan bertanggung jawab untuk menghubungkan ke soket API back-end kami. Kami akan menggunakan npm package phoenix. Jadi kita harus menginstalnya:

npm install phoenix --save

Ini akan menginstal paket npm phoenix dan menyimpannya ke file package.json kami. Fungsi connectToSocket kita akan terlihat seperti berikut:

Selanjutnya, kita mendefinisikan fungsi joinChannel kami, yang akan bertanggung jawab untuk bergabung dengan chanel tertentu dari back-end. Fungsi joinChannel akan memiliki isi sebagai berikut:

Jika proses bergabung berhasil, kami akan mencatat 'Joined successfully' hanya untuk testing. Jika ada kesalahan selama fase penggabungan, kami juga akan mencatatnya hanya untuk keperluan debugging.

createSocketChannel akan bertanggung jawab untuk menciptakan sebuah acara channel dari soket tertentu.

Fungsi ini juga akan berguna jika kita ingin berhenti berlangganan dari saluran tertentu.

HandleUpdatedData hanya akan memanggil tindakan yang diteruskan ke situ sebagai argumen.

Sekarang, mari tambahkan sisa saga di file app/containers/FeedsPage/sagas.js kami. Kita akan menciptakan dua fungsi lain di sini: connectWithFeedsSocketForNewFeeds dan watchConnectWithFeedsSocketForNewFeeds.

Fungsi connectWithFeedsSocketForNewFeeds akan bertanggung jawab untuk menghubungkan dengan soket back-end dan memeriksa feed baru. Jika ada feed baru, ini akan memanggil fungsi createSocketChannel dari file utils/socketSagas.js, yang akan membuat channel acara untuk soket yang diberikan. Fungsi connectWithFeedsSocketForNewFeeds kami akan berisi hal-hal berikut:

Dan watchConnectWithFeedsSocketForNewFeeds akan memiliki berikut:

Sekarang, kami akan mengikat semuanya dengan file app/containers/FeedsPage/index.js kami. File ini akan berisi semua elemen antarmuka pengguna kami. Mari kita mulai dengan memanggil prop yang akan mengambil data dari bagian belakang di componentDidMount kami:

Ini akan mengambil semua umpan. Sekarang, kita perlu memanggil fetchFeedsRequest prop lagi setiap kali hasNewFeeds prop benar (anda bisa merujuk ke initialState reducer kami untuk struktur aplikasi kami):

Setelah ini, kami hanya membuat feed dalam fungsi render kami. Kami akan membuat fungsi FeedsNode dengan konten berikut:

Dan kemudian, kita dapat memanggil metode ini dalam metode render kami:

Jika kita sekarang pergi ke http://localhost:3000/feeds, kita akan melihat berikut login konsol:

Bergabung Sukses Bergabung feeds

Ini berarti bahwa API umpan kami berfungsi dengan baik, dan kami telah berhasil menghubungkan front-end kami dengan aplikasi back-end kami. Sekarang, kita hanya perlu membuat formulir agar kita dapat memasukkan feed baru.

Jangan ragu untuk merujuk pada commit saya karena banyak hal yang dilakukan dalam commit ini!

Buat Formulir untuk Menambah Feed Baru

Pada langkah ini, kami akan membuat formulir yang melaluinya kami dapat menambahkan umpan baru ke database kami.

Mari kita mulai dengan menambahkan konstanta ke file app/containers/AddFeedPage/constants.js kami:

Konstanta UPDATE_ATTRIBUTES akan digunakan ketika kita menambahkan beberapa teks ke kotak input. Semua konstanta lainnya akan digunakan untuk menyimpan judul dan deskripsi feed ke database kami.

Kontainer AddFeedPage akan menggunakan empat action: updateAttribut, saveFeedRequest, saveFeed, dan saveFeedError. Fungsi updateAttributes akan memperbarui atribut feed baru kami. Ini berarti setiap kali kita mengetik sesuatu di kotak input dari judul dan deskripsi feed, fungsi updateAttributes akan memperbarui status Redux kita. Keempat tindakan ini akan terlihat seperti berikut:

Selanjutnya, mari kita tambahkan fungsi reducer kami dalam app/containers/AddFeedPage/reducer.js file. InitialState akan terlihat seperti berikut:

Dan fungsi reducer akan terlihat seperti:

Selanjutnya, kita akan mengkonfigurasi file app/containers/AddFeedPage/selectors.js kami. Itu akan memiliki empat penyeleksi: titledescriptionerror, dan saving. Seperti namanya, selector ini akan mengekstraksi status ini dari status Redux dan membuatnya tersedia dalam wadah kami sebagai alat peraga.

Keempat fungsi ini akan terlihat seperti berikut:

Selanjutnya, mari kita konfigurasi sagas kami untuk container AddFeedPage. Ini akan memiliki dua fungsi: saveFeed dan watchSaveFeed. Fungsi saveFeed akan bertanggung jawab untuk melakukan permintaan POST ke API kami, dan itu akan memiliki hal-hal berikut:

Fungsi watchSaveFeed akan mirip dengan fungsi jam sebelumnya kami:

Selanjutnya, kita hanya perlu membuat formulir di container kami. Untuk menjaga agar termodulasi, mari buat sub-komponen untuk form. Buat file form.js baru di dalam app/containers/AddFeedPage/sub-components folder (folder sub-components adalah folder baru yang Anda akan harus membuat). Ini akan berisi form dengan satu input box untuk judul feed dan satu textarea untuk deskripsi feed. Method render akan memiliki isi sebagai berikut:

Kami akan membuat dua fungsi lagi: handleChange dan handleSubmit. Fungsi handleChange bertanggung jawab untuk memperbarui status Redux kami setiap kali kami menambahkan beberapa teks, dan fungsi handleSubmit memanggil API kami untuk menyimpan data dalam status Redux kami.

Fungsi handleChange memiliki isi seperti berikut:

Dan fungsi handleSubmit akan berisi sebagai berikut:

Di sini, kami menyimpan data dan kemudian membersihkan nilai form.

Sekarang, kembali ke file app/containers/AddFeedPage/index.js kami, kita akan hanya me-render form kami dibuat.

Sekarang, semua pengkodean kami selesai. Jangan ragu untuk memeriksa commit saya jika anda memiliki keraguan.

Finalisasi

Kami telah menyelesaikan pembangunan aplikasi kita. Sekarang, kami dapat mengunjungi http://localhost:3000/feed/new dan menambahkan feed baru yang akan ditampilkan secara real time di http://localhost:3000/feeds. Kami tidak perlu merefresh halaman untuk melihat feed baru. Anda juga dapat mencoba ini dengan membuka http://localhost:3000/feed pada dua tab secara berdampingan dan mengujinya!

Kesimpulan

Ini akan menjadi contoh aplikasi untuk menunjukkan kekuatan nyata menggabungkan Phoenix dengan React. Kami menggunakan real-time data di kebanyakan tempat sekarang, dan ini mungkin hanya membantu Anda mendapatkan feel untuk mengembangkan sesuatu seperti itu. Saya berharap bahwa anda menemukan tutorial ini berguna.

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.