React Native Tutorial by The Net Ninja - Notes
Nestor Solalinde
Posted on December 13, 2021
Youtube Link: https://www.youtube.com/watch?v=ur6I5m2nTvk&list=PL4cUxeGkcC9ixPU-QkScoRBVxtPPzVjrQ
Repo: https://github.com/iamshaunjp/react-native-tutorial
Documentation: https://reactnative.dev/docs/getting-started
Local folder: E:\NMS\CURSOS\REACT-NATIVE-NINJA\react-native-tutorial
components lib: https://reactnativeelements.com/docs/header
Initial commands – Configuration
Android studio installation: Intel® HAXM installation failed. To install Intel® HAXM follow the instructions found at: https://software.intel.com/android/articles/installation-instructions-for-intel-hardware-accelerated-execution-manager-windows
Expo documentation: https://docs.expo.io/
npm install --global expo-cli
expo init myproject
npm start
Full examples:
Todo App: https://github.com/manolosolalinde/react-native-tutorial/tree/lesson-15
The reviews App: https://github.com/manolosolalinde/react-native-tutorial/tree/lesson-35
Tutorial structure:
lesson-2 to lesson-8
: setup and basics
lesson-9 to lesson-15
: Todo App
React Native Tutorial #10 – Todo App (part 2)
React Native Tutorial #11 – Todo App (part 3)
React Native Tutorial #12 – Alerts
React Native Tutorial #13 – Dismissing the Keyboard
React Native Tutorial #14 – Flexbox Basics
React Native Tutorial #15 – Icons & More Flexbox
lesson-16 to lesson-35
: The reviews App
React Native Tutorial #16 – Starting the Reviews App
React Native Tutorial #17 – Custom Fonts
React Native Tutorial #18 – Global Styles
React Native Tutorial #19 – React Navigation Setup
React Native Tutorial #20 – Stack Navigator
React Native Tutorial #21 – Navigating Around
React Native Tutorial #22 – Passing Data Between Screens
React Native Tutorial #23 – Navigation Options
React Native Tutorial #24 – Drawer Navigation
React Native Tutorial #25 – Custom Header Component
React Native Tutorial #26 – Custom Card Component
React Native Tutorial #27 – Using Images
React Native Tutorial #28 – Background Images
React Native Tutorial #29 – Modals
React Native Tutorial #30 – Formik Forms (part 1)
React Native Tutorial #31 – Formik Forms (part 2)
React Native Tutorial #32 – Validation with Yup
React Native Tutorial #33 – Showing Form Errors
React Native Tutorial #34 – Custom Button Component
React Native Tutorial #35 – Wrap Up
Views, text and styles
Note: React native does not use css. It emulates the idea of css.
Note: Styles are not automatically inherited.
In general views
are used instead of div
.
Due to the lack of DOM, React Native doesn’t use tags like: div, section, span, input, etc. But don’t worry, almost every HTML tag has an equivalent React Native component, so we are able to use the same mindset of the web to develop with React Native components View
, Text
, TextInput
, etc.
Examples
ScrollView, Button, TextInput:
<ScrollView>
<Button title='update state' onPress={clickHandler}/>
<TextInput
multiline
keyboardType='numeric'
placeholder='e.g. John Doe'
onChangeText={()=>setName()}
style={styles.input}/>
<ScrollView/>
Flatlist, touchable component:
<View style={styles.container}>
<FlatList
numColumns={2}
keyExtractor={(item) => item.id}
data={people}
renderItem={({ item }) => (
<TouchableOpacity onPress={()=>pressHandler(item.id)}>
<Text style={styles.item}>{item.name}</Text>
</TouchableOpacity>
)}
/>
</View>
Alert:
// jsx
Alert.alert('OOPS', 'Todo must be over 3 characters long', [
{text: 'Understood', onPress: () => console.log('alert closed') }
]);
Keyboard dismiss:
<TouchableWithoutFeedback onPress={() => {
Keyboard.dismiss();
console.log('dismissed');
}}>
<View style={styles.container}>
<Header />
<View style={styles.content}>
<AddTodo submitHandler={submitHandler} />
<View style={styles.list}>
<FlatList
data={todos}
renderItem={({ item }) => (
<TodoItem item={item} pressHandler={pressHandler} />
)}
/>
</View>
</View>
</View>
</TouchableWithoutFeedback>
Flexbox:
export default function Sandbox() {
return (
<View style={styles.container}>
<Text style={styles.boxOne}>one</Text>
<Text style={styles.boxTwo}>two</Text>
<Text style={styles.boxThree}>three</Text>
<Text style={styles.boxFour}>four</Text>
</View>
);
}
const styles = StyleSheet.create({
container: {
paddingTop: 40,
backgroundColor: '#ddd',
flexDirection: 'row',
justifyContent: 'space-around',
alignItems: 'center',
height: '100%',
},
boxOne: {
flex: 1,
backgroundColor: 'violet',
padding: 10,
},
boxTwo: {
flex: 2,
backgroundColor: 'gold',
padding: 10,
alignSelf: 'flex-end',
},
boxThree: {
flex: 1,
backgroundColor: 'coral',
padding: 10,
},
boxFour: {
flex: 3,
backgroundColor: 'skyblue',
padding: 10,
alignSelf: 'flex-start',
}
});
Icons:
https://docs.expo.io/guides/icons/
import { MaterialIcons } from '@expo/vector-icons';
export default function TodoItem({ pressHandler, item }) {
return (
<TouchableOpacity onPress={() => pressHandler(item.key)}>
<View style={styles.item}>
<MaterialIcons name='delete' size={18} color='#333' />
<Text style={styles.itemText}>{item.text}</Text>
</View>
</TouchableOpacity>
)
}
Fonts:
– Documentation: https://docs.expo.io/guides/using-custom-fonts/?redirected
– Installation:
expo install expo-font @expo-google-fonts/nunito
npm install expo-app-loading
- Example:
import React from 'react';
import AppLoading from 'expo-app-loading';
import Home from './screens/home';
import { useFonts, Nunito_400Regular, Nunito_700Bold } from '@expo-google-fonts/nunito';
export default function App() {
let [fontsLoaded] = useFonts({
Nunito_400Regular,
Nunito_700Bold,
});
if (!fontsLoaded) {
return <AppLoading />;
}
else {
return <Home />;
}
}
lesson-18 – Global Styles:
Just create a file in styles -> global.js and create and do:
(nothing weird)
import { StyleSheet } from 'react-native';
export const globalStyles = StyleSheet.create({
titleText: {
fontSize: 18,
fontWeight: 'bold',
color: '#333',
},
paragraph: {
marginVertical: 8,
lineHeight: 20,
},
container: {
flex: 1,
padding: 20,
},
});
lesson-19 – React Navigation Configuration
# install react-navigation 5.0
npm install @react-navigation/native
npm install @react-navigation/stack
expo install react-native-gesture-handler react-native-reanimated react-native-screens react-native-safe-area-context @react-native-community/masked-view
npm install react-navigation-stack
lesson-20 – Stack Navigator
Installs for react navigator 5.0x:
routes/homeStack.js
:
import React from "react";
import { NavigationContainer } from "@react-navigation/native";
import { createStackNavigator } from "@react-navigation/stack";
import Home from "../screens/home";
import ReviewDetails from "../screens/reviewDetails";
const { Navigator, Screen } = createStackNavigator();
const HomeNavigator = () => (
<Navigator headerMode="none">
{/* //other options: "float", "screen" */}
<Screen name="Details" component={ReviewDetails} />
<Screen name="Home" component={Home} />
</Navigator>
);
export const AppNavigator = () => (
<NavigationContainer>
<HomeNavigator />
</NavigationContainer>
);
And bind it into the App.js root component:
...
import { AppNavigator } from "./routes/HomeStack";
...
if (fontsLoaded) {
return <AppNavigator />;
} else {
...
}
lesson-21 – Example navigation:
export default function Home({ navigation }) {
const pressHandler = () => {
navigation.navigate('ReviewDetails');
// navigation.goBack();
// navigation.push('ReviewDetails');
}
return (
<View style={globalStyles.container}>
<Text style={globalStyles.titleText}>Home Screen</Text>
<Button title='to review details screen' onPress={pressHandler} />
</View>
);
}
React Native Tutorial #22 – Passing Data Between Screens
Navigation documentation: https://reactnavigation.org/docs/params
React Native Tutorial #23 – Navigation Options
https://reactnavigation.org/docs/headers#sharing-common-options-across-screens
React Native Tutorial #24 – Drawer Navigation
npm install @react-navigation/drawer
./routes/drawer.js
import React from 'react';
import { createDrawerNavigator } from '@react-navigation/drawer';
import { NavigationContainer } from '@react-navigation/native';
import { HomeNavigator } from './homeStack'
import { AboutNavigator } from './aboutStack';
const Drawer = createDrawerNavigator();
export const AppDrawer = () => {
return (
<NavigationContainer>
<Drawer.Navigator headerMode="screen" initialRouteName="Home">
<Drawer.Screen name="Home" component={HomeNavigator} />
<Drawer.Screen name="About" component={AboutNavigator} />
</Drawer.Navigator>
</NavigationContainer>
);
}
React Native Tutorial #30 – Formik Forms (part 1)
npm install formik
Formik Example:
import React from 'react';
import { StyleSheet, Button, TextInput, View, Text } from 'react-native';
import { globalStyles } from '../styles/global.js';
import { Formik } from 'formik';
import * as yup from 'yup';
import FlatButton from '../shared/button.js';
const reviewSchema = yup.object({
title: yup.string()
.required()
.min(4),
body: yup.string()
.required()
.min(8),
rating: yup.string()
.required()
.test('is-num-1-5', 'Rating must be a number 1 - 5', (val) => {
return parseInt(val) < 6 && parseInt(val) > 0;
}),
});
export default function ReviewForm({ addReview }) {
return (
<View style={globalStyles.container}>
<Formik
initialValues={{ title: '', body: '', rating: '' }}
validationSchema={reviewSchema}
onSubmit={(values, actions) => {
actions.resetForm();
addReview(values);
}}
>
{props => (
<View>
<TextInput
style={globalStyles.input}
placeholder='Review title'
onChangeText={props.handleChange('title')}
onBlur={props.handleBlur('title')}
value={props.values.title}
/>
{/* only if the left value is a valid string, will the right value be displayed */}
<Text style={globalStyles.errorText}>{props.touched.title && props.errors.title}</Text>
<FlatButton onPress={props.handleSubmit} text='submit' />
</View>
)}
</Formik>
</View>
);
}
Posted on December 13, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.