Apakah kait diganti dalam React Redux?

Sejak kait muncul di Bereaksi, ada banyak pertanyaan tentang apakah mereka dapat menggantikan Redux.

Saya percaya bahwa kait dan Redux memiliki sedikit kesamaan. Hooks tidak memberi kita beberapa peluang luar biasa baru untuk bekerja dengan negara. Sebagai gantinya, mereka memperluas API sehingga mereka dapat melakukan dalam Bereaksi apa yang sudah mungkin ada di dalamnya. Namun, hook API telah membuat bekerja dengan kapabilitas manajemen negara React jauh lebih nyaman. Ternyata lebih mudah untuk menggunakan kemampuan baru untuk bekerja dengan negara daripada yang lama yang tersedia dalam komponen berdasarkan kelas. Sekarang saya menggunakan alat untuk bekerja dengan keadaan komponen lebih sering daripada sebelumnya. Secara alami, saya melakukan ini hanya jika sesuai.



Untuk menjelaskan sikap saya terhadap React hooks dan Redux, saya ingin berbicara tentang situasi di mana Redux biasanya digunakan.

Apa itu Redux?


Redux adalah perpustakaan yang mengimplementasikan penyimpanan keadaan aplikasi yang dapat diprediksi. Ini juga merupakan arsitektur yang diintegrasikan dengan React.

Berikut adalah kekuatan utama Redux:

  • Representasi negara deterministik (dalam kombinasi dengan komponen murni, ini memungkinkan untuk membentuk elemen visual deterministik).
  • Dukungan untuk perubahan status transaksional.
  • Isolasi manajemen negara dari mekanisme I / O dan efek samping.
  • Kehadiran satu sumber data andal untuk negara.
  • Organisasi mudah berkolaborasi dengan negara dalam berbagai komponen.
  • Alat analisis transaksional (pencatatan otomatis objek aksi).
  • Debugging dengan kemampuan untuk merekam dan memainkan proses pelaksanaan program (Time Travel Debugging, TTD).

Dengan kata lain, Redux memungkinkan Anda untuk mengatur kode Anda dengan baik dan memungkinkan Anda untuk debug itu dengan mudah. Redux membantu mengembangkan aplikasi yang mudah dirawat. Menggunakan perpustakaan ini memudahkan untuk menemukan sumber masalah yang muncul dalam program.

Apa itu React hooks?


React hooks memungkinkan, ketika bekerja dengan komponen fungsional, untuk menggunakan analog dari keadaan komponen berdasarkan kelas dan analog dari metode siklus hidup mereka. Kait muncul di Bereaksi 16.8.

Di antara kekuatan utama kait adalah sebagai berikut:

  • Kemampuan untuk menggunakan keadaan dan menangani peristiwa siklus hidup komponen tanpa menggunakan komponen berbasis kelas.
  • Penyimpanan gabungan dari logika terkait di lokasi komponen yang sama dan bukannya pemisahan logika yang sama antara beberapa metode siklus hidup.
  • Mekanisme berbagi terlepas dari implementasi komponen (ini mirip dengan templat prop render ).

Perhatikan bahwa fitur-fitur hebat ini, pada kenyataannya, tidak melebihi Redux. React hooks dapat dan harus digunakan untuk melakukan pembaruan keadaan deterministik, tetapi ini selalu menjadi salah satu fitur Bereaksi, dan model keadaan deterministik Redux bergabung dengan baik dengan fitur ini. Inilah cara React mencapai determinisme dalam output elemen visual, dan inilah, tanpa berlebihan, salah satu motif penggerak untuk menciptakan React.

Jika Anda menggunakan alat seperti API reaksi-redux dengan kait , atau kait React useReducer , Anda akan menemukan bahwa tidak ada alasan untuk bertanya apa yang harus dipilih - kait atau Redux. Anda dapat menggunakan keduanya, menggabungkan dan menggabungkan teknologi ini.

Apa yang menggantikan kait?


Setelah API hook muncul, saya berhenti menggunakan teknologi berikut:


Apa yang tidak menggantikan kait?


Saya masih sering menggunakan teknologi berikut:

  • Redux - untuk semua alasan di atas.
  • Komponen dengan urutan lebih tinggi - untuk tujuan melakukan komposisi komponen jika saya harus menerapkan fungsionalitas ujung ke ujung yang dibagikan oleh semua atau beberapa komponen visual aplikasi. Fungsionalitas tersebut termasuk penyedia Redux, sistem tata letak halaman, sistem pendukung pengaturan aplikasi, alat otentikasi dan otorisasi, alat internasionalisasi aplikasi, dan sebagainya.
  • Pemisahan antara komponen wadah dan komponen yang memiliki representasi visual. Ini memungkinkan Anda untuk meningkatkan modularitas dan testabilitas aplikasi, lebih baik memisahkan efek dan logika murni.

