
Dan Abramov je 2015. napisao članak Presentacijske i kontejnerske komponente, koji su neki koji su reagirali novopridošli pogrešno protumačeni kao zapovijedi. U stvari, i sam sam slučajno naletio na članak i mnoge druge koji ponavljaju njegova učenja i pomislio sam, ovo mora biti najbolji način za razdvajanje briga među komponentama .
Ali, i sam Dan Abramov kasnije se obratio zajednici zbog držanja dizajnerskih obrazaca koje je iznio.

Radeći s Reactom već više od godinu dana, nabasao sam na vlastite uzorke dizajna i ovdje ću ih pokušati formalizirati. Shvatite ove ideje s rezervom, to su samo moja vlastita zapažanja koja sam smatrao konstruktivnima.
Bijeg od dihotomije
Komponente su već dugo klasificirane kao pametne ili glupe, spremničke ili prezentacijske, sa statusom države ili bez državljanstva, čiste ili nečiste. Postoji puno terminologije, ali sve one znače približno isto. Pametne komponente znaju povezati vašu aplikaciju, a glupe komponente samo uzimaju podatke kako bi ih predstavile krajnjem korisniku. Ovo je korisna razlika, ali zapravo nije kako razmišljam dok dizajniram komponente.
Problem s načinom razmišljanja Kontejner vs prezentacijski jest taj što se previše trudi definirati odgovornosti komponenata u smislu stanja, logike i drugih aspekata unutarnjeg rada komponente.
Dizajniranju komponenata bolje je pristupiti odgađanjem detalja implementacije i razmišljanjem u smislu sučelja komponenata . Posebno je važno razmisliti o tome kakve prilagodbe komponenta treba dopustiti i kakve implicitne i eksplicitne ovisnosti komponenta treba sadržavati.
Predstavljamo trihotomiju
Trihotomija? Je li to uopće riječ? Ne znam, ali shvaćate. Zamišljam da React komponente padaju u jednu od tri kante.
Univerzalne komponente
To su komponente koje se mogu koristiti više puta u bilo kojoj aplikaciji .
Ove komponente:
- Trebao bi se ponovno koristiti
- Trebao bi biti vrlo prilagodljiv
- Ne trebaju biti svjesni koda specifičnog za aplikaciju, uključujući modele, trgovine, usluge itd.
- Treba smanjiti ovisnosti o bibliotekama treće strane
- Rijetko se treba koristiti izravno u vašoj aplikaciji
- Treba koristiti kao gradivne blokove za globalne komponente
- Može završiti sufiksom "Base" (npr. ButtonBase, ImageBase)
To su temeljne komponente koje su agnostičke za primjenu i ne moraju se nužno koristiti izravno u komponentama Viewa jer su često previše prilagodljive. Njihova upotreba izravno u komponentama vašeg pregleda značilo bi puno kopiranja i lijepljenja iste ploče kotla. Također biste riskirali da programeri zloupotrijebe vrlo prilagodljivu prirodu komponenata na načine koji stvaraju nedosljedno iskustvo u vašoj aplikaciji.
Globalne komponente
To su komponente koje se mogu koristiti više puta u jednoj aplikaciji .
Ove komponente:
- Trebao bi se ponovno koristiti
- Trebao bi biti minimalno prilagodljiv
- Može koristiti kod specifičan za aplikaciju
- Treba implementirati univerzalne komponente , ograničavajući njihovu prilagodljivost
- Trebalo bi se koristiti kao gradivni blok za komponente View
- Često povezuju jedan s jednim s primjercima modela (npr. DogListItem, CatCard)
Te se komponente mogu ponovno koristiti u vašoj aplikaciji, ali ih nije lako prenijeti u druge programe jer ovise o logici aplikacije. To su gradivni elementi za View komponente i ostale globalne komponente.
Trebali bi biti minimalno prilagodljivi kako bi se osigurala dosljednost vaše aplikacije. Aplikacije ne bi trebale imati trideset različitih varijacija gumba, već bi trebale imati pregršt različitih varijacija gumba. To bi se trebalo provesti uzimanjem visoko prilagodljive komponente Universal ButtonBase i uklapanjem u nju stilova i funkcionalnosti u obliku komponente Globalni gumb. Globalne komponente često imaju drugi oblik kao prikazi podataka o modelu domene.
Pogledajte komponente
To su komponente koje se koriste samo jednom u vašoj aplikaciji .
Ove komponente:
- Trebao ne biti zabrinuti ponovne uporabe
- Vjerojatno će upravljati državom
- Primajte minimalne rekvizite
- Trebali bi povezati globalne komponente (i možda univerzalne komponente)
- Često rješavaju rute aplikacija
- Često održavaju namjenski zacrtani prikaz nekretnina
- Često imaju velik broj ovisnosti
- Trebali bi biti blokovi za vašu aplikaciju
Ovo su komponente najviše razine vaše aplikacije koje lijepe komponente za višekratnu upotrebu, pa čak i druge poglede. To će često biti komponente koje rješavaju rute i mogu se prikazati u obliku komponenata na razini stranice. Oni su teški u stanju i lagani u rekvizitima. To su ono što bi Dan Abramov smatrao komponentama spremnika.
Gumb Promise
Pogledajmo univerzalne i globalne implementacije gumba za obećanje i vidjet ćemo kako se uspoređuju. Gumb za obećanje ponaša se poput običnog gumba, osim ako rukovatelj onClick ne vrati obećanje. U slučaju vraćenog obećanja, gumb može uvjetno prikazati sadržaj na temelju stanja obećanja.
Primijetite kako nam PromiseButtonBase omogućuje kontrolu onoga što ćemo prikazati u bilo kojem trenutku životnog ciklusa obećanja, ali PromiseButton se peče u teal PulseLoaderu tijekom stanja na čekanju. Sad kad god koristimo PromiseButton, zajamčena nam je animacija učitavanja teal-a i ne moramo brinuti o dupliciranju tog koda ili pružanju nedosljednog iskustva učitavanja uključivanjem višestrukih animacija učitavanja više boja u našoj aplikaciji. PromiseButtonBase je prilagodljiv, ali PromiseButton je restriktivan.
Struktura direktorija
Sljedeće ilustrira kako bismo mogli organizirati komponente slijedeći ovaj obrazac.
App/ App.js Views/ DogListView/ Global/ Models/ Dog/ DogListItem/ Image/ PromiseButton/ Universal/ ImageBase/ PromiseButtonBase/
Ovisnosti o komponentama
Ispod ilustrira kako gornje komponente ovise jedna o drugoj.
/* App.js */ import { DogListView } from './Views' /* DogListView.js */ import { DogListItem } from 'App/Global/Models/Dog' /* DogListItem.js */ import Image from '../../Image', import PromiseButton from '../../PromiseButton' /* Image.js */ import { ImageBase } from 'Universal' /* PromiseButton.js */ import { PromiseButtonBase } from 'Universal'
Naša komponenta View ovisi o Globalnoj komponenti, a naše Globalne komponente ovise o ostalim Globalnim komponentama, kao i o Universal komponentama. Taj će tok ovisnosti biti prilično čest. Primijetite i upotrebu apsolutnog i relativnog uvoza. Lijepo je koristiti relativni uvoz kada uvlačite ovisnosti koje se nalaze unutar istog modula. Također je lijepo koristiti apsolutni uvoz prilikom uvlačenja ovisnosti između modula ili kada je struktura vašeg direktorija duboko ugniježđena ili se često mijenja.
Problem s modelom Container vs Presentational je u tome što se previše trudi definirati odgovornosti komponenata u smislu unutarnjeg rada komponenata. Ključno je oduzeti pogled na dizajn komponenata u smislu sučelja komponenata . Ono što je manje važno je implementacija koja omogućuje komponenti da ispuni svoj ugovor. Važno je razmisliti o tome kakve prilagodbe komponenta treba dopustiti i kakve implicitne i eksplicitne ovisnosti komponenta treba sadržavati.
Ako su vam ove misli korisne i željeli biste vidjeti više mojih ideja, slobodno pogledajte ovaj repo koji koristim za održavanje svojih misli i najboljih praksi za pisanje React / Redux aplikacija.