Refactoring en 3 andere tips die we onthouden van React.js in Amsterdam

Op door Thorr Stevens

Bij Marlon is React.js ons frontend framework naar keuze. React Native gebruiken we om quality mobile apps af te leveren aan onze klanten. Ook dit jaar trokken enkele van onze Javascript developers naar Amsterdam om hun React skills bij te schaven. Thorr en Nico doen uit de doeken wat zij bijleerden over het React-ecosysteem.

Refactor waar nodig

Siddharth Kshetrapal leerde ons in zijn talk “Refactoring React” hoe we ‘code smell’ kunnen vermijden in React.js. Wij hebben begrepen dat code smell niet persé hoeft te betekenen dat er iets fout is met je React-code, maar dat het wel kan lijken alsof het zo is. Die code smell kan op verschillende plaatsen voorkomen.

Op DX-niveau (Developer Experience) kan code smell betekenen dat een <Toggle/> component een onToggle of onClick handler heeft in plaats van de algemeen gekende onChange benaming. Veel developers zien een onChange als de standaard in dit geval, waardoor het intuïtiever is om deze te gebruiken.

Op featureniveau is het eerder belangrijk dat je ‘feature envy’ vermijdt. Dat wil zeggen dat je componenten best niet teveel bezig zijn met hoe de omringende of child components werken. Encapsuleer je componenten en optimaliseer ze voor mogelijke veranderingen van omgeving. Zo vermijd je dat je component niet meer werkt wanneer het in een andere context wordt gebruikt.

Een ander voorbeeld van code smell is het niet spreaden van props op single node componenten. Een single node component kan bijvoorbeeld zijn:

React.js - ongespreide props op single node componenten

Bij dit component is het probleem dat zaken die ingeburgerd zijn, zoals het meegeven van een id, className of andere HTML-attributen, niet meer zullen werken. Dit is makkelijk op te lossen door de resterende props wel toe te voegen aan het DOM-element:

In deze ‘oplossing’ zitten we opnieuw met een probleem. Er wordt al een standaard className toegekend, maar die wordt overschreven indien we ook een className aan <Form/> toevoegen. De oplossing? De standaard className mergen met die uit de props:

React.js - props toevoegen aan DOM-element

Het React-team heeft natuurlijk die code smell patronen opgemerkt en een oplossing bedacht. Wat wij daarom vooral onthouden? In projecten met React 16.8 laten we patronen als higher order components best even achterwege voor de nieuwere React Hooks API’s.

Wil je graag meer tips over React refactoring? We verzamelden alle tips van Sid in een handig lijstje:

  1. Vermijd lokale state wanneer je zaken uit props kan halen.
  2. Benoem je functies naar gedrag in plaats van interactie, maar hou het intuïtief.
  3. Pas op met ‘Feature Envy.’
  4. Rangschikking bij het doorgeven van props maakt een verschil.
  5. Maak een keuze tussen controlled & uncontrolled inputs.
  6. Geef niet teveel verantwoordelijkheden aan je componenten.
  7. Higher Order Components kunnen voor naamconflicten zorgen.
  8. Gebruik children voor zaken als message/title props.
  9. Kies verstandig tussen cloneElement & context.

React componenten als design primitives

Soms zijn er te veel manieren/tools of programmeertalen die de communicatie binnen een team met designers en developers moeilijker maken. De heilige graal van deze communicatie zou eerder gelimiteerd moeten worden om te verzekeren dat iedereen in een team elkaar correct en goed begrijpt.

Andrey Okonetchnikov stelde in zijn talk “A common design language” een uitbreiding op design systems voor als best practice. Zo’n systeem combineert regels omtrent typografie, witruimte, kleuren… om limieten op te leggen. Zo ontstaat er een set van instructies, een soort van technisch huisstijlhandboek, om mee te geven aan alle betrokkenen. Als UI de designtaal is voor digitale producten, zijn componenten de ideale fit om als woorden te gebruiken in die taal.  

