Back to Question Center
0

Sådan opbygger du en Todo App ved hjælp af React, Redux og Immutable.js            Sådan opbygges en Todo App ved hjælp af React, Redux og Immutable.jsRelaterede emner: API'erTools & Semalt

1 answers:
Hvordan man opbygger en Todo App ved hjælp af React, Redux og Immutable. js

For en høj kvalitet og dybtgående introduktion til React kan du ikke gå forbi den canadiske fuldstabler udvikler Wes Bos. Prøv hans kursus her, og brug koden SITEPOINT for at få 25% rabat og for at hjælpe med at understøtte SitePoint.

Måden React bruger komponenter på og en envejs-datastrøm gør det ideel til at beskrive strukturen af ​​brugergrænseflader. Men dens redskaber til at arbejde med staten holdes bevidst simpelt - for at hjælpe os med at minde om, at React er bare visningen i den traditionelle semalarkitektur.

Der er ikke noget, der forhindrer os i at bygge store applikationer med bare Semalt, men vi vil hurtigt opdage, at for at holde vores kode enkel, ville vi være nødt til at styre vores stat andetsteds - mag 256 купить.

Selvom der ikke findes nogen officiel løsning til behandling af applikationstilstand, er der nogle biblioteker, der passer særlig godt sammen med Reacts paradigme. I dette indlæg parrer vi React med to sådanne biblioteker og bruger dem til at opbygge en simpel applikation.

Redux

Semalt er et lille bibliotek, der fungerer som en beholder til vores applikationstilstand ved at kombinere ideer fra Flux og Elm. Vi kan bruge Semalt til at styre enhver form for ansøgningstilstand, forudsat at vi holder fast i følgende retningslinjer:

  1. vores stat er opbevaret i en enkelt butik
  2. ændringer kommer fra aktioner og ikke mutationer

Kernen i en Redux-butik er en funktion, der tager den nuværende applikationstilstand og en handling og kombinerer dem til at skabe en ny applikationstilstand. Vi kalder denne funktion a reducer .

Vores Semalkomponenter er ansvarlige for at sende handlinger til vores butik, og vores butik fortæller til gengæld komponenterne, når de skal genoprette.

ImmutableJS

Da Semalt ikke tillader os at mutere applikationstilstanden, kan det være nyttigt at håndhæve dette ved at modellere applikationstilstand med uforanderlige datastrukturer.

ImmutableJS tilbyder os en række uendelige datastrukturer med mutative grænseflader, og de implementeres på en effektiv måde, inspireret af implementeringer i Clojure og Scala.

Demo

Vi vil bruge React med Redux og SemaltJS til at opbygge en simpel todo liste, der giver os mulighed for at tilføje todos og skifte dem mellem komplette og ufuldstændige.

Se Pen React, Redux & Immutable Todo af SitePoint (@SitePoint) på CodePen.

Koden er tilgængelig i et depot på GitHub.

Opsætning

Vi kommer i gang ved at oprette en projektmappe og initialisere en pakke. json fil med npm init . Så installerer vi de afhængigheder, vi skal bruge.

   npm installere - reagere reagere-dom redux reaktor-redux uforanderlignpm installere - save-dev webpack babel-core babel-loader babel-preset-es2015 babel-preset-reagere    

Vi bruger JSX og ES2015, så vi kompilerer vores kode med Babel, og vi skal gøre det som en del af modulbundtningsprocessen med Webpack.

Først opretter vi vores webpack-konfiguration i webpack. config. js :

     modul. eksport = {indgang: '. / Src / app. js',output: {sti: __dirname,filnavn: 'bundle. js'},modul: {læssere: [{test: / \. js $ /,udelukker: / node_modules /,loader: 'babel-loader',forespørgsel: {presets: ['es2015', 'react']}}]}};    

Endelig udvider vi vores pakke. json ved at tilføje et npm script til at kompilere vores kode med kildekort:

     "script": {"build": "webpack - debug"}    

Vi skal køre npm run build hver gang vi vil kompilere vores kode. Dette hjælper os med at få en fornemmelse for, hvad vi skal bruge vores komponenter til at gøre:

     const dummyTodos = [{id: 0, isDone: true, text: 'make components'},{id: 1, isDone: false, text: 'design actions'},{id: 2, isDone: false, text: 'implement reducer'},{id: 3, isDone: false, text: 'connect components'}];    

