socialgekon.com
  • Tärkein
  • Tuotemerkin Suunnittelu
  • Projektinhallinta
  • Kaukosäätimen Nousu
  • Tietojenkäsittely Ja Tietokannat
Teknologia

Ylätason hallinta Redux-tilan hallinnan avulla: ClojureScript-opetusohjelma

Tervetuloa takaisin toiseen jännittävään erään ClojureScriptin löytäminen ! Tässä viestissä aion käsitellä seuraavaa suurta askelta vakavampaan ClojureScriptiin: valtionhallinta - tässä tapauksessa Reactin avulla.

Etupään ohjelmistojen avulla valtionhallinta on iso juttu. Laatikossa on pari tapaa käsitellä tilaa Reagoi :

  • Tilan pitäminen ylätasolla ja sen (tai tietyn tilan käsittelijän) välittäminen lapsikomponenteille.
  • Puhtauden heittäminen ulos ikkunasta ja globaalien muuttujien tai jonkin Lovecraftin riippuvuusinjektion muoto.

Yleisesti ottaen kumpikaan näistä ei ole hieno. Tilan pitäminen ylätasolla on melko yksinkertaista, mutta silloin on suuri määrä sovellustilan siirtämistä jokaiselle sitä tarvitsevalle komponentille.



Vertailun vuoksi, globaalien muuttujien (tai muiden valtion naiiviversioiden) saaminen voi johtaa vaikeasti jäljitettäviin samanaikaisuusongelmiin, mikä johtaa komponenttien päivittymättä odotetulla tavalla tai päinvastoin.

Joten miten tähän voidaan puuttua? Niille teistä, jotka tuntevat Reactin, olet ehkä kokeillut Reduxia, valtion kontti JavaScript sovelluksia. Olet ehkä löytänyt tämän omasta tahdostasi etsimällä rohkeasti hallittavaa järjestelmää valtion ylläpitämiseksi. Tai olet ehkä vain törmännyt siihen lukiessasi JavaScriptiä ja muita verkkotyökaluja.

Huolimatta siitä, miten ihmiset päätyvät katsomaan Reduxia, kokemukseni mukaan heillä on yleensä kaksi ajatusta:

  • 'Minusta tuntuu, että minun on käytettävä tätä, koska kaikki sanovat, että minun on käytettävä sitä.'
  • 'En todellakaan ymmärrä täysin, miksi tämä on parempi.'

Yleisesti ottaen Redux tarjoaa abstraktion, jonka avulla valtionhallinta mahtuu reaktiivinen Reactin luonne. Lataamalla kaikki tilat Reduxin kaltaiselle järjestelmälle, säilytät puhtaus React. Näin päädyt paljon vähemmän päänsärkyyn ja yleensä sellaiseen, johon on paljon helpompi perustella.

Niille, jotka ovat uusia Clojuressa

Vaikka tämä ei välttämättä auta sinua oppimaan ClojureScriptiä kokonaan tyhjästä, tässä aion ainakin kertoa joitain Clojure [Script] -tilan peruskäsitteitä. Voit ohittaa nämä osat, jos olet jo kokenut clojurilainen !

Muista yksi Clojure-perusteista, jotka koskevat myös ClojureScript: Oletuksena tiedot ovat muuttumattomia . Tämä on erinomaista kehittää ja taata, että aikataulussa N luomasi on edelleen sama ajanjaksolla> N. ClojureScript tarjoaa meille myös kätevän tavan saada muutettava tila tarvittaessa, atom konsepti.

atom ClojureScript on hyvin samanlainen kuin AtomicReference Java: Se tarjoaa uuden objektin, joka lukitsee sen sisällön samanaikaisuustakeilla. Aivan kuten Java-ohjelmassa, voit sijoittaa mihin tahansa haluamaasi tähän esineeseen - siitä lähtien atomi on atomi viite mihin tahansa.

Kun sinulla on atom, voit asettaa siihen uuden arvon käyttämällä reset! toiminto (huomioi funktiossa ! - Clojure-kielellä tätä käytetään usein osoittamaan, että operaatio on tilallinen tai epäpuhdas).

Huomaa myös, että toisin kuin Java, Clojure ei välitä siitä, mitä laitat atom Se voi olla merkkijono, luettelo tai objekti. Dynaaminen kirjoittaminen, kulta!

(def my-mutable-map (atom {})) ; recall that {} means an empty map in Clojure (println @my-mutable-map) ; You 'dereference' an atom using @ ; -> this prints {} (reset! my-mutable-map {:hello 'there'}) ; atomically set the atom (reset! my-mutable-map 'hello, there!') ; don't forget Clojure is dynamic :)