Kapan harus menggunakan kait?


Tidak perlu berusaha untuk menggunakan Redux di setiap aplikasi dan di setiap komponen. Jika proyek Anda terdiri dari satu komponen visual, jika tidak menyimpan data dan tidak memuat data dari sana, jika operasi I / O asinkron tidak dilakukan di dalamnya, maka saya tidak dapat menemukan alasan yang layak untuk mempersulit proyek ini dengan menggunakan Redux di dalamnya.

Hal yang sama dapat dikatakan tentang komponen yang memiliki fitur berikut:

  • Mereka tidak menggunakan sumber daya jaringan.
  • Mereka tidak menyimpan data dalam keadaan dan tidak memuatnya dari sana.
  • Mereka tidak berbagi negara dengan komponen lain yang bukan keturunan mereka.
  • Mereka tidak memiliki keadaan tertentu sendiri, digunakan untuk penyimpanan data jangka pendek.

Anda mungkin memiliki alasan kuat untuk menggunakan model status komponen Bereaksi standar dalam situasi tertentu. Dalam situasi seperti ini, Bereaksi kait akan melakukan pekerjaan Anda dengan baik. Misalnya, formulir yang dijelaskan di bawah ini menggunakan status lokal komponen menggunakan hook React useState .

 import React, { useState } from 'react'; import t from 'prop-types'; import TextField, { Input } from '@material/react-text-field'; const noop = () => {}; const Holder = ({  itemPrice = 175,  name = '',  email = '',  id = '',  removeHolder = noop,  showRemoveButton = false, }) => {  const [nameInput, setName] = useState(name);  const [emailInput, setEmail] = useState(email); const setter = set => e => {    const { target } = e;    const { value } = target;    set(value);  }; return (    <div className="row">      <div className="holder">        <div className="holder-name">          <TextField label="Name">            <Input value={nameInput} onChange={setter(setName)} required />          </TextField>        </div>        <div className="holder-email">          <TextField label="Email">            <Input              value={emailInput}              onChange={setter(setEmail)}              type="email"              required            />          </TextField>        </div>        {showRemoveButton && (          <button            className="remove-holder"            aria-label="Remove membership"            onClick={e => {              e.preventDefault();              removeHolder(id);            }}          >            ×          </button>        )}      </div>      <div className="line-item-price">${itemPrice}</div>      <style jsx>{cssHere}</style>    </div>  ); }; Holder.propTypes = {  name: t.string,  email: t.string,  itemPrice: t.number,  id: t.string,  removeHolder: t.func,  showRemoveButton: t.bool, }; export default Holder; 

Di sini useState digunakan untuk mengontrol keadaan singkat yang digunakan dari bidang input name dan email :

 const [nameInput, setName] = useState(name); const [emailInput, setEmail] = useState(email); 

Anda mungkin memperhatikan bahwa masih ada pembuat tindakan removeHolder masuk ke properti dari Redux. Seperti yang telah disebutkan, kombinasi dan kombinasi teknologi sepenuhnya normal.

Menggunakan status komponen lokal untuk menyelesaikan masalah seperti itu selalu tampak bagus, tetapi sebelum React hooks, saya ingin menyimpan data komponen dalam penyimpanan Redux dan mendapatkan status dari properti.

Sebelumnya, bekerja dengan keadaan komponen yang terlibat menggunakan komponen berbasis kelas, menulis data awal ke negara menggunakan mekanisme untuk mendeklarasikan properti kelas (atau dalam konstruktor kelas), dan sebagainya. Akibatnya, ternyata untuk menghindari penggunaan Redux, komponen harus terlalu rumit. Redux juga berbicara mendukung keberadaan alat yang mudah digunakan untuk mengelola keadaan formulir menggunakan Redux. Akibatnya, sebelumnya, saya tidak akan khawatir bahwa keadaan sementara formulir disimpan di tempat yang sama dengan data dengan masa pakai yang lebih lama.

Karena saya sudah menggunakan Redux dalam semua aplikasi saya yang kurang lebih kompleks, pilihan teknologi untuk menyimpan keadaan komponen komponen tidak membuat saya banyak berpikir. Saya baru saja menggunakan Redux di hampir semua kasus.

