JavaScript XML, permets d'entrelaçer des balises avec le code JavaScript et d'encapsuler les responsabilités via les components
Un seul élément à la racine, sinon utiliser un conteneur ou un fragment
return <Text ... >Coucou!</Text>
// ou
return <> <Text>Coucou!</Text> <Text>Plus de texte...</Text> </>
On peut formatter le retour du JSX sur plusieurs lignes en encadrant de ( )
return (
<>
<Text>Coucou!</Text>
<Text>Plus de texte...</Text>
...
</>
)
JSX n'est pas exactement du HTML, il faut absolument fermer toutes les balises
<Image></Image>
...
<Button />
<Image />
<TextInput />
<Switch />
...
Les attributs HTML et les propriétés CSS utilisent la nomenclature camelCase className, onClick, backgroundColor, etc.
<View style={{ justifyContent: 'center', flexDirection: 'row'}}>
<Button title='Click me!' onPress={ () => Alert.alert('Clicked :)')}/>
</View>
Un component est défini par une fonction dont le nom commence par une MAJUSCULE, qui retourne du JSX
function FormField() {
return (
<View>
<Text>Label:</Text>
<TextInput />
</View>
)
}
// Usage
<FormField></FormField>
<FormField></FormField>
// ou
<FormField />
<FormField />
Les 2 accolades {{ ... }}
intègrent un objet JavaScript
function FormField() {
return (
<View style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }}>
<Text>Label:</Text>
<TextInput style={{ borderWidth: 1, flexGrow: 1 }} />
</View>
)
}
Les components peuvent recevoir des paramètres via les props
function FormField(props) {
return (
<View style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }}>
<Text>{ props.label } :</Text>
<TextInput style={{ borderWidth: 1, flexGrow: 1 }} />
</View>
)
}
// Usage
<FormField label="a"></FormField>
<FormField label="b"></FormField>
<FormField label="c" />
On peut simplifier l'accès aux props via le destructuring
function FormField({ label }) {
return (
<View style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }}>
<Text>{ label } :</Text>
<TextInput style={{ borderWidth: 1, flexGrow: 1 }} />
</View>
)
}
On peut fournir du contenu au component, accessible via la prop children
function FormField({ label, children }) {
return (
<View style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }}>
<Text>{ label } :</Text>
{ children }
</View>
)
}
// Usage
<FormField label="Text">
<TextInput style={{ borderWidth: 1, flexGrow: 1 }} />
</FormField>
<FormField label="Switch">
<Switch />
</FormField>
// ...
{
[
{
label: 'Text',
field: <TextInput style={{ borderWidth: 1, flexGrow: 1 }} />
},
{
label: 'Switch',
field: <Switch />
}
].map( ({label, field}) => (
<FormField key={ label } label={ label } >
{ field }
</FormField>
))
}
On peut également intégrer la logique à l'intérieur du JSX via les accolades { ... }
. On peut intégrer des expressions JS dans le JSX, donc des énoncés de code qui retournent une valeur.
function FormField({ label, children }) {
function format() {
if (label) {
return <Text>{ label.toUpperCase() } :</Text>
}
}
return (
<View style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }}>
{ /* Ternaire */ }
{ label ? <Text>{ label.toUpperCase() } :</Text> : null }
{ /* Court circuit */ }
{ label && <Text>{ label.toUpperCase() } :</Text> }
{ /* Appel de fonction */ }
{ format() }
{ children }
</View>
)
}
// Usage
<FormField>
<Switch />
</FormField>
On retrouve la plupart des propriétés CSS en React Native. On utilise 2 unités de mesure les DIP fontSize: 24
par défaut, et les % width: '50%'
📚 Styles
On utilise Flexbox qui permets de distribuer des éléments sur un axes et de contrôler leur positionnement via plusieurs propriétés CSS.
📚 Flexbox
React Native propose un ensemble de components par défaut, mais ils ne répondent pas nécessairement à tous les besoins. Il est commun d'utiliser des librairies de composants pour accélérer et uniformiser la mise en place de l'interface de l'application.
📚 Référence components et attributs
Expo intègre une librairie d'icônes exhaustive et facile d'utilisation
import { FontAwesome5 } from '@expo/vector-icons';
// ...
<FontAwesome5 name="smile" size={24} color="black" />