Het probleem blijft dat designers en developers andere ‘talen’ spreken. Designers spreken in de vorm van design tools en prototypes, waar developers praten in programmeertalen als HTML, CSS en Javascript. Dat betekent natuurlijk niet dat designers moeten programmeren of omgekeerd. De oplossing ligt erin gelijkenissen te zoeken tussen de talen. De overlap hier zit in de UI primitives: de allerkleinste units/atomen die een UI kunnen opbouwen.

Binnen React denken we qua UI primitives voor tekst bijvoorbeeld aan <Text> jsx; containers kunnen <View>'s zijn, afbeeldingen <Image>, knoppen <Button> & iconen <Icon>. De props van deze primitieve componenten zorgen dan voor de nodige variaties zoals <Text kind="danger"> & <Button kind="primary">. De eindoplossing zit hem volgens Andrey in het gebruiken van zo'n React-componenten in design tools. Designers ontwerpen dan als het ware met componenten als universele design taal en developers weten meteen waarover het gaat.

UI primitives als atomen om een UI te bouwen

Ontwerpen met React

Mark Dalgleish bouwde in “Designing with React” verder op wat Andrey vertelde over  "Component driven design" en het ontwerpen in het finale medium.

Tien jaar geleden werd vermeden om direct met code te ontwerpen, voornamelijk omdat code traag was. Vandaag de dag is dat gelukkig niet zo. Codevoorbeelden kunnen tegenwoordig heel snel opgezet worden met tools als Codesandbox. Ook iteratie/variatie wordt heel makkelijk dankzij features als forking. Omdat we hier spreken over web tools, zijn die variaties op zich makkelijk deelbaar met andere betrokken partijen.

Hoe passen we diezelfde veranderingen toe op moderne design systemen? Hoe maken we component code vlugger beschikbaar voor designers, zonder eerst een resem aan libraries te moeten installeren en runnen in terminal?

Seek, het bedrijf waar Mark voor werkt, heeft met Playroom zelf ook zo'n React design tool ontworpen. De tool ziet er misschien uit als Sketch, maar de focus van Playroom ligt op jsx. Naast je preview van je design, zie je in een apart paneel ook live de code die het ontwerp opbouwt. Design kan binnen Playroom dus ook volledig in code gedaan worden, binnen hetzelfde paneel.

Het einddoel is zowel een code powered design tool als een design powered development tool. Belangrijker is dat het een formaat met zich meebrengt dat heel uitnodigend is voor zowel developers als non-developers. Iets wat niet altijd even makkelijk is.
Playroom tool visualisation

Leer uit de fouten van anderen

Niemand meer geschikt om dit principe uit te leggen dan Max Stoiber. In zijn jonge leven heeft hij al een interessant traject afgelegd binnen de React JS en Open Source wereld. Hij was onder andere de core contributor van het veelgebruikte styled-components. Zijn laatste start-up verkocht hij aan Github. Maar dat betekent niet dat alles altijd van een leien dakje is gelopen.

In zijn talk “Tech regrets at Spectrum" leidde hij ons door het verhaal van de initiële architecturale keuzes bij Spectrum, wat er fout liep en welke lessen hij en zijn team daaruit getrokken hebben. Zo zou mobile first denken voor web de vertaling naar de mobile app een pak makkelijker hebben gemaakt. Een ervaring geoptimaliseerd voor mobile op desktop gebruiken is verdraagbaar, maar omgekeerd niet. Als ze bovendien van in het begin react-native-web hadden gebruikt, zou het maken van een React Native app nu een pak minder tijd in beslag nemen. Daarom is het volgens Max een goed idee om vooruit te denken en te optimaliseren voor aankomende veranderingen.

Spectrum is daar het ideale voorbeeld van. De initiële aanzet was opgesteld met Create React App. Voor SEO optimalisatie hadden ze SSR (Server Side Rendering) nodig. Ze moesten de afweging maken tussen verdergaan met wat ze al hadden -en dus een eigen serverside renderer bouwen- of kiezen voor Next.js. Ze kozen voor hun eigen implementatie. Doordat ze zelf alle logica en architectuur moesten voorzien om alles performant te houden, hebben ze veel tijd verloren.

