React i den virkelige verden


I forrige uke ble det avholdt en meetup på Teknologihuset i Oslo om React. Dette er en oppsummering av lyntalene som ble avholdt, til glede for alle som ikke var tilstede.

Erfaringer fra utviklingen av nettbutikk.netcom.no

Jakub Holy, Jakub Lind og Alex York avholdt den lengste lyntalen, og snakket om sine erfaringer med React, Reflux og npm fra et prosjekt hos NetCom. Sammen tok de for seg de tre viktigste utfordringene de møtte under utviklingen.

Utfordring 1: I begynnelsen ble det laget en mengde stores, hvilket resulterte en stor mengde actions fordi hver store har en korresponderende action-fil. Dette anså de som et problem, og etter en lang diskusjon endte de opp med en stor refaktorering som førte til at de all logikk ble samlet i en enkelt store.

Utfordring 2: Serverside rendering var et absolutt krav på grunn av rask lastetid og SEO. Problemet er at alle eksemplene som ligger på nettet er for enkle. De vanskelige problemene, som å forhåndspopulere stores med data var en hard nøtt å knekke. Løsningen ble eksponere en funksjon(data) mot App.jsx som igjen går mot store.

Utfordring 3: Testing. Først så de på Jest. Denne var bra i teorien, men ikke så bra i det virkelige liv. Testene er trege (fra hundrevis av millisekunder pr. test til flere sekunder). Jest utvikles av et lite team med utviklere og kjører på node 0.10 og Jasmine 1.3 (mens både node og Jasmin finnes i nyere versjoner). Automockingen skaper problemer. Det gjør også rare bugs og ikke-standard import av moduler. Løsningen ble å gå for en miks av Mocha Chai, Sinon.

One-state architecture

Thomas Bassetto snakket om hans erfaringer med en Elm-inspirert arkitektur for React-applikasjoner, med arkitektur hentet fra kefir og baconjs. Tankegangen er at applikasjonen kun har en tilstand, og at enhver event som skal forårsake tilstandsendringer skal komme fra utsiden (som tastetrykk, endre størrelse på nettleser, side-endringer etc).

Bassetto viste en del eksempler under lyntalen og noe av dette er tilgjengelig fra hans presentasjon. Mer omfattende eksempler vil etterhvert bli publisert på github-kontoen hans, så det kan være verdt å følge med på denne.

Isomorfiske JavaScript-applikasjoner

Eirik Vullum snakket om å utvikle en isomorfisk applikasjon for mobilversjonen av sol.no basert på react-async. Med react-async og renderToStringAsync er det svært enkelt å sette opp en isomorfisk applikasjon, hvilket han også forklarte. Ettersom min egen blogg er basert på samme oppsett kjente jeg meg god igjen i arkitekturvalget. Eirik snakket også om routing-løsningen som ble laget for appen, som er en single page application med uendelig scrolling. Ettersom tilbake-knappen normalt ville ta deg til toppen av siden laget han en løsning som ganske enkelt ser slik ut:

if (isBrowser && hasHistory) {
    history.pushState({
      articles: his.state.articles,
      scrollPosition: document.body.scrollTop
    }, null, '/?offset=' + this.state.articles.length);
  }

Og det må jo sies å være en ganske smart løsning.

React Native

Magnús Dæhlen snakket om hans erfaringer med React Native. Med utgangspunkt i den ferskeste versjonen av React Native kikket Magnus på muligheten for å bygge en sosial mobilapp kalt Woop som kan konkurrere med (og være bedre enn) Yammer. Woop finnes allerede i en React-versjon, så eksperimentet gikk ut på å se hvor raskt man kunne lage Woop Native uten å skrive om appen til Objective C (eller Swift). Svaret var ganske enkelt: en fungerende prototype lager du en arbeidsdag, og da kan du gjenbruke JavaScript-koden du allerede har skrevet for web-versjonen. En annen fordel fremfor native programmering er at du kan refreshe appen med Cmd-R og teste endringer umiddelbart i stedet for å rekompilere som du må når du programmerer i Objective C. Ulempen er at du er avhengige av egenutviklede kontroller for elementer som ikke følger med React Native. For eksempel, skriver du følgende i React:


render: function() {
    return (
      <div className="container">
        <div>
          <p> Welcome to Woop</p>
          <img className="logo" src="./logo.png" />
        </div>
        <Messages messages={Dummy} />
      </div>

    );

Så kan du lage en React Native-versjonen ved å gjøre det om til følgende:


 render: function() {
    return (
      <View style={styles.container}>
        <View>
          <Text> Welcome to Woop</Text>
          <Image style={styles.image} source={require('image!woop')} />
        </View>
        <Messages messages={Dummy} />
      </View>

    );

Responsive images in React

Simen Brekken og Daniel Mahal fra Anton Sport bidro med en løsning på et problem vi alle sliter med innimellom, responsive bilder. Utgangspunktet for problemet var som følger: 50.000+ bilder. Båndbredde-restriksjoner. Økende pikseltetthet (retinaskjermer). Begrensede menneskelige ressurser. De kikket først på de vanlige løsningene, som er:


PictureFill
<img  srcset={...} sizes={...} />
<picture> & <source />
HiSRC
jQuery
max-width: 100%; height: auto

men ingen av disse passet helt til den bruken de så for seg.

Løsningen ble å bruke en skybasert tjeneste (cloudinary) som lar deg generere bilder ved behov, og å gi brukeren det mest optimale bildet basert på pikseltettheten til enheten som samtidig tar høyde for om brukerens tilgjengelige båndbredde. En viktig regel: ingen menneskelige mellomledd. Personlig synes jeg koden var både elegant og smart, så jeg vil anbefale at du tar en titt.

Reflux improved

Jeg bidro også med en liten presentasjon om Reflux.

En React-app dreier seg nesten hovedsakelig om dataflyt. Facebook laget en arkitektur de kalte Flux, og programmerere over hele verden har tatt denne til seg og laget sine egne implementasjoner av ideen. Av disse er Reflux en jeg har kikket mye på, og som vi bruker daglig i et prosjekt jeg sitter i hos NetCom.

Kjernen i presentasjonen min handler om en bedre og mer testbar modell for å bruke Reflux, der tanken er å unngå at du sitter med tynne actions og komponenter og fete stores med mye logikk, hvilket er noe man gjerne ser i eksemplene man finner på nettet. I stedet lager man services, og gjør dataendringer i actions, og så sitter man igjen med testbare tjenester, tynne stores som bare tar seg av data, og actions-filer som får ansvar for å hente og sende data til stores.

Omslagsbilde Copyright Facebook © 2015. Brukt med tillatelse