Ami egy weboldal esetében a CSS, az React Native és React esetében is StyleSheet vagy styled-components. Ez a kettő leggyakoribb módja annak, hogy a képernyő elemekhez „css” stílust rendeljünk.
Nagyon fontos, hogy NEM CSS-ről van szó. Amit „css”-ként adunk meg az valójában JSX. A JSX-ről itt olvashatsz bővebben.
StyleSheet

A stílusok használatának van egy React Native által biztosított egyszerű és kényelmes módja. Ez a StyleSheet, ami a react-native csomag része:
import { StyleSheet } from "react-native";
Ennek a create metódusával hozunk létre stílus objektumot (általában a fájl legvégén), amiben minden egyes elem egy objektum. És ezeken az objektumokon belül adjuk meg a formázásokat. Például:
const styles = StyleSheet.create({
container: {
flex: 1,
marginTop: StatusBar.currentHeight,
},
searchContainer: {
padding: 16,
},
listContainer: {
flex: 1,
backgroundColor: "blue",
padding: 16,
},
});
Aztán így rendeljük a komponensekhez, UI elemekhez a stílusokat:
<SafeAreaView style={styles.container}>
<View style={styles.searchContainer}>
<Searchbar />
</View>
<View style={styles.listContainer}>
<RestaurantInfoCard />
</View>
</SafeAreaView>
styled-components

Van egy másik kedvelt megoldás is. A styled-components használata. Hasznos linkek:
Telepítés
npm install --save styled-components
vagy
yarn add styled-components
A telepítés során az oldal azt javasolja, hogy az olyan csomagkezelők (pl. Yarn), amik támogatják a package.json fájlban a „resolutions” kulcsot, egy ilyen bejegyzést is célszerű elhelyezni a package.json fájlban:
"resolutions": {
"styled-components": "^5"
},
Ez megakadályozza az abból fakadó hibákat, ha a projekten belül több más verziójú styled-components csomagot használunk.
Használat
Amit importálunk:
import styled from "styled-components/native";
Példa a használatra:
const Title = styled.Text`
padding: 16px;
color: red;
`;
Létrehoztunk egy Title „komponenst”, ami egy react-native Text elemet jelent. A formázást pedig template sztringként adtuk meg. Látható, hogy kell használni a mértékegységet is (különben a konzol hibát fog jelezni), mert ez a háttérben átfordítódik a React Native számára érthető értékké. De ezzel a webfejlesztők is jobban eligazodnak, akik ismerik a CSS-t. Ráadásul a styled megérti a React-ben használt „css” tulajdonságokat és a CSS-ben használtakat is. Tehát például működik a backgroundColor és a background-color is.
Van egy oldal, ahol ki lehet próbálni ezt az átalakítást élőben is, ami valójába a háttérben zajlik:
Korábban a komponenshez rendelt style tulajdonsággal így nézett ki a dolog:
<Text style={styles.title}>{name}</Text>
A styled-components használatával pedig így:
<Title>{name}</Title>
Beszédesebb is a Text helyett használt Title, valamint nem kell megadni a style tulajdonságot sem. Másfelől egy módja annak, hogy igazán CSS szerű stílusokat gyártsunk a React Native-ban.
Konkrét példa
Ez volt StyleSheet stílusokkal egy Card komponens:
<Card elevation={5} style={styles.card}>
<Card.Cover key={name} source={{ uri: photos[0] }} style={styles.cover} />
<Text style={styles.title}>{name}</Text>
</Card>
styled-components megoldás. Ez a stílus definíció:
const RestaurantCard = styled(Card)`
background-color: white;
`;
const RestaurantCardCover = styled(Card.Cover)`
padding: 20px;
background-color: white;
`;
const Title = styled.Text`
padding: 16px;
color: red;
`;
Ez pedig az alkalmazás:
<RestaurantCard elevation={5}>
<RestaurantCardCover key={name} source={{ uri: photos[0] }} />
<Title>{name}</Title>
</RestaurantCard>
Amit meg lehet még figyelni, hogy a színeket most már nem sztringként kell megadni, hanem mint a css-ben:
background-color: white;
Ha egy származtatott értéket akarunk használni, akkor azt pedig ugyanúgy tesszük, ahogy a template sztringeknél mindig. $ és { } használatával:
const SafeArea = styled(SafeAreaView)`
flex: 1;
margin-top: ${StatusBar.currentHeight}px;
`;
Hozzáteszem, hogy ha ezt így hagyom, akkor kapok egy hibaüzenetet a konzolban iOS esetén: JSON value ‘px’ of type NSString cannot be converted to a ABI45_0_0YGValue.
Ez azért van, mert a StatusBar-nak a currentHeight tulajdonsága iOS esetén nem értelmezett, ezért null értékkel tér vissza. Ezért a margin-top értéke ez lenne: nullpx. Ezt úgy lehet megoldani, hogy ha a StatusBar.currentHeight nem null, akkor van normális érték. Egyébként pedig legyen 0 az értéke, ami már értelmezhető (0px):
const marginTopValue = StatusBar.currentHeight !== null ? StatusBar.currentHeight : 0;
const SafeArea = styled(SafeAreaView)`
flex: 1;
margin-top: ${marginTopValue}px;
`;
Vagy, nem is kell külön változó erre:
const SafeArea = styled(SafeAreaView)`
flex: 1;
margin-top: ${StatusBar.currentHeight !== null ? StatusBar.currentHeight : 0}px;
`;
Még másképpen:
const SafeArea = styled(SafeAreaView)<code>
flex: 1;
${StatusBar.currentHeight && <span style="background-color: initial; font-family: inherit; font-size: inherit; color: var(--nv-text-color); font-weight: var(--bodyfontweight); letter-spacing: var(--bodyletterspacing); text-transform: var(--bodytexttransform);">`</span>margin-top: ${StatusBar.currentHeight}px`};
</code>`;
Azt jelenti, hogy ha a StatusBar.currentHeight-nek van értéke, akkor állítsa csak be a margin-top tulajdonságot.
Téma
A styled-components azzal teszi egységessé a stílusokat, hogy lehetővé teszi a témák használatát. Biztosít nekünk egy <ThemeProvider> wrapper komponenst. Ez a komponens ad egy témát az összes olyan React komponensnek, ami a <ThemeProvider>…</ThemeProvider> tag-ek közé kerül. Ezt a context API segítségével teszi. Másképpen megfogalmazva a ThemeProvider olyan, mint egy globális state, rajta keresztül minden olyan React elem hozzáfér a témához, amit a ThemeProvider közrezár.
A téma készítésének egy külön bejegyzést szenteltem.