Next.js zou veel van die dingen makkelijker hebben gemaakt. Als Max en zijn team opnieuw mochten kiezen, zou de keuze snel gemaakt zijn. Daaruit leren wij dat je dus best bestaande oplossingen gebruikt voor problemen waar je zelf nog geen kennis van hebt.

Daartegenover staat dat er bestaande oplossingen kunnen zijn, maar dat de community soms te klein is om de keuze ervoor te valideren. Het Spectrum-team koos voor RethinkDB, omdat dit changefeeds out of the box aanbiedt. Aangezien Spectrum een chatapplicatie is, betekende dit voor hen dat ze zelf geen PubSub-systeem hoefden te schrijven. Achteraf gezien bleken de changefeeds niet echt schaalbaar. Ze hadden veel database storingen en het debuggen bleek moeilijk omdat er niet veel documentatie of mensen met dezelfde problemen waren.

Hun keuze voor React Native Web en Next.js voor SSR houden steek dankzij de community size. Ook het feit dat deze in grotere bedrijven gebruikt worden, speelt zeker een rol. Hadden ze eerder naar de community van RethinkDB gekeken, hadden ze kunnen inschatten dat RethinkDB geen ideale match zou zijn.

Weeg daarom altijd je doorslaggevende architecturale keuzes goed af als het om de core technologieën gaat.
 
 

Wat maakt een goeie Developer Experience?

Peggy Rayzis van Apollo GraphQL bracht met haar talk “The GraphQL developer experience” dieper inzicht in wat er precies voor zorgt dat developers positieve feedback geven over werken met GraphQL en alle aanverwante tools. Als leidraad gebruikte ze de reacties die ze op haar Twitteroproep kreeg. Ze vroeg aan haar volgers wat voor hen belangrijk is op DX-vlak. Daaruit kwamen drie zaken naar voor:

  1. Niet opdringerig: de focus ligt op het schrijven van code, niet op tool pleasing.
  2. Voorspelbaarheid: hints helpen je sneller op weg.
  3. Onmiddellijke feedback: je krijgt een waarschuwing als iets niet goed zit.

Programmeurs houden van tools die problemen oplossen. GraphQL biedt een oplossing omdat data ophalen in React niet altijd de beste ervaring blijkt te zijn. Tools zoals The GraphQL Playground (Graphiql) en VSCode plugins zoals Apollo GraphQL zorgen ervoor dat een instant feedback loop mogelijk wordt. Doordat GraphQL gezien kan worden als een contract tussen front-end en back-end, is er meer vertrouwen als er changes gebeuren aan gelijk welk onderdeel van de app. Live previews en GraphQL code hinting / linting brengen je op tijd op de hoogte als iets niet meer klopt.

Bij Marlon proberen we al deze tips en tricks toe te passen. Voor enkele van onze laatste nieuwe projecten, zoals de Toyota Car Configurator, de VDAB planningstool en Be-Mobile​​​​​​​, werkten we onder andere met GraphQL, automagisch gegenereerde component documentatie dankzij Storybook, Prettier voor code formatting…

In team meetings worden alle voorstellen, van zowel eigen tools als andere DX-tools, besproken en wegen we af of de DX en UX nog in balans zijn. De ideale manier om de Marlon Javascript Developer Experience steeds top te houden.
Live previews en GraphQL code hinting / linting in GraphQL tools
Vacature Javascript Developer

Ervaar onze developer experience first-hand

Heb je zelf een passie voor JS, een oog voor goede DX en UX en kennis van React of React Native? Ben je bovendien op zoek naar een nieuwe uitdaging? Wij zijn vragende partij! Kom gerust eens langs voor een babbel in ons kantoor te Gent.

Check onze vacature