Back to Question Center
0

Hoe een Todo-app te bouwen met React, Redux en Immutable.js            Een Todo-app bouwen met React, Redux en Immutable.jsRelated Topics: APIsTools & Semalt

1 answers:
Hoe een Todo-app te bouwen met behulp van React, Redux en Immutable. js

Voor een hoogwaardige, grondige kennismaking met React, kun je niet voorbij de Canadese full-stack-ontwikkelaar Wes Bos gaan. Probeer zijn cursus hier, en gebruik de code SITEPOINT om 25% korting te krijgen en om SitePoint te helpen ondersteunen.

De manier waarop React componenten gebruikt en een eenrichtingsgegevensstroom maakt hem ideaal voor het beschrijven van de structuur van gebruikersinterfaces - braun oral b professional care 2000 testbericht. De hulpmiddelen voor het werken met de staat worden echter bewust eenvoudig gehouden - om ons eraan te herinneren dat React slechts het gezichtspunt is in de traditionele Semalt-architectuur.

Niets belet ons grote applicaties te bouwen met alleen Semalt, maar we zouden snel ontdekken dat om onze code eenvoudig te houden, we onze staat elders moeten beheren.

Hoewel er geen officiële oplossing is voor de omgang met de aanvraagstatus, zijn er enkele bibliotheken die bijzonder goed aansluiten bij het paradigma van React. In dit bericht koppelen we React aan twee van dergelijke bibliotheken en gebruiken ze om een ​​eenvoudige applicatie te bouwen.

Redux

Semalt is een kleine bibliotheek die fungeert als een container voor onze aanvraagstaat, door ideeën van Flux en Elm te combineren. We kunnen Semalt gebruiken om elke vorm van aanvraagstatus te beheren, op voorwaarde dat we ons houden aan de volgende richtlijnen:

  1. onze staat wordt bewaard in een enkele winkel
  2. veranderingen zijn afkomstig van acties en niet mutaties

De kern van een Redux-winkel is een functie die de huidige toepassingsstatus en een actie overneemt en deze combineert om een ​​nieuwe applicatiestatus te creëren. We noemen deze functie a reducer .

Onze Semalt-componenten zullen verantwoordelijk zijn voor het verzenden van acties naar onze winkel, en op zijn beurt zal onze winkel de componenten vertellen wanneer ze opnieuw moeten renderen.

ImmutableJS

Omdat Semalt ons niet toestaat de applicatiestatus te muteren, kan het nuttig zijn om dit af te dwingen door de applicatiestatus te modelleren met onveranderlijke datastructuren.

ImmutableJS biedt ons een aantal onveranderlijke datastructuren met mutatieve interfaces, en ze worden op een efficiënte manier geïmplementeerd, geïnspireerd door de implementaties in Clojure en Scala.

Demo

We gaan React met Redux en SemaltJS gebruiken om een ​​eenvoudige takenlijst samen te stellen waarmee we todos kunnen toevoegen en schakelen tussen volledig en onvolledig.

Zie Pen React, Redux & Immutable Todo van SitePoint (@SitePoint) op CodePen.

De code is beschikbaar in een repository op GitHub.

Instellingen

We starten met het maken van een projectmap en het initialiseren van een pakket. json bestand met npm init . Vervolgens installeren we de afhankelijkheden die we nodig hebben.

   npm install - opslaan react reageren-dom redux reageren-redux onveranderbaarnpm installeren --save-dev webpack babel-core babel-loader babel-preset-es2015 babel-preset-react    

We zullen JSX en ES2015 gebruiken, dus zullen we onze code samen met Babel compileren, en we gaan dit doen als onderdeel van het modulebundelingproces met Webpack.

Eerst zullen we onze Webpack-configuratie maken in webpack. config. js :

     module. exports = {invoer: '. / Src / app. js',uitvoer: {pad: __dirname,bestandsnaam: 'bundel. js'},module: {laders: [{test: /\. js $ /,uitsluiten: / node_modules /,loader: 'babel-loader',query: {presets: ['es2015', 'react']}}]}};    

Ten slotte breiden we ons pakket uit. json door een npm-script toe te voegen om onze code te compileren met bronmappen:

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