Dalam kondisi modern, membuat pilihan juga mudah: bekerja dengan keadaan komponen diatur menggunakan mekanisme Bereaksi standar, dan mengelola keadaan aplikasi menggunakan Redux.

Kapan harus menggunakan Redux?


Pertanyaan umum lain mengenai manajemen negara adalah: “Apakah saya harus meletakkan semuanya dalam repositori Redux? Jika saya tidak melakukannya, apakah itu akan melanggar kemampuan untuk men-debug aplikasi menggunakan mekanisme TTD? "

Tidak perlu untuk meng-host semuanya di repositori Redux. Faktanya adalah bahwa aplikasi menggunakan banyak data sementara yang terlalu tersebar di sekitarnya untuk memberikan beberapa informasi yang, direkam dalam log atau digunakan selama debugging, dapat memberikan pengembang bantuan yang signifikan dalam menemukan masalah. Mungkin Anda, kecuali jika Anda menulis aplikasi editor real-time, Anda tidak perlu menulis ke negara setiap gerakan mouse atau setiap keystroke. Ketika Anda meletakkan sesuatu dalam status Redux, Anda menambahkan tingkat abstraksi tambahan ke aplikasi, serta tingkat kerumitan tambahan yang menyertainya.

Dengan kata lain, Anda dapat menggunakan Redux dengan aman, tetapi harus ada alasan untuk ini. Penggunaan fitur Redux dalam komponen dapat dibenarkan jika komponennya berbeda dalam fitur berikut:

  • Mereka menggunakan I / O. Misalnya, mereka bekerja dengan jaringan atau dengan perangkat tertentu.
  • Mereka menyimpan data ke atau memuat data dari itu.
  • Mereka bekerja dengan negara mereka dalam hubungannya dengan komponen-komponen yang bukan keturunan mereka.
  • Mereka berurusan dengan logika bisnis yang digunakan bagian lain dari aplikasi, - mereka memproses data yang digunakan di bagian lain aplikasi.