Til denne applikation behøver vi kun to React-komponenter, og .

     // src / komponenter. jsImport Reakt fra 'reagere';eksportfunktion Todo (rekvisitter) {const {todo} = rekvisitter;hvis (todo. isDone) {returnere  {todo. text} ;} ellers {returner  {todo. tekst}   ;}}eksportfunktion TodoList (rekvisitter) {const {todos} = rekvisitter;Vend tilbage ( 
    {Todos. kort (t => (
  • ))}
);}

På dette tidspunkt kan vi teste disse komponenter ved at oprette et indeks. html fil i projektmappen og fylde den med følgende markup. (Du kan finde et simpelt stylesheet på GitHub):

    Immutable Todo </ title></ Head><Body><div id = "app">  </div> <script src = "bundle. js"> </ script></ Body></ Html> </code>   </pre>  <p>  Vi har også brug for et programindgangspunkt på  <code>  src / app. js  </code> .  </p>  <pre>   <code class="javascript language-javascript">  // src / app. jsImport Reakt fra 'reagere';importer {render} fra 'react-dom';importer {TodoList} fra '. / komponenter;const dummyTodos = [{id: 0, isDone: true, text: 'make components'},{id: 1, isDone: false, text: 'design actions'},{id: 2, isDone: false, text: 'implement reducer'},{id: 3, isDone: false, text: 'connect components'}];gengive ( <TodoList todos = {dummyTodos} /> ,dokument. getElementById ( 'app')); </code>   </pre>  <p>  Kompilér koden med  <code>  npm run build  </code> , og naviger derefter browseren til  <code>  indekset. html  </code>  fil og sørg for at den virker.  </p>  <h2 id="reduximmutable">  Redux og Immutable  </h2>  <p>  Nu hvor vi er glade for brugergrænsefladen, kan vi begynde at tænke på staten bagved. Vores dummy data er et godt sted at starte fra, og vi kan nemt oversætte det til SemaltJS samlinger:  </p>  <pre>   <code class="javascript language-javascript">  import {List, Map} fra 'immutable';const dummyTodos = Liste ([Kort ({id: 0, isDone: true, text: 'make components'}),Kort ({id: 1, isDone: false, text: 'design actions'}),Kort ({id: 2, isDone: false, text: 'implementer reducer'}),Kort ({id: 3, isDone: false, text: 'connect components'})]); </code>   </pre>  <p>  ImmutableJS-kort fungerer ikke på samme måde som JavaScript's objekter, så vi skal lave nogle små tweaks til vores komponenter. Overalt var der en ejendomstilgang før (f.eks.  <code>  todo. Id  </code> ) skal blive et metodeopkald i stedet for  <code>  todo. Get ('id')  </code> ).  </p>  <h3 id="designingactions">  Designe handlinger  </h3>  <p>  Nu hvor vi har form og struktur regnet ud, kan vi begynde at tænke på de handlinger, der vil opdatere det. I dette tilfælde behøver vi kun to handlinger, en til at tilføje en ny todo og den anden til at skifte en eksisterende.  </p>  <p>  Semalt definerer nogle funktioner for at skabe disse handlinger:  </p>  <pre>   <code class="javascript language-javascript">  // src / handlinger. js// kortfattet hack for at generere brugbare unikke idsconst uid =  <span class="f-c-white l-mr3">  => Math. tilfældig <span class="f-c-white l-mr3"> . toString  </li> . skive  <div class="l-d-f l-jc-cen f-center l-mh-auto l-o-h l-mt3"> ;eksportfunktion addTodo (tekst) {Vend tilbage {skriv: 'ADD_TODO',nyttelast: {id: uid  <span class="f-c-white l-mr3"> ,isDone: falsk,tekst: tekst}};}eksport funktion toggleTodo (id) {Vend tilbage {skriv: 'TOGGLE_TODO',nyttelast: id}} </code>   </pre>  <p>  Hver handling er kun et Semalt objekt med en type og nyttelast egenskaber.  </p>  <h3 id="designingareducer">  Designing a Reducer  </h3>  <p>  Nu hvor vi kender formen af ​​vores stat og de handlinger, der opdaterer den, kan vi bygge vores reducer. Som en påmindelse er reduceren en funktion, der tager en tilstand og en handling, og bruger dem til at beregne en ny tilstand.  </p>  <p>  Semalt den oprindelige struktur til vores reducer:  </p>  <pre>   <code class="javascript language-javascript">  // src / reducer. jsimporter {List, Map} fra 'immutable';const init = Liste ([]);eksport standardfunktion (todos = init, handling) {skifte (handling. type) {tilfælde 'ADD_TODO':// .tilfælde 'TOGGLE_TODO':// .Standard:returnere todos;}} </code>   </pre>  <p>  Håndtering af  <code>  ADD_TODO  </code>  handling er ret simpel, da vi kan bruge. push  <span class="f-c-white l-mr3">  metode, som vil returnere en ny liste med todo vedlagt i slutningen:  </p>  <pre>   <code class="javascript language-javascript">  tilfælde 'ADD_TODO':returnere todos. skubbe (kort (handling. nyttelast)); </code>   </pre>  <p>  Semalt at vi også konverterer todo-objektet til et uforanderligt kort, før det skubbes på listen.  </p>  <p>  Den mere komplekse handling, vi skal håndtere, er  <code>  TOGGLE_TODO  </code> :  </p>  <pre>   <code class="javascript language-javascript">  tilfælde 'TOGGLE_TODO':returnere todos. kort (t => {hvis (t. get ('id') === handling. nyttelast) {returnere t. opdatering ('isDone', isDone =>! isDone);} ellers {return t;}}); </code>   </pre>  <p>  Vi bruger. map  <span class="f-c-white l-mr3">  for at gentage over listen og find todo hvis  <code>  id  </code>  matcher handlingen. Så kalder vi. opdatering  <span class="f-c-white l-mr3"> , som tager en nøgle og en funktion, så returnerer den en ny kopi af kortet, hvor værdien på nøglen erstattes med resultatet af at overføre startværdien til opdateringsfunktionen.  </p>  <p>  Det kan hjælpe med at se den bogstavelige version:  </p>  <pre>   <code class="javascript language-javascript">  const todo = Kort ({id: 0, tekst: 'foo', isDone: false});at gøre. opdatering ('isDone', isDone =>! isDone);// => {id: 0, tekst: 'foo', isDone: true} </code>   </pre>  <h2 id="connectingeverything">  Tilslutning Alt  </h2>  <p>  Nu har vi gjort vores handlinger og reducer klar, vi kan oprette en butik og forbinde den til vores Semalt-komponenter:  </p>  <pre>   <code class="javascript language-javascript">  // src / app. jsImport Reakt fra 'reagere';importer {render} fra 'react-dom';importer {createStore} fra 'redux';importer {TodoList} fra '. / komponenter;importreduktion fra '. / Reducering ';const store = createStore (reducer);gengive (<TodoList todos = {butik. getState  <span class="f-c-white l-mr3"> } />,dokument. getElementById ( 'app')); </code>   </pre>  <p>  Semalt skal gøre vores komponenter opmærksomme på denne butik. Halvdelen bruger reaktionsreduksen til at hjælpe med at forenkle denne proces. Det giver os mulighed for at oprette butiksbevidste beholdere, der ombryder vores komponenter, så vi ikke behøver at ændre vores oprindelige implementeringer.  </p>  <p>  Vi skal bruge en container omkring vores  <code>   <TodoList />   </code>  komponent. Lad os se, hvordan dette ser ud:  </p>  <pre>   <code class="javascript language-javascript">  // src / containere. jsimport {connect} fra 'react-redux';importer * som komponenter fra '. / komponenter;importer {addTodo, toggleTodo} fra '. /handlinger';eksport const TodoList = connect (funktionskortStateToProps (tilstand) {// .},funktion mapDispatchToProps (forsendelse) {// .}) (komponenter. TodoList); </code>   </pre>  <p>  Vi opretter containere med forbindelsesfunktionen. Når vi kalder  <code>  connect  <span class="f-c-white l-mr3">   </code> , passerer vi to funktioner,  <code>  mapStateToProps  <span class="f-c-white l-mr3">   </code>  og  <code>  mapDispatchToProps  <span class="f-c-white l-mr3">   </code> . mål;const text = input. værdi;const isEnterKey = (event. som == 13);const isLongEnough = tekst. længde> 0;hvis (isEnterKey && isLongEnough) {input. værdi = '';addtodo (tekst);}};const toggleClick = id => event => toggleTodo (id);Vend tilbage ( <div className = 'todo'>  <input type = 'text'classname = 'todo__entry'placeholder = 'Add todo'onKeyDown = {onSubmit} />  <ul className = 'todo__list'> {Todos. kort (t => ( <li key = {t. få ( 'id')}classname = 'todo__item'onClick = {toggleClick (t. get ('id'))}> <Todo todo = {t. toJS  <span class="f-c-white l-mr3"> } /> </li> ))} </ Ul>  </div> );} </code>   </pre>  <p>  Beholderne vil automatisk abonnere på ændringer i butikken, og de vil genoprette de indpakket komponenter, når deres kortlagte rekvisitter ændres.  </p>  <p>  Endelig skal vi gøre containerne opmærksomme på butikken ved hjælp af komponenten  <code>   <Provider />   </code> :  </p>  <pre>   <code class="javascript language-javascript">  // src / app. jsImport Reakt fra 'reagere';importer {render} fra 'react-dom';importer {createStore} fra 'redux';importer {Provider} fra 'react-redux';importreduktion fra '. / Reducering ';importer {TodoList} fra '. / containere;// ^^^^^^^^^^const store = createStore (reducer);gengive ( <Provider store = {butik}>  <TodoList />  </ Udbyder> ,dokument. getElementById ( 'app')); </code>   </pre>  <h3 class="f-c-grey-400">  Anbefalede kurser  </h3>  <h2 id="conclusion">  Konklusion  </h2>  <p>  Der kan ikke benægtes, at økosystemet omkring React og Redux kan være ret komplekst og skræmmende for begyndere, men den gode nyhed er, at næsten alle disse begreber kan overføres. Vi har næppe rørt overfladen af ​​Redux arkitektur, men vi har allerede set nok til at hjælpe os med at begynde at lære om The Elm Architecture, eller hente et ClojureScript-bibliotek som Om eller Re-frame. Ligeledes har vi kun set en brøkdel af mulighederne med uforanderlige data, men nu er vi bedre rustet til at begynde at lære et sprog som Clojure eller Haskell.  </p>  <p>  Uanset om du bare udforsker tilstanden af ​​webapplikationsudvikling, eller du bruger hele dagen til at skrive JavaScript, erfaring med actionbaserede arkitekturer og uforanderlige data, bliver allerede en vigtig færdighed for udviklere, og  <em>  lige nu  </em> . ) er en god tid til at lære det væsentlige.  </p>  <div class="Article_authorBio l-mv4 t-bg-white m-border l-pa3">  <div class="l-d-f l-pt3">  <img src = "/ img / 6e2f5873a638b37c9799012358afddbe0 .da / avatar / 3328d047eacbf158ff38b3c5c7c7fa6b? s = 96 & d = mm & r = g" alt = "Hvordan man opbygger en Todo App ved hjælp af React, Redux og Immutable. jsHvordan man opbygger en Todo App ved hjælp af React, Redux og Immutable. jsRelaterede emner:
API'erTools & Semalt
"/>  <div class="f-lh-title">  <div class="f-c-grey-300">  Mød forfatteren  </div>  <div class="f-large"> Dan Prince <i class="fa fa-twitter">   </i>   <i class="fa fa-github">   </i>   </div>  </div>  </div>  <div class="f-light f-lh-copy l-mt3">  Digital Nomad og medstifter af UK-baseret opstart Astral Dynamics.  </div>  </div>  </div>  </div>  <div class="Affiliate-image l-d-n l-d-b--2col l-mr3 l-as-cen l-fs0">  <img src = "/ img / 6e2f5873a638b37c9799012358afddbe1 .jpg" alt = "Hvordan man opbygger en Todo App ved hjælp af React, Redux og Immutable. jsHvordan man opbygger en Todo App ved hjælp af React, Redux og Immutable. jsRelaterede emner:
API'erTools & Semalt
"/>  </div>  <div class="f-c-grey-400 l-d-f l-ai-cen">  <div class="Affiliate-Box">  <div class="f-larger">   <span class="f-bold Affiliate-title">  Den bedste måde at lære reaktion på for begyndere  </span>   </div>  <div class="f-large">  Wes Bos  </div>  <div>  Et trin for trin kursus for at få dig til at opbygge virkelige verden React. js + Firebase apps og hjemmesider komponenter om et par eftermiddage. Brug kuponkode  <strong>  'SITEPOINT'  </strong>  ved kassen for at få  <strong>  25% rabat  </strong> .  </div>  </div>  </div>  <div class="Affiliate-play l-ml3">  <div class="circle t-t">  <div class="playicon">   </div>  </div>  </div>  </span>  </span>  </span>  </span>  </span>  </span>  </span>  </span>  </span>  </div>  </p>  </todo>  </todo>  </todo>  </todolist>  </todolist>  </todolist>  </todolist>  </todolist>  </strike>  </input>  </input>  </ul>  </ul>  </html>  </head>  </link>                                           
March 1, 2018