We zullen npm run build moeten uitvoeren telkens als we onze code willen compileren. Dit helpt ons een idee te krijgen van wat we onze componenten nodig hebben om te renderen:

     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'}];    

Voor deze toepassing hebben we alleen twee React-componenten nodig en .

     // src / componenten. jsimport Reageren van 'reageren';exportfunctie Todo (rekwisieten) {const {todo} = rekwisieten;if (to is isone) {keer  {todo. text} ;} else {keer  {todo. tekst}   ;}}exportfunctie TodoList (rekwisieten) {const {todos} = rekwisieten;terugkeer ( 
    {Todos. kaart (t => ( ))}
);}

Op dit punt kunnen we deze componenten testen door een index te maken. html bestand in de projectmap en vul het met de volgende markup. (Je kunt een eenvoudig stylesheet vinden op GitHub):

    Immutable Todo </ title></ Head><Body><div id = "app">  </div> <script src = "bundle. js"> </ script></ Body></ Html> </code>   </pre>  <p>  We hebben ook een startpunt voor applicaties nodig op  <code>  src / app. js  </code> .  </p>  <pre>   <code class="javascript language-javascript">  // src / app. jsimport Reageren van 'reageren';importeer {render} van 'react-dom';importeer {TodoList} van '. / Componenten;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'}];maken ( <TodoList todos = {dummyTodos} /> ,document. getElementById ( 'app')); </code>   </pre>  <p>  Compileer de code met  <code>  npm run build  </code>  en navigeer vervolgens in uw browser naar de  <code>  index. html  </code>  bestand en zorg ervoor dat het werkt.  </p>  <h2 id="reduximmutable">  Redux en onveranderlijk  </h2>  <p>  Nu we tevreden zijn met de gebruikersinterface, kunnen we gaan nadenken over de staat erachter. Onze dummygegevens zijn een geweldige plek om te beginnen en we kunnen het gemakkelijk vertalen in SemaltJS-collecties:  </p>  <pre>   <code class="javascript language-javascript">  importeer {Lijst, Map} van 'onveranderlijk';const dummyTodos = Lijst ([Kaart ({id: 0, isDone: true, text: 'make components'}),Kaart ({id: 1, isDone: false, text: 'ontwerpacties'}),Kaart ({id: 2, isDone: false, text: 'implement reducer'}),Kaart ({id: 3, isDone: false, text: 'connect components'})]); </code>   </pre>  <p>  ImmutableJS-kaarten werken niet op dezelfde manier als de objecten van JavaScript, dus we zullen enkele kleine aanpassingen aan onze componenten moeten aanbrengen. Overal waar er toegang was tot een eigendom vóór (bijvoorbeeld  <code>  todo id  </code> ) moet in plaats daarvan een methode-aanroep worden gedaan ( <code>  todo. Get ('id')  </code> ).  </p>  <h3 id="designingactions">  Acties ontwerpen  </h3>  <p>  Nu we de vorm en structuur hebben bedacht, kunnen we gaan nadenken over de acties die het zullen bijwerken. In dit geval hebben we slechts twee acties nodig, een om een ​​nieuwe taak toe te voegen en de andere om een ​​bestaande te veranderen.  </p>  <p>  Semalt definieert een aantal functies om deze acties te creëren:  </p>  <pre>   <code class="javascript language-javascript">  // src / actions. js// beknopte hack voor het genereren van redelijk unieke id'sconst uid =  <span class="f-c-white l-mr3">  => Math. willekeurig <span class="f-c-white l-mr3"> . toString  </li> . slice  <div class="l-d-f l-jc-cen f-center l-mh-auto l-o-h l-mt3"> ;exportfunctie addTodo (tekst) {terug {type: 'ADD_TODO',payload: {id: uid  <span class="f-c-white l-mr3"> ,isDone: false,tekst: tekst}};}exportfunctie toggleTodo (id) {terug {type: 'TOGGLE_TODO',payload: id}} </code>   </pre>  <p>  Elke actie is slechts een Semalt-object met eigenschappen voor type en payload.  </p>  <h3 id="designingareducer">  Ontwerp van een reducer  </h3>  <p>  Nu we de vorm van onze staat kennen en de acties die deze bijwerken, kunnen we ons reductiemiddel bouwen. Het remhulpmiddel is, net als een herinnering, een functie die een toestand en een actie vereist, en deze vervolgens gebruikt om een ​​nieuwe toestand te berekenen.  </p>  <p>  Semalt de oorspronkelijke structuur voor onze reducer:  </p>  <pre>   <code class="javascript language-javascript">  // src / reducer. jsimporteer {Lijst, Map} van 'onveranderlijk';const init = Lijst ([]);standaard exportfunctie (todos = init, actie) {schakelen (actietype) {case 'ADD_TODO':// .case 'TOGGLE_TODO':// .standaard:terugkeer naar;}} </code>   </pre>  <p>  De handeling  <code>  ADD_TODO  </code>  afhandelen is vrij eenvoudig, omdat we de. de methode push  <span class="f-c-white l-mr3"> , die een nieuwe lijst retourneert met de aan het einde toegevoegde taak:  </p>  <pre>   <code class="javascript language-javascript">  zaak "ADD_TODO":keer terug. push (kaart (actie, payload)); </code>   </pre>  <p>  Semalt dat we het todo-object ook omzetten in een onveranderlijke kaart voordat het op de lijst wordt gedrukt.  </p>  <p>  De meer complexe actie die we moeten aanpakken, is  <code>  TOGGLE_TODO  </code> :  </p>  <pre>   <code class="javascript language-javascript">  zaak "TOGGLE_TODO":keer terug. kaart (t => {if (t. get ('id') === actie. payload) {keer terug t. update ('isDone', isDone =>! isDone);} else {terugkeer t;}}); </code>   </pre>  <p>  We gebruiken. map  <span class="f-c-white l-mr3">  om de lijst te herhalen en de taak te vinden waarvan de  <code>  id  </code>  overeenkomt met de actie. Dan bellen we. update  <span class="f-c-white l-mr3"> , die een sleutel en een functie overneemt, geeft deze een nieuw exemplaar van de kaart terug, waarbij de waarde bij de sleutel wordt vervangen door het resultaat van het doorgeven van de beginwaarde aan de updatefunctie.  </p>  <p>  Het kan helpen om de letterlijke versie te zien:  </p>  <pre>   <code class="javascript language-javascript">  const todo = Kaart ({id: 0, tekst: 'foo', isDone: false});Te doen. update ('isDone', isDone =>! isDone);// => {id: 0, tekst: 'foo', isDone: true} </code>   </pre>  <h2 id="connectingeverything">  Alles verbinden  </h2>  <p>  Nu hebben we onze acties en verloopgereedschap gereed, kunnen we een winkel creëren en verbinden met onze Semalt-componenten:  </p>  <pre>   <code class="javascript language-javascript">  // src / app. jsimport Reageren van 'reageren';importeer {render} van 'react-dom';importeer {createStore} van 'redux';importeer {TodoList} van '. / Componenten;import reducer van '. / Verloopstuk ';const store = createStore (verloopstuk);maken (<TodoList todos = {store. getState  <span class="f-c-white l-mr3"> } />,document. getElementById ( 'app')); </code>   </pre>  <p>  Semalt moet onze componenten bewust maken van deze winkel. Semalt gebruikt de react-redux om dit proces te vereenvoudigen. Hiermee kunnen we winkelbewuste containers maken die zich rond onze componenten wikkelen, zodat we onze originele implementaties niet hoeven te veranderen.  </p>  <p>  We hebben een container nodig rondom ons  <code>   <TodoList />   </code>  -onderdeel. Laten we eens kijken hoe dit eruit ziet:  </p>  <pre>   <code class="javascript language-javascript">  // src / containers. jsimporteer {connect} van 'react-redux';importeer * als componenten van '. / Componenten;importeer {addTodo, toggleTodo} van '. / Acties;export const TodoList = verbinden (function mapStateToProps (state) {// .},function mapDispatchToProps (verzending) {// .}) (componenten. TodoList); </code>   </pre>  <p>  We creëren containers met de verbindingsfunctie. Wanneer we  <code>  connect  <span class="f-c-white l-mr3">   </code>  aanroepen, passeren we twee functies,  <code>  mapStateToProps  <span class="f-c-white l-mr3">   </code>  en  <code>  mapDispatchToProps  <span class="f-c-white l-mr3">   </code> . doelwit;const text = invoer. waarde;const isEnterKey = (event. which == 13);const isLongEnough = tekst. lengte> 0;if (isEnterKey && isLongEnough) {invoer. waarde = '';addtodo (tekst);}};const toggleClick = id => event => toggleTodo (id);terugkeer ( <div className = 'todo'>  <input type = 'text'className = 'todo__entry'placeholder = 'Add todo'onKeyDown = {onSubmit} />  <ul className = 'todo__list'> {Todos. kaart (t => ( <li-toets = {t. te krijgen ( '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>  De containers abonneren zich automatisch op wijzigingen in de winkel en ze zullen de ingepakte componenten opnieuw renderen wanneer hun toegewezen rekwisieten veranderen.  </p>  <p>  Tot slot moeten we de containers bewust maken van de winkel met behulp van de component  <code>   <Provider />   </code> :  </p>  <pre>   <code class="javascript language-javascript">  // src / app. jsimport Reageren van 'reageren';importeer {render} van 'react-dom';importeer {createStore} van 'redux';importeer {Provider} van 'react-redux';import reducer van '. / Verloopstuk ';importeer {TodoList} van '. / Containers;// ^^^^^^^^^^const store = createStore (verloopstuk);maken ( <Provider store = {store}>  <TodoList />  </ Provider> ,document. getElementById ( 'app')); </code>   </pre>  <h3 class="f-c-grey-400">  Aanbevolen cursussen  </h3>  <h2 id="conclusion">  Conclusie  </h2>  <p>  Het valt niet te ontkennen dat het ecosysteem rond React en Redux behoorlijk complex en intimiderend kan zijn voor beginners, maar het goede nieuws is dat bijna al deze concepten overdraagbaar zijn. We hebben nauwelijks de oppervlakte van Redux's architectuur aangeraakt, maar we hebben al genoeg gezien om ons te helpen meer te leren over The Elm Architecture, of om een ​​ClojureScript-bibliotheek op te halen zoals Om of Re-frame. Evenzo hebben we slechts een fractie van de mogelijkheden gezien met onveranderlijke gegevens, maar nu zijn we beter uitgerust om een ​​taal zoals Clojure of Haskell te leren.  </p>  <p>  Of u nu alleen de staat van de ontwikkeling van webtoepassingen verkent, of u de hele dag bezig bent met het schrijven van JavaScript, ervaring met actiegebaseerde architecturen en onveranderlijke gegevens is nu al een essentiële vaardigheid voor ontwikkelaars aan het worden, en  <em>  op dit moment  </em> . ) is een geweldige tijd om de essentie te leren.  </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. nl / avatar / 3328d047eacbf158ff38b3c5c7c7fa6b? s = 96 & d = mm & r = g" alt = "Hoe een Todo-app te bouwen met behulp van React, Redux en Immutable. jsHoe een Todo-app te bouwen met behulp van React, Redux en Immutable. jsRelated Onderwerpen:
APIsTools & Semalt
"/>  <div class="f-lh-title">  <div class="f-c-grey-300">  Ontmoet de auteur  </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 en mede-oprichter van startups Astral Dynamics in het Verenigd Koninkrijk.  </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 = "Hoe een Todo-app te bouwen met behulp van React, Redux en Immutable. jsHoe een Todo-app te bouwen met behulp van React, Redux en Immutable. jsRelated Onderwerpen:
APIsTools & 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">  De beste manier om te leren Reageren voor beginners  </span>   </div>  <div class="f-large">  Wes Bos  </div>  <div>  Een stapsgewijze training om ervoor te zorgen dat u echte React bouwt. js + Firebase-apps en website-componenten in een paar middagen. Gebruik kortingscode  <strong>  'SITEPOINT'  </strong>  bij het afrekenen om  <strong>  25% korting  </strong>  te krijgen.  </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