mata teras
Dalam artikel ini, saya akan meneroka bekas negara Redux dengan mendalam dengan membina enjin pemprosesan gaji. Aplikasi ini akan menyimpan gaji bersama -sama dengan semua tambahan seperti bonus dan pilihan saham. Saya akan menggunakan JavaScript Pure dan Typescript untuk pemeriksaan jenis untuk memastikan penyelesaiannya mudah. Oleh kerana Redux sangat mudah untuk diuji, saya juga akan menggunakan JEST untuk mengesahkan permohonan.
Dalam tutorial ini, saya menganggap anda mempunyai pemahaman tentang JavaScript, Node, dan NPM.
Pertama, anda boleh memulakan aplikasi ini dengan NPM:
npm init
Saya akan menggunakan TypeScript untuk melakukan pemeriksaan jenis dan menentukan model data. Ini membantu mengkonseptualisasikan apa yang kita cuba bina.
untuk memulakan dengan TypeScript:
npm i typescript --save-dev
"start": "tsc && node .bin/index.js"
Buat fail tsconfig.json dengan konfigurasi berikut:
{ "compilerOptions": { "strict": true, "lib": ["esnext", "dom"], "outDir": ".bin", "sourceMap": true }, "files": [ "src/index" ] }
Berikut adalah beberapa pilihan pengkompil yang munasabah yang akan memberi kita titik permulaan yang baik dan apakah setiap pilihan bermakna:
kerana saya akan menggunakan jest untuk ujian unit, saya akan terus menambahkannya:
npm init
TS-Jest Dependency menambah pemeriksaan jenis untuk rangka kerja ujian. Satu perkara yang perlu diperhatikan adalah untuk menambah konfigurasi jest dalam pakej.json:
npm i typescript --save-dev
Ini membolehkan rangka kerja ujian untuk mengambil fail TypeScript dan mengetahui cara menukarnya. Ciri yang bagus ialah anda boleh melakukan pemeriksaan jenis semasa menjalankan ujian unit. Untuk memastikan projek ini siap, buat folder __Tests__ yang mengandungi fail index.test.ts. Kemudian, pemeriksaan sanitasi dilakukan. Contohnya:
"start": "tsc && node .bin/index.js"
{ "compilerOptions": { "strict": true, "lib": ["esnext", "dom"], "outDir": ".bin", "sourceMap": true }, "files": [ "src/index" ] }
enjin paystop dalam operasi sebenar
jadi ini meninggalkan jenis operasi berikut:
npm i jest ts-jest @types/jest @types/node --save-dev
TypeScript
Sebagai contoh, masukkannya dalam src/index.ts:
"jest": { "preset": "ts-jest" }
Antara muka TypeScript ini harus dilakukan:
npm init
Bagi setiap harta, perhatikan bahawa TypeScript menggunakan kolon untuk menentukan jenis. Sebagai contoh,: nombor. Ini menentukan kontrak jenis dan menambah kebolehprediksi kepada pemeriksa jenis. Redux boleh dipertingkatkan menggunakan sistem jenis dengan pengisytiharan jenis eksplisit. Ini kerana bekas negara Redux dibina untuk tingkah laku yang boleh diramal.
Idea ini tidak gila atau radikal. Pembelajaran Redux Bab 1 (ahli Premium SitePoint sahaja) menerangkan ini dengan baik.
Apabila perubahan aplikasi, pemeriksaan taip menambah ramalan tambahan. Apabila aplikasi berkembang, teori jenis juga membantu memudahkan pembinaan semula segmen kod besar.
menggunakan enjin konseptualisasi jenis sekarang membantu membuat fungsi operasi berikut:
npm i typescript --save-dev
Perkara yang baik ialah jika anda cuba melakukan ProcessBasePay ('ABC'), pemeriksa jenis akan memberi amaran kepada anda. Memusnahkan kontrak jenis mengurangkan kebolehprediksi bekas negara. Saya menggunakan kontrak operasi tunggal seperti PayrollAction untuk menjadikan pemproses gaji lebih diramalkan. Ambil perhatian bahawa jumlahnya ditetapkan dalam objek Operasi melalui singkatan atribut ES6. Pendekatan yang lebih tradisional adalah jumlah: jumlah, yang lebih verbose. Fungsi anak panah, seperti () = & gt;
Contoh:
"start": "tsc && node .bin/index.js"
{ "compilerOptions": { "strict": true, "lib": ["esnext", "dom"], "outDir": ".bin", "sourceMap": true }, "files": [ "src/index" ] }
npm i jest ts-jest @types/jest @types/node --save-dev
Mulakan pernyataan suis pengurangan untuk mengendalikan kes penggunaan pertama:
"jest": { "preset": "ts-jest" }
it('is true', () => { expect(true).toBe(true); });
npm init
Oleh kerana jumlahnya adalah pilihan, pastikan ia mempunyai nilai lalai untuk mengurangkan kegagalan. Ini adalah kelebihan TypeScript, kerana pemeriksa jenis akan melihat perangkap ini dan memberi amaran kepada anda. Sistem jenis tahu fakta tertentu, jadi ia boleh membuat andaian yang munasabah. Katakan anda ingin berurusan dengan bonus:
npm i typescript --save-dev
Mod ini menjadikan reducer boleh dibaca kerana ia hanya mengekalkan keadaan. Anda mendapat jumlah operasi, hitung jumlah gaji, dan buat teks objek baru. Tidak ada yang berbeza ketika berurusan dengan pilihan saham:
"start": "tsc && node .bin/index.js"
Untuk memproses gaji pada hari gaji, ia memerlukan pemadaman bonus dan pembayaran balik. Kedua -dua atribut ini tidak disimpan di negeri ini dalam setiap gaji. Dan, tambahkan kemasukan ke sejarah gaji. Upah asas dan pilihan saham boleh disimpan di negeri ini kerana mereka tidak sering berubah. Dengan itu, ini adalah bagaimana Pay_day dikendalikan:
{ "compilerOptions": { "strict": true, "lib": ["esnext", "dom"], "outDir": ".bin", "sourceMap": true }, "files": [ "src/index" ] }
Dalam array seperti NewPayHistory, gunakan pengendali lanjutan, yang merupakan antonim untuk berehat. Tidak seperti harta benda dalam objek koleksi, ia memperluaskan projek. Sebagai contoh, [... payhistory]. Walaupun kedua -dua pengendali kelihatan sama, mereka tidak sama. Tonton dengan teliti, kerana ini mungkin muncul dalam soalan wawancara.
menggunakan pop () untuk payhistory tidak akan mengubah keadaan. Kenapa? Kerana Slice () mengembalikan array baru. Array dalam JavaScript disalin dengan rujukan. Menetapkan array ke pembolehubah baru tidak mengubah objek yang mendasari. Oleh itu, penjagaan mesti diambil semasa berurusan dengan jenis objek ini.
Kerana lastPayHistory mungkin tidak ditentukan, saya menggunakan nilai null lelaki miskin untuk memulakannya kepada sifar. Sila ambil perhatian bahawa (O && O.Property) || Mungkin ada cara yang lebih elegan untuk melakukan ini dalam versi masa depan JavaScript atau bahkan TypeScript.
Setiap pengurangan redux mesti menentukan cawangan lalai. Untuk memastikan bahawa Negeri tidak menjadi tidak jelas:
npm i jest ts-jest @types/jest @types/node --save-dev
Salah satu daripada banyak manfaat menulis fungsi tulen ialah mereka mudah diuji. Ujian unit adalah ujian di mana anda perlu mengharapkan tingkah laku yang boleh diramal, dan anda boleh mengautomasikan semua ujian sebagai sebahagian daripada binaan. Dalam __Tests __/index.test.ts, membatalkan ujian maya dan mengimport semua fungsi kepentingan:
"jest": { "preset": "ts-jest" }
Perhatikan bahawa semua fungsi ditetapkan untuk dieksport, jadi anda boleh mengimportnya. Untuk gaji asas, mulakan pengurangan enjin gaji dan uji:
it('is true', () => { expect(true).toBe(true); });
Redux menetapkan keadaan awal untuk tidak ditentukan. Oleh itu, adalah idea yang baik untuk memberikan nilai lalai dalam fungsi reducer. Bagaimana dengan pengendalian pembayaran balik?
npm i redux --save
Corak bonus pengendalian adalah sama seperti ini:
const BASE_PAY = 'BASE_PAY'; const REIMBURSEMENT = 'REIMBURSEMENT'; const BONUS = 'BONUS'; const STOCK_OPTIONS = 'STOCK_OPTIONS'; const PAY_DAY = 'PAY_DAY';
untuk pilihan saham:
interface PayrollAction { type: string; amount?: number; }
Perhatikan bahawa apabila stockoptions lebih besar daripada totalpay, totalpay mesti kekal tidak berubah. Oleh kerana syarikat hipotetikal ini beretika, ia tidak mahu mengambil wang dari pekerjanya. Jika anda menjalankan ujian ini, sila ambil perhatian bahawa TotalPay ditetapkan kepada -10, kerana stok akan ditolak. Inilah sebabnya kami menguji kod! Mari kita selesaikan tempat di mana jumlah gaji dikira:
npm init
Jika wang yang diperoleh oleh pekerja tidak mempunyai cukup wang untuk membeli saham syarikat, sila terus melangkau potongan. Juga, pastikan ia menetapkan semula stok ke sifar:
npm i typescript --save-dev
Pembetulan ini menentukan sama ada mereka mempunyai cukup wang dalam NewStockOptions. Dengan ini, ujian unit berlalu, kod itu adalah bunyi dan bermakna. Kami boleh menguji kes penggunaan positif di mana terdapat cukup wang untuk membuat potongan:
"start": "tsc && node .bin/index.js"
untuk hari paydays, gunakan pelbagai status untuk menguji dan pastikan transaksi satu kali tidak berterusan:
{ "compilerOptions": { "strict": true, "lib": ["esnext", "dom"], "outDir": ".bin", "sourceMap": true }, "files": [ "src/index" ] }
Perhatikan bagaimana saya menyesuaikan Oldstate untuk mengesahkan bonus dan menetapkan semula pembayaran balik kepada sifar.
Bagaimana dengan cawangan lalai dalam pengurangan?
npm i jest ts-jest @types/jest @types/node --save-dev
redux menetapkan jenis operasi seperti init_action pada mulanya. Kami hanya peduli sama ada pengurangan kami mempunyai beberapa set keadaan awal.
Pada ketika ini, anda mungkin mula tertanya -tanya jika Redux lebih banyak corak reka bentuk. Jika anda menjawab bahawa ia adalah corak dan perpustakaan ringan, anda betul. Dalam index.ts, import redux:
"jest": { "preset": "ts-jest" }
Contoh kod seterusnya boleh dibalut ini jika pernyataan. Ini adalah stopgap jadi ujian unit tidak bocor ke ujian integrasi:
it('is true', () => { expect(true).toBe(true); });
Saya tidak mengesyorkan melakukan ini dalam projek sebenar. Modul boleh diletakkan dalam fail berasingan untuk mengasingkan komponen. Ini menjadikannya lebih mudah dibaca dan tidak membocorkan masalah. Ujian unit juga mendapat manfaat daripada fakta bahawa modul berjalan secara bebas.
Gunakan PayrollEnginereducer untuk memulakan penyimpanan Redux:
npm i redux --save
setiap kedai.subscribe () mengembalikan fungsi berhenti berlangganan () berikutnya yang boleh digunakan untuk pembersihan. Ia berhenti melanggan panggilan balik apabila ia dijadualkan melalui storan. Di sini saya menggunakan Store.getState () untuk mengeluarkan keadaan semasa ke konsol.
Katakan pekerja memperoleh 300, mempunyai 50 pembayaran balik, 100 bonus, dan 15 untuk stok syarikat:
const BASE_PAY = 'BASE_PAY'; const REIMBURSEMENT = 'REIMBURSEMENT'; const BONUS = 'BONUS'; const STOCK_OPTIONS = 'STOCK_OPTIONS'; const PAY_DAY = 'PAY_DAY';
untuk menjadikannya lebih menyeronokkan, membuat 50 lagi pembayaran balik dan memproses gaji lain:
interface PayrollAction { type: string; amount?: number; }
Akhirnya, jalankan gaji lain dan berhenti berlangganan untuk penyimpanan redux:
interface PayStubState { basePay: number; reimbursement: number; bonus: number; stockOptions: number; totalPay: number; payHistory: Array<PayHistoryState>; } interface PayHistoryState { totalPay: number; totalCompensation: number; }
Hasil akhir adalah seperti berikut:
export const processBasePay = (amount: number): PayrollAction => ({type: BASE_PAY, amount}); export const processReimbursement = (amount: number): PayrollAction => ({type: REIMBURSEMENT, amount}); export const processBonus = (amount: number): PayrollAction => ({type: BONUS, amount}); export const processStockOptions = (amount: number): PayrollAction => ({type: STOCK_OPTIONS, amount}); export const processPayDay = (): PayrollAction => ({type: PAY_DAY});
Seperti yang ditunjukkan, Redux mengekalkan keadaan, mengubah keadaan dan memberitahu pelanggan dalam pakej kecil yang kemas. Fikirkan Redux sebagai mesin negara, yang merupakan sumber sebenar data negara. Semua ini mengamalkan amalan terbaik pengekodan, seperti paradigma fungsional yang baik.
Redux menyediakan penyelesaian mudah kepada masalah pengurusan negara yang kompleks. Ia bergantung kepada paradigma berfungsi untuk mengurangkan ketidakpastian. Kerana reducer adalah fungsi tulen, ujian unit sangat mudah. Saya memutuskan untuk menggunakan JEST, tetapi sebarang rangka kerja ujian yang menyokong dakwaan asas akan berfungsi.
TypeScript menggunakan teori jenis untuk menambah lapisan perlindungan tambahan. Campurkan pemeriksaan jenis dengan pengaturcaraan berfungsi dan anda mendapat kod kukuh yang hampir tidak pernah terganggu. Paling penting, TypeScript tidak mendapat cara bekerja semasa menambah nilai. Jika anda perasan, sebaik sahaja kontrak jenis disediakan, hampir tidak ada pengekodan tambahan. Pemeriksa jenis melakukan selebihnya. Seperti mana -mana alat yang baik, TypeScript mengotomatisasi disiplin pengekodan sementara masih tidak kelihatan. Typescript menyalak dengan kuat, tetapi ia menggigit ringan.
Jika anda ingin mencuba projek ini (saya harap anda melakukan ini), anda boleh mencari kod sumber untuk artikel ini di GitHub.
Atas ialah kandungan terperinci Menyelam jauh ke redux. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!