React Native v3 - Frontend Masters

Kadi, Expo

npx create-expo-app

npx - Allows users to execute a command from an npm package

Expo

Expo is a React Native framework. The React team now recommends using Expo to build RN projects.

Vanilla React Native ships with the ability to run React code on a native iOS or Android device but it’s missing many core features like navigation, push notifications, accessing the camera, etc. It’s also tedious to build native modules so the more community sharing possible the better the ecosystem.

Expo Go

Expo is the lightweight sandbox app for building prototypes before moving onto ‘development builds’.

In the beginning of a project when you’re adding a lot of packages, it makes sense to bundle with Expo Go instead of the development build so that each change doesn’t rebuild a whole new build.

Adding packages

After adding packages, you must rebuild if you’re using development builds as expo will not recompile with the added modules.

Components

Display points

Native unit of size

Pressable

A more extendable interactive component for press gestures. Has an onPressIn and ‘onPressOut` methods called when touch is engaged or released.

ScrollView

If you iterate over a list of components, you should use a FlatList and not a ScrollView.

<ScrollView style={styles.container} contentContainerStyle={styles.contentContainer} stickyHeaderIndices={[0]} > <TextInput value={value} style={styles.textInput} onChangeText={setValue} placeholder="E.g Coffee" onSubmitEditing={handleSubmit} returnKeyType="done" /> {shoppingList.map((item) => ( <ShoppingListItem name={item.name} key={item.id} /> ))} </ScrollView>

Flatlist

Doesn’t render items far outside the view.

<FlatList data={shoppingList} renderItem={({ item }) => <ShoppingListItem name={item.name} />} style={styles.container} ListHeaderComponent={() => ( <TextInput placeholder="E.g. Coffee" style={styles.textInput} value={value} onChangeText={(value) => setValue(value)} returnKeyLabel="done" onSubmitEditing={() => handleSubmit()} /> )} ></FlatList>

KeyboardAwareScrollView

For views with keyboard inputs, it’s nice to have the keyboard not cover the input. The library react-native-keyboard-aware-scroll-view handles this by sliding the view when the keyboard opens.

Styling

Array of styles

<View style={[styles.itemContainer, isDefined ? styles.definedStyle : undefined]} ></View>

Flexbox

flex: 1

flex: 1 is basically saying: fill all available space. So if something is too long or too big, make sure both the item and parent can expand using flex: 1

Hooks

useEffect

Async function in synchronous useEffect? Just define the function within the useEffect.

useEffect(() => { const fetchInitial = async () => { const data = await getFromStorage(storageKey); if (data) { setShoppingList(data); } }; fetchInitial(); }, []);

useRef

Animation

Layout animation

LayoutAnimation is a React Native package that enable simple, full-page animations between state changes. It animates UI from one state to the next by calling it immediately before a state change.

Haptics

Push Notifications

Can only ask for permissions once.

By default, if the app is open the notification won’t happen unless foreground notifications are configured.

await Notifications.scheduleNotificationAsync({ content: { title: "I'm a notification from your app! 📨", }, trigger: { seconds: 5 /* can trigger after any amount of time */, }, });

Intermediate React Native

Entry point

With expo-router, the entry point for the app is in the node_modules folder. Some libraries like Sentry require the app component to be wrapped. In order to do this, you must copy the entry point locally and change its location in package.json.

Expo Router

App folder

Nothing should be within the folder that is not a screen or layout

Path alias

In order to do away with the complicated import theme from "../../../../../theme”; imports it’s possible to replace it with import theme from "@/theme”; with Typescript.

/* tsconfig.json */ { "extends": "expo/tsconfig.base", "compilerOptions": { "strict": true, "paths": { "@/*": ["./*"] } } }

State Management Library

Will take care of persisting data between sessions with local storage automatically.