Berikut adalah contoh lain yang diambil dari aplikasi TDDDay :

 import React from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { compose } from 'ramda'; import page from '../../hocs/page.js'; import Purchase from './purchase-component.js'; import { addHolder, removeHolder, getHolders } from './purchase-reducer.js'; const PurchasePage = () => {  //      // mapStateToProps  mapDispatchToProps  const dispatch = useDispatch();  const holders = useSelector(getHolders); const props = {    //           //    dispatch.    addHolder: compose(      dispatch,      addHolder    ),    removeHolder: compose(      dispatch,      removeHolder    ),    holders,  }; return <Purchase {...props} />; }; // `page` -    ,    //        . export default page(PurchasePage); 

Dokumen ini tidak berurusan dengan DOM. Ini adalah komponen presentasi. Terhubung ke Redux menggunakan API reaksi-redux dengan dukungan hook .

Redux digunakan di sini karena kami membutuhkan data yang ditangani oleh formulir ini untuk digunakan di bagian lain dari antarmuka pengguna. Dan setelah operasi pembelian selesai, kita perlu menyimpan informasi yang relevan dalam database.

Fragmen status yang digunakan oleh kode ini digunakan oleh berbagai komponen, tidak diproses hanya oleh satu komponen. Ini bukan data, hanya ada waktu singkat. Data ini dapat dianggap permanen, dapat digunakan pada berbagai layar aplikasi dan dalam beberapa sesi. Semua ini adalah skenario di mana keadaan komponen untuk menyimpan data tidak dapat diterapkan. Benar, ini masih mungkin, tetapi hanya jika pembuat aplikasi menulis, berdasarkan React API, perpustakaannya sendiri untuk mengelola keadaan. Ini jauh lebih sulit dilakukan daripada hanya menggunakan Redux.

React Suspense API, di masa depan, mungkin berguna ketika menyimpan data dalam keadaan dan memuatnya. Kita perlu menunggu rilisnya dan melihat apakah ia dapat mengganti templat untuk menyimpan dan memuat data Redux. Redux memungkinkan kita untuk dengan jelas memisahkan efek samping dari sisa komponen logika, sementara kita tidak perlu bekerja dengan layanan I / O dengan cara khusus. (Alasan saya lebih suka pustaka redux-saga ke middleware redux-thunk adalah efek isolasi). Untuk bersaing dengan Redux dalam skenario ini, React API perlu memberikan efek isolasi.

Redux adalah arsitektur


Redux jauh lebih (dan sering jauh lebih sedikit) daripada perpustakaan manajemen negara. Ini juga merupakan bagian dari arsitektur Flux , yang jauh lebih ketat mendefinisikan bagaimana perubahan negara diimplementasikan. Baca lebih lanjut tentang arsitektur Redux di sini .

Saya sering menggunakan reduksi yang dibuat dalam gaya Redux dalam kasus-kasus ketika saya perlu mempertahankan keadaan kompleks komponen, tetapi tidak perlu menggunakan perpustakaan Redux. Selain itu, saya menggunakan tindakan yang dibuat dalam semangat Redux (dan bahkan alat Redux seperti Autodux dan redux -saga ) untuk mengirim tindakan dalam aplikasi Node.js. Namun, saya bahkan tidak mengimpor Redux ke aplikasi semacam itu.

Proyek Redux selalu lebih merupakan arsitektur dan seperangkat perjanjian sukarela daripada perpustakaan. Bahkan, implementasi dasar Redux dapat ditata secara harfiah dalam beberapa lusin baris kode.

Ini akan menjadi berita baik bagi mereka yang ingin menggunakan komponen lokal dengan kait lebih sering dan tidak mengikat semuanya ke Redux.

Bereaksi mendukung hook useReducer , yang dapat bekerja dengan reduksi gaya Redux. Ini bagus untuk mengimplementasikan logika non-sepele bekerja dengan negara, untuk bekerja dengan fragmen negara yang tergantung, dan sebagainya. Jika Anda menemukan masalah yang cocok untuk kondisi sementara komponen individual, maka Anda dapat menggunakan arsitektur Redux untuk bekerja dengan kondisi ini, tetapi alih-alih menggunakan pustaka Redux, Anda bisa menggunakan hook useReducer untuk mengelola keadaan.

Jika nanti Anda perlu membuat penyimpanan data permanen yang sebelumnya hanya sementara disimpan, maka Anda akan siap 90% untuk perubahan seperti itu. Yang harus Anda lakukan adalah menghubungkan komponen ke repositori Redux dan menambahkan peredam yang sesuai di sana.

Tanya Jawab


Apakah determinisme rusak jika Redux tidak mengelola semua data aplikasi?


Tidak, tidak rusak. Bahkan, menggunakan Redux tidak membuat proyek menjadi deterministik. Tetapi perjanjian itu. Jika Anda ingin kondisi Redux Anda menjadi deterministik, gunakan fungsi murni . Hal yang sama berlaku untuk situasi di mana perlu bahwa keadaan sementara komponen lokal harus ditentukan.

▍ Haruskah pustaka Redux memainkan peran sebagai sumber tunggal data yang andal?


Prinsip satu sumber data yang dapat diandalkan tidak menunjukkan bahwa semua data yang termasuk dalam status aplikasi perlu disimpan di satu tempat. Arti dari prinsip ini adalah bahwa setiap fragmen negara seharusnya hanya memiliki satu sumber data yang dapat diandalkan. Akibatnya, kita dapat memiliki banyak fragmen negara, yang masing-masing memiliki sumber data andal sendiri.

Ini berarti bahwa pemrogram dapat memutuskan apa yang ditransfer ke Redux dan apa yang ditransfer ke keadaan komponen. Data penentuan negara juga dapat diambil dari sumber lain. Misalnya, dari API peramban yang memungkinkan Anda bekerja dengan informasi tentang alamat halaman yang Anda lihat.

Redux adalah alat yang hebat untuk mendukung satu sumber data yang dapat diandalkan untuk keadaan aplikasi. Tetapi jika keadaan komponen terletak dan digunakan secara eksklusif dalam komponen ini, maka, menurut definisi, keadaan ini sudah memiliki satu sumber data yang dapat diandalkan - keadaan komponen Bereaksi.

Jika Anda memasukkan beberapa data dalam kondisi Redux, Anda harus selalu membaca data ini dari kondisi Redux. Untuk semua yang ada di repositori Redux, repositori ini harus menjadi satu-satunya sumber data yang dapat diandalkan.

Menempatkan semuanya dalam kondisi Redux, jika perlu, adalah hal yang normal. Mungkin ini akan mempengaruhi kinerja jika Anda menggunakan fragmen status yang perlu sering diperbarui, atau jika Anda berbicara tentang menyimpan status komponen di mana fragmen keadaan dependen banyak digunakan. Anda tidak perlu khawatir tentang kinerja sampai ada masalah dengan kinerja. Tetapi jika Anda khawatir tentang masalah kinerja, cobalah kedua cara bekerja dengan negara dan mengevaluasi dampaknya terhadap kinerja. Profil proyek Anda dan ingat model kinerja RAIL.

▍ Apakah saya perlu menggunakan fungsi koneksi dari react-redux, atau lebih baik menggunakan kait?


Itu tergantung banyak. Fungsi connect membuat komponen tingkat tinggi yang cocok untuk penggunaan berulang, dan kait dioptimalkan untuk integrasi dengan satu komponen.

Apakah saya perlu menghubungkan properti yang sama ke komponen yang berbeda? Jika demikian, gunakan connect . Kalau tidak, saya lebih suka memilih kait. Misalnya, bayangkan Anda memiliki komponen yang bertanggung jawab untuk mengotorisasi izin untuk tindakan pengguna:

 import { connect } from 'react-redux'; import RequiresPermission from './requires-permission-component'; import { userHasPermission } from '../../features/user-profile/user-profile-reducer'; import curry from 'lodash/fp/curry'; const requiresPermission = curry(  (NotPermittedComponent, { permission }, PermittedComponent) => {    const mapStateToProps = state => ({      NotPermittedComponent,      PermittedComponent,      isPermitted: userHasPermission(state, permission),    });    return connect(mapStateToProps)(RequiresPermission);  }, ); export default requiresPermission; 

Sekarang, jika seorang administrator bekerja secara intensif dengan aplikasi, semua tindakannya memerlukan izin khusus, Anda dapat membuat komponen tingkat tinggi yang menggabungkan semua izin ini dengan semua fungsi ujung ke ujung yang diperlukan:

 import NextError from 'next/error'; import compose from 'lodash/fp/compose'; import React from 'react'; import requiresPermission from '../requires-permission'; import withFeatures from '../with-features'; import withAuth from '../with-auth'; import withEnv from '../with-env'; import withLoader from '../with-loader'; import withLayout from '../with-layout'; export default compose(  withEnv,  withAuth,  withLoader,  withLayout(),  withFeatures,  requiresPermission(() => <NextError statusCode={404} />, {    permission: 'admin',  }), ); 

Berikut cara menggunakannya:

 import compose from 'lodash/fp/compose'; import adminPage from '../HOCs/admin-page'; import AdminIndex from '../features/admin-index/admin-index-component.js'; export default adminPage(AdminIndex); 

API komponen tingkat tinggi nyaman untuk tugas ini. Ini memungkinkan Anda untuk menyelesaikannya dengan lebih ringkas, menggunakan lebih sedikit kode daripada menggunakan kait. Tetapi untuk menggunakan fungsi connect , Anda harus ingat bahwa dibutuhkan mapStateToProps sebagai argumen pertama, dan mapStateToProps sebagai argumen kedua. Kita tidak boleh lupa bahwa fungsi ini dapat mengambil fungsi atau objek literal. Anda perlu tahu bagaimana perbedaan penggunaan connect , dan bahwa ini adalah fungsi kari, tetapi karinya tidak dilakukan secara otomatis.

Dengan kata lain, saya dapat mengatakan bahwa saya percaya bahwa selama pengembangan connect banyak pekerjaan dilakukan ke arah keringkasan kode, tetapi kode yang dihasilkan tidak terlalu mudah dibaca, juga tidak terlalu nyaman. Jika saya tidak perlu bekerja dengan beberapa komponen, maka saya ingin memilih API connect tidak nyaman dengan API pengait yang jauh lebih nyaman, bahkan mengingat hal ini akan mengarah pada peningkatan jumlah kode.

▍ Jika singleton dianggap sebagai anti-pola dan Redux adalah singleton, apakah ini berarti bahwa Redux adalah anti-pola?


Tidak, tidak. Menggunakan singleton dalam kode mengisyaratkan kualitas kode ini yang meragukan, yang menunjukkan keberadaan keadaan yang dapat diubah bersama di dalamnya. Ini adalah pola anti nyata. Redux, di sisi lain, mencegah mutasi status bersama melalui enkapsulasi (Anda tidak boleh mengubah status aplikasi secara langsung, di luar reduksi; Redux memecahkan masalah mengubah keadaan) dan dengan mengirim pesan (hanya objek acara yang dikirim yang dapat menyebabkan perubahan status).

Ringkasan


Apakah Redux mengganti React hooks? Kait memang bagus, tetapi mereka tidak menggantikan Redux.

Kami berharap materi ini akan membantu Anda dalam memilih model manajemen negara bagian untuk proyek Bereaksi Anda.

Pembaca yang budiman! Pernahkah Anda mengalami situasi di mana React hooks dapat menggantikan Redux?

Source: https://habr.com/ru/post/id464293/


All Articles