Reagenssi laajentaa tätä atomin käsitettä omilla atom. (Jos et ole perehtynyt Reagentiin, tarkista viesti ennen tätä .) Tämä toimii samalla tavalla kuin ClojureScript atom, paitsi että se laukaisee myös renderöintitapahtumat Reagentissa, aivan kuten Reactin sisäänrakennettu valtion myymälä.

Esimerkki:

(ns example (:require [reagent.core :refer [atom]])) ; in this module, atom now refers ; to reagent's atom. (def my-atom (atom 'world!')) (defn component [] [:div [:span 'Hello, ' @my-atom] [:input {:type 'button' :value 'Press Me!' :on-click #(reset! My-atom 'there!')}]])

Tämä näyttää yksittäisen, joka sisältää sanomalla 'Hei maailma!' ja painike, kuten voit odottaa. Painikkeen painaminen mutatoi atomisesti my-atom sisältää 'there!'. Se käynnistää komponentin uudelleensuunnittelun, minkä seurauksena alue sanoo “Hei, siellä! sen sijaan.

Katsaus Reduxin ja Reagentin käsittelemään valtionhallintaan.

Tämä näyttää riittävän yksinkertaiselta paikalliselle komponenttitason mutaatiolle, mutta entä jos meillä on monimutkaisempi sovellus, jolla on useita abstraktiotasoja? Tai jos meidän on jaettava yhteinen tila useiden alikomponenttien ja niiden alikomponenttien välillä?

Monimutkaisempi esimerkki

Tutkitaan tätä esimerkin avulla. Täällä toteutamme karkean kirjautumissivun:

(ns unearthing-clojurescript.login (:require [reagent.core :as reagent :refer [atom]])) ;; -- STATE -- (def username (atom nil)) (def password (atom nil)) ;; -- VIEW -- (defn component [on-login] [:div [:b 'Username'] [:input {:type 'text' :value @username :on-change #(reset! username (-> % .-target .-value))}] [:b 'Password'] [:input {:type 'password' :value @password :on-change #(reset! password (-> % .-target .-value))}] [:input {:type 'button' :value 'Login!' :on-click #(on-login @username @password)}]])

Isännöimme sitten tätä kirjautumiskomponenttia pääosassa app.cljs, kuten näin:

(ns unearthing-clojurescript.app (:require [unearthing-clojurescript.login :as login])) ;; -- STATE (def token (atom nil)) ;; -- LOGIC -- (defn- do-login-io [username password] (let [t (complicated-io-login-operation username password)] (reset! token t))) ;; -- VIEW -- (defn component [] [:div [login/component do-login-io]])

Odotettu työnkulku on siis:

  1. Odotamme, että käyttäjä antaa käyttäjätunnuksensa ja salasanansa ja paina Lähetä.
  2. Tämä laukaisee do-login-io toiminto pääkomponentissa.
  3. do-login-io function tekee joitain I / O-toimintoja (kuten kirjautuu palvelimelle ja noutaa tunnuksen).

Jos tämä toiminto estää, olemme jo kasassa ongelmia, koska sovelluksemme on jumissa - jos se ei ole, meillä on asynkronia, josta huolehtia!

Lisäksi meidän on nyt toimitettava tämä tunnus kaikille alikomponenteillemme, jotka haluavat tehdä kyselyitä palvelimellemme. Koodin uudelleenkäsittely sai juuri paljon vaikeampaa!

Lopuksi, komponenttimme ei ole enää puhtaasti reaktiivinen —Se on nyt osallisena muun sovelluksen tilan hallinnassa, käynnistää I / O: n ja on yleensä vähän haittaa.

ClojureScript-opetusohjelma: Kirjoita Redux

Redux on taikasauva, joka saa kaikki valtiolliset unelmasi toteutumaan. Oikein toteutettuna se tarjoaa tilaa jakavan abstraktin, joka on turvallista, nopeaa ja helppokäyttöistä.

Reduxin sisäinen toiminta (ja sen takana oleva teoria) jäävät jonkin verran tämän artikkelin ulkopuolelle. Sen sijaan aion sukeltaa toimivaan esimerkkiin ClojureScriptin kanssa, jonka pitäisi toivottavasti mennä jonkin verran osoittamaan, mihin se kykenee!

Yhteyksissämme Redux on yksi monista saatavilla olevista ClojureScript-kirjastoista; tämä soitti kehys uudelleen . Se tarjoaa Clojure-ified-kääreen Reduxin ympärille, mikä (mielestäni) tekee siitä täydellisen ilon käyttää.

Perusteet

Redux nostaa sovellustilan, jolloin komponentit ovat kevyet. Reduxified-komponentin täytyy vain miettiä:

  • Miltä se näyttää
  • Mitä tietoja se kuluttaa
  • Mitä tapahtumia se laukaisee

Loput hoidetaan kulissien takana.

Korostaaksemme tätä asiaa, tehkäämme uudelleen yllä oleva kirjautumissivumme.

Tietokanta

Ensimmäiset asiat ensin: Meidän on päätettävä, miltä sovellusmallimme näyttää. Teemme tämän määrittelemällä muoto tiedoistamme, datasta, joka on käytettävissä koko sovelluksessa.

Hyvä nyrkkisääntö on, että jos tietoja on käytettävä useissa Redux-komponenteissa tai niiden on oltava pitkäikäisiä (kuten tunnuksemme tulee olemaan), ne tulisi tallentaa tietokantaan. Sitä vastoin, jos tiedot ovat komponentin paikallisia (kuten käyttäjätunnus- ja salasanakenttämme), niiden tulisi elää paikallisena komponenttitilana eikä niitä pitäisi tallentaa tietokantaan.

Luodaan tietokannan kattolevy ja kerrotaan tunnuksemme:

(ns unearthing-clojurescript.state.db (:require [cljs.spec.alpha :as s] [re-frame.core :as re-frame])) (s/def ::token string?) (s/def ::db (s/keys :opt-un [::token])) (def default-db {:token nil})

Tässä on muutama mielenkiintoinen asia, joka kannattaa huomioida:

  • Käytämme Clojure's spec kirjasto että kuvaa miten tietojemme pitäisi näyttää. Tämä sopii erityisen hyvin dynaamiseen kieleen, kuten Clojure [Script].
  • Tässä esimerkissä seuraamme vain yleistä tunnusta, joka edustaa käyttäjää, kun hän on kirjautunut sisään. Tämä tunnus on yksinkertainen merkkijono.
  • Ennen kuin käyttäjä kirjautuu sisään, meillä ei kuitenkaan ole tunnusta. Tätä edustaa :opt-un avainsana, joka tarkoittaa 'valinnainen, pätemätön'. (Clojuressa tavallinen avainsana olisi jotain :cat, kun taas hyväksytty avainsana voi olla jotain :animal/cat. Karsinta tapahtuu yleensä moduulitasolla - tämä estää eri moduulien avainsanoja ryöstämästä toisiaan .)
  • Lopuksi määritämme tietokannan oletustilan, mikä se alustetaan.

Milloin tahansa, meidän on oltava varmoja siitä, että tietokantaamme kuuluvat tiedot vastaavat täällä olevia tietoja.

Tilaukset

Nyt kun olemme kuvanneet tietomalliamme, meidän on pohdittava miten näkymä näyttää nämä tiedot. Olemme jo kuvanneet miltä näkökulmamme näyttää Redux-komponentissamme - nyt meidän on yksinkertaisesti yhdistettävä näkymä tietokantaan.

Reduxillä emme pääse suoraan tietokantaamme - tämä voi johtaa elinkaareen ja samanaikaisuuteen. Sen sijaan rekisteröimme suhteemme tietokannan osaan kautta tilauksia .

Tilaus kertoo uudelleenkehykselle (ja Reagentille), että olemme riippuvaisia ​​tietokannan osasta, ja jos kyseistä osaa muutetaan, Redux-komponenttimme tulisi tehdä uudelleen.

Tilaukset on helppo määritellä:

(ns unearthing-clojurescript.state.subs (:require [re-frame.core :refer [reg-sub]])) (reg-sub :token ; <- the name of the subscription (fn [{:keys [token] :as db} _] ; first argument is the database, second argument is any token)) ; args passed to the subscribe function (not used here)

Täällä rekisteröimme yhden tilauksen - itse tunnukseen. Tilaus on yksinkertaisesti tilauksen nimi ja toiminto, joka poimii kyseisen kohteen tietokannasta. Voimme tehdä mitä haluamme tuohon arvoon ja mutatoida näkymän niin paljon kuin haluamme täällä; tässä tapauksessa kuitenkin yksinkertaisesti poimimme tunnuksen tietokannasta ja palautamme sen.

On paljon, paljon Enemmän voit tehdä tilauksilla - esimerkiksi määrittelemällä näkymiä tietokannan alaosioista uudelleenhahmonnuksen tiukentamiseksi - mutta pidämme sen nyt yksinkertaisena!

Tapahtumat

Meillä on tietokanta ja näkemyksemme tietokantaan. Nyt meidän on käynnistettävä joitain tapahtumia! Tässä esimerkissä meillä on kahdenlaisia ​​tapahtumia:

  • Puhdas tapahtuma (jolla ei sivuvaikutus) uuden tunnuksen kirjoittaminen tietokantaan.
  • I / O-tapahtuma ( ottaa sivuvaikutus) menemällä ulos ja pyytämällä tunnustamme asiakkaan kanssa.

Aloitamme helpommasta. Uudelleen kehys tarjoaa jopa toiminnon tarkalleen tällaiselle tapahtumalle:

(ns unearthing-clojurescript.state.events (:require [re-frame.core :refer [reg-event-db reg-event-fx reg-fx] :as rf] [unearthing-clojurescript.state.db :refer [default-db]])) ; our start up event that initialises the database. ; we'll trigger this in our core.cljs (reg-event-db :initialise-db (fn [_ _] default-db)) ; a simple event that places a token in the database (reg-event-db :store-login (fn [db [_ token]] (assoc db :token token)))

Jälleen, tässä on aika suoraviivaista - olemme määrittäneet kaksi tapahtumaa. Ensimmäinen on tietokannan alustaminen. (Katso, miten se jättää huomiotta molemmat argumentit? Alustamme tietokannan aina default-db! -Palvelumme avulla.) Toinen on tunnuksen tallentamiseen, kun olemme saaneet sen.

Huomaa, että kummallakaan näistä tapahtumista ei ole sivuvaikutuksia - ei ulkoisia puheluita, ei I / O: ta ollenkaan! Tämä on erittäin tärkeää pyhän Redux-prosessin pyhyyden säilyttämiseksi. Älä tee siitä epäpuhdasta, ettet haluaisi Reduxin vihaa.

Lopuksi tarvitsemme kirjautumistapahtumamme. Sijoitamme sen muiden alle:

(reg-event-fx :login (fn [{:keys [db]} [_ credentials]] {:request-token credentials})) (reg-fx :request-token (fn [{:keys [username password]}] (let [token (complicated-io-login-operation username password)] (rf/dispatch [:store-login token]))))

reg-event-fx funktio on pitkälti samanlainen kuin reg-event-db, vaikka siinä on joitain hienovaraisia ​​eroja.

  • Ensimmäinen argumentti ei ole enää vain itse tietokanta. Se sisältää lukuisia muita asioita, joita voit käyttää sovellustilan hallintaan.
  • Toinen argumentti muistuttaa paljon reg-event-db
  • Sen sijaan, että palauttaisimme vain uuden db, palautamme sen sijaan kartan, joka kuvaa kaikki vaikutukset ('fx'), joiden pitäisi tapahtua tälle tapahtumalle. Tässä tapauksessa kutsumme yksinkertaisesti :request-token vaikutus, joka on määritelty alla. Yksi muista kelvollisista vaikutuksista on :dispatch, joka yksinkertaisesti kutsuu toista tapahtumaa.

Kun vaikutuksemme on lähetetty, :request-token -efektiä kutsutaan, joka suorittaa pitkäaikaisen I / O-kirjautumistoimintomme. Kun tämä on valmis, se lähettää mielellään tuloksen takaisin tapahtumasilmukkaan, mikä täydentää jakson!

ClojureScript-opetusohjelma: lopullinen tulos

Niin! Olemme määrittäneet varastoinnin. Miltä komponentti näyttää nyt?

(ns unearthing-clojurescript.login (:require [reagent.core :as reagent :refer [atom]] [re-frame.core :as rf])) ;; -- STATE -- (def username (atom nil)) (def password (atom nil)) ;; -- VIEW -- (defn component [] [:div [:b 'Username'] [:input {:type 'text' :value @username :on-change #(reset! username (-> % .-target .-value))}] [:b 'Password'] [:input {:type 'password' :value @password :on-change #(reset! password (-> % .-target .-value))}] [:input {:type 'button' :value 'Login!' :on-click #(rf/dispatch [:login {:username @username :password @password]})}]])

Ja sovelluskomponenttimme:

(ns unearthing-clojurescript.app (:require [unearthing-clojurescript.login :as login])) ;; -- VIEW -- (defn component [] [:div [login/component]])

Ja lopuksi, tunnuksen käyttäminen jossakin etäkomponentissa on yhtä helppoa kuin:

(let [token @(rf/subscribe [:token])] ; ... )

Yhdistämällä kaikki yhteen:

Kuinka paikallinen tila ja globaali (Redux) tila toimivat kirjautumisesimerkissä.

Ei jalkoja, ei pakko.

Komponenttien irrottaminen Redux / Re-frame-tekniikalla tarkoittaa puhdasta tilan hallintaa

Reduxia käyttämällä (uudelleenkehyksen kautta) erotimme näkymäkomponentit onnistuneesti tilankäsittelyn sotkusta. Valtion vedenoton laajentaminen on nyt kakku!

Redux ClojureScriptissä todella On niin helppoa - sinulla ei ole tekosyitä olla kokeilematta sitä.

Jos olet valmis murtumaan, suosittelen kirjautumista ulos upeat uudelleenkehystetyt asiakirjat ja yksinkertainen toiminut esimerkkimme . Odotan lukevani kommenttisi tästä ClojureScript-opetusohjelmasta alla. Onnea!

Liittyvät: Tilahallinta kulmalla Firebasen avulla

Perustietojen ymmärtäminen

Mikä on Redux-tila?

Redux-tila viittaa yksittäiseen myymälään, jota Redux käyttää sovellustilan hallintaan. Tätä myymälää hallitsee yksinomaan Redux, eikä siihen pääse suoraan sovelluksesta.

Onko Redux-tapahtumien hankinta?

Ei, Redux on erillinen tekniikka mallista, joka tunnetaan nimellä tapahtumien hankinta. Redux sai innoituksensa toisesta tekniikasta nimeltä Flux.

Mikä on Redux-kontti?

Redux-säilö (tai yksinkertaisesti 'kontti') on React-komponentti, joka tilaa Redux-tilan ja saa päivityksiä, kun tilan osa muuttuu.

Onko Redux kehys?

Kyllä, Redux tarjoaa puitteet valtionhallinnalle verkkosovelluksessa.

Mikä on ClojureScript?

ClojureScript on Clojuren kääntäjä, joka kohdistuu JavaScriptiin. Sitä käytetään yleisesti web-sovellusten ja kirjastojen rakentamiseen Clojure-kieltä käyttäen.

Vaikutuspikselit - vakuuttavien suunnitteluperiaatteiden hajottaminen

Ux-Suunnittelu

Vaikutuspikselit - vakuuttavien suunnitteluperiaatteiden hajottaminen
Nvidia Shield - erilainen otos Android-pelikonsoleista

Nvidia Shield - erilainen otos Android-pelikonsoleista

Matkapuhelin

Suosittu Viestiä
Täydennä UX-suunnitteluprosessiasi - opas prototyyppisuunnitteluun
Täydennä UX-suunnitteluprosessiasi - opas prototyyppisuunnitteluun
Kuinka kuvata luovaa abstraktia valokuvaa iPhonellasi
Kuinka kuvata luovaa abstraktia valokuvaa iPhonellasi
Kykyjen oppimisohjelmien johtaja
Kykyjen oppimisohjelmien johtaja
Ruokinta tulevaisuuteen: yleiskatsaus elintarviketeknologiaan
Ruokinta tulevaisuuteen: yleiskatsaus elintarviketeknologiaan
Android-kehittäjän opas Google Location Services -sovellusliittymään
Android-kehittäjän opas Google Location Services -sovellusliittymään
 
Kuinka käyttää negatiivista tilaa valokuvauksessa kuvan muuttamiseen
Kuinka käyttää negatiivista tilaa valokuvauksessa kuvan muuttamiseen
Kuinka kauan käynnistysyrityksesi voi selviytyä ilman kokopäiväistä talousjohtajaa?
Kuinka kauan käynnistysyrityksesi voi selviytyä ilman kokopäiväistä talousjohtajaa?
Figma vs. Sketch vs. Axure - Tehtäväpohjainen arvostelu
Figma vs. Sketch vs. Axure - Tehtäväpohjainen arvostelu
Apple Watch pähkinänkuoressa: Ominaisuusesittely iOS-kehittäjille
Apple Watch pähkinänkuoressa: Ominaisuusesittely iOS-kehittäjille
Teroita taitojasi: Monitieteisen suunnittelun arvo
Teroita taitojasi: Monitieteisen suunnittelun arvo
Luokat
Ketterä KykyLähettäminenUi-SuunnitteluJaetut JoukkueetInnovaatioKaukosäätimen NousuMatkapuhelinMobiilisuunnitteluProsessi Ja TyökalutMuu

© 2023 | Kaikki Oikeudet Pidätetään

socialgekon.com