Bijna alles en iedereen gebruikt taal. Kort gezegd zou je kunnen stellen dat mensen gebruik maken van taal om drie redenen: om te communiceren (communicatie), zich uit te drukken (expressie) en de werkelijkheid te beschrijven (conceptualisatie). Er zijn veel verschillende talen, maar toch voldoen talen gemiddeld genomen aan deze drie functies, of het nou gaat over Swahili, CSS of gebarentaal. Een belangrijke eigenschap van taal is dat het een aantal gemeenschappelijke erkende regels volgt, maar tegelijkertijd fluïde is: het past zijn regels continu aan om te voldoen aan de veranderende behoeften van haar gebruikers.
Sinds de komst van computers en ontwikkeling van verschillende ICT-technologieën is er behoefte ontstaan naar taal die het mogelijk maakt om als mens, maar ook als technologie, onderling te communiceren. Neem bijvoorbeeld HTML, een programmeer-taal die de mens in staat stelt te communiceren met computers zodat er een hiërarchische, informatieve website ontstaat op het internet. Omdat de expressieve kant van HTML tekort schoot en gebruikers de behoefte kregen om visueel spannendere websites met kleur en animaties te ervaren ontstonden er talen als CSS en JavaScript om hieraan te voloen. Behoefte naar websites met meer visuele uitdaging, en de trend naar steeds complexere internet-applicaties is niet zo gek als je nagaat dat de gemiddelde persoon in de VS per dag meer dan 2 uur op zijn/haar mobiele telefoon en meer dan 4 uur achter een PC bevindt.
Fast-forward naar 2020: welkom in de wereld waarin platte HTML-websites plaatsgemaakt hebben voor websites die draaien op component-based React websites waar de animaties, kleuren en interacties je om de oren vliegen. Complexere, visueel uitdagendere web applicaties voor verschillende multimedia apparatuur hebben als gevolg dat code: steeds complexer en omvangrijker wordt, geschikt moet zijn voor een grote verscheidenheid aan apparaten en schermgrootten, en steeds vaker wordt geschreven in groter wordende teams. Het is daarom niet onverwachts dat er behoefte is ontstaan naar een programmeertaal die beter aansluit bij de nieuwe behoeften van webontwikkelaars. Styled-components zijn een goed voorbeeld van een taal die uit deze behoefte is ontwikkeld.
Styled-components
Styled-components zijn een van de laatste ontwikkelingen op het gebied van component-based styling. Het is een 'CSS-in-JS Library' die webontwikkelaars de mogelijkheid biedt om styling toe te passen in de vorm van componenten, welke in de React-template worden ge-rendered zonder dat deze gekoppeld hoeven te worden aan een geassocieerde CSS class. Kort gezegd voldoen Styled-components aan: expressieve (CSS), communicatieve (explicietere & beknopte naamgevingen) en conceptuele (koppeling componenten & styling ) behoeften die voortvloeien uit de React-community.
Ter illustratie: In het verleden zou een typisch gestyled React-component de volgende code aannemen wanneer men hiervoor CSS-classes zou gebruiken.
<h2 className="title primary">Hello World</h2>h2.SubTitle{font-size: 2em;color: green;& .primary {color: red;}}
Bij het gebruik van Styled-components is de zelfde output te behalen door de volgende code:
const Subtitle = styled.h2`font-size: 2em;color: ${props => props.primary ? 'red' : 'green'};`<Subtitle primary>Hello World</Subtitle>
Voordelen & Uitdagingen
Het verschil in de hierboven beschreven code kan worden samengevat in de volgende voordelen die het gebruik van Styled-components met zich meebrengt:
- Minder code in de template: gebruik van Styled-components biedt de mogelijkheid om conditionele styling logica vanuit de template weg te abstraheren naar een styling bestand, en deze te vervangen met enkel de styling props.
- Explicietere code: Voorbij is de tijd van 20 <div>'s en <span>'s in een component template met daarin het reptetieve className={...} om te refereren naar één van de vele CSS-classes. Door gebruik te maken van Styled-components importeert men enkel een Styled component met een beschrijvende naam zoals: <RedListContainer/>. Dit scheelt code en is explicieter dan <div className={Styled.redListContainer}.
- Native mobile ondersteuning: Styled components biedt ontwikkelaars de flexibiliteit die ze gewend zijn van CSS voor zowel React als React Native, en kan dus cross-platform worden ingezet voor het stylen van componenten.
Toch brengt het gebruik van Styled-components enkele uitdagingen met zich mee aan de ontwikkelingskant. Wanneer er een groot aantal verschillende Styled-components wordt gebruikt in een component heeft dit een lange import-lijst als gevolg bovenin het component. Ook kan de naamgeving van Styled-components worden overgelaten aan de ontwikkelaar. Wanneer er veel unieke Styled-components worden gebruik in een React-component heeft dit als gevolge dat naamgeving al snel verwarrend en maakt. Bijvoorbeeld: <RedContainerWrapperBig> vs <RedContainerWrapperBigMarginEight/> vs <RedContainerWrapperBigMarginTen/>. Dit bemoeilijkt de conceptuele functie die een effectieve taal heeft, omdat de gebruikers niet langer gemakkelijk een gemeenschappelijk idee kunnen vormen van datgene dat wordt beschreven door de naam.
In het geval dat veel unieke Styled-components benodigd zijn in een component vergt dit veel heen-en-weer switchen tussen het styling bestand en het React-component gedurende het coderen. Ook wordt snel onderscheid maken tussen standaard Styled-components zoals <View/> of <Text/> en custom Styled-components als <ViewRed/> en <BigText/> bemoeilijkt wanneer deze in grote getale afwisselend worden gebruikt binnen één component.
'Import as * as Styled from'
Wanneer we bij Humanoids Styled-components gebruiken in een React-component definiëren we eerst dit Styled-component in een -.styled.ts bestand. Het onderstaande Floating Action Button component is hiervan een goed voorbeeld:
├── floating-action-button│ ├── FloatingActionButton.styled.ts│ └── FLoatingActionButton.tsx
In dit bestand definiëren we alle Styled-components en gebruiken hierbij een beschrijvende, beknopte naam (beginnende met een hoofdletter) waarna we deze exporteren:
export const ButtonView = styled.View`align-items: center;background-color: ${(props: Props) =>props.disabled ? color.secondaryDisabledLight: color.primary500};border-radius: 50px;box-shadow: ${(props: Props) =>props.disabled ? 'none' : shadow.elevation4dp};elevation: ${(props: Props) => (props.disabled ? 0 : 4)};flex: 1;justify-content: center;`export const ButtonSize = styled.View`height: 56px;width: 56px;`export const MiniButtonSize = styled.View`height: 40px;width: 40px;`
Vervolgens worden al deze Styled-components geïmporteerd in een React-component in één regel code. Wanneer deze Styled-components afzonderlijk zouden worden geïmporteerd zou dit significant meer code vergen.
import React from 'react'import { TouchableNativeFeedback } from 'react-native'import * as Styled from './FloatingActionButton.styled'
Deze manier van importeren heeft ook als gevolg dat de ontwikkelaar vervolgens in het React-component <Styled. kan typen, waarna de totale lijst aan geassocieerde Styled-components zichtbaar wordt binnen het React-component. Dit scheelt wisselen tussen het styling bestand en het React-component en maakt duidelijk onderscheid tussen custom Styled-components (via het 'Styled.' label) en default Styled-components (in dit geval een TouchableNativeFeedback).