Skip to content

Commit be09de9

Browse files
authored
546-react-native-with-expo-simon-grimm (#546)
* draft: cwcc react-native on expo * update cover * update expo post
1 parent 10cca0b commit be09de9

File tree

2 files changed

+220
-0
lines changed
  • apps/codingcatdev/src
    • lib/components/content
    • routes/(content-single)/(non-course)/podcast/cwcc-1-expo-react-native

2 files changed

+220
-0
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<script lang="ts">
2+
export let url: string;
3+
$: github = url.replace('https://github.com/', '');
4+
</script>
5+
6+
<section class="flex w-full items-center align-middle gap-2 flex-wrap">
7+
<a href={`https://codespaces.new/${github}`} target="_blank">
8+
<img
9+
src="https://github.com/codespaces/badge.svg"
10+
alt="Open in GitHub Codespaces"
11+
style="max-width: 100%;"
12+
/>
13+
</a>
14+
<a href={`https://stackblitz.com/github/${github}`} target="_blank">
15+
<img
16+
alt="Open in StackBlitz"
17+
src="https://developer.stackblitz.com/img/open_in_stackblitz.svg"
18+
/>
19+
</a>
20+
21+
<a href={`https://gitpod.io/#https://github.com/${github}`} target="_blank">
22+
<img alt="Open in Gitpod" src="https://gitpod.io/button/open-in-gitpod.svg" />
23+
</a>
24+
25+
<a href={`https://githubbox.com/${github}`} target="_blank">
26+
<img
27+
alt="Open in CodeSandbox"
28+
src="https://img.shields.io/badge/Open%20in-CodeSandbox-blue?style=flat-square&logo=codesandbox"
29+
/>
30+
</a>
31+
</section>
Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
---
2+
type: podcast
3+
authors:
4+
- alex-patterson
5+
episode:
6+
recording_date: Dec 18, 2023 12:00 PM
7+
season: 3
8+
published: published
9+
podcast: code-with-coding-cat
10+
chapters_done: false
11+
cloudinary_convert: false
12+
cover: https://media.codingcat.dev/image/upload/v1703611617/main-codingcatdev-photo/3_ReactNativeExpo.png
13+
devto:
14+
excerpt: 'Dive into the seamless world of cross-platform app development as we unravel the magic of React Native with Expo, combining power and simplicity for an unparalleled mobile experience.'
15+
guests:
16+
- simon-grimm
17+
hashnode:
18+
picks:
19+
slug: cwcc-1-expo-react-native
20+
sponsors:
21+
spotify:
22+
start: Dec 18, 2023
23+
title: 'Exploring React Native: A Journey into Cross-Platform Delight'
24+
youtube: https://youtube.com/live/xtj5wPgWuf4?feature=share
25+
---
26+
27+
<script>
28+
import OpenIn from '$lib/components/content/OpenIn.svelte'
29+
</script>
30+
31+
<OpenIn url="https://github.com/CodingCatDev/cwcc-expo-react-native-catapp" />
32+
33+
## Introduction
34+
35+
Welcome to a live coding session where we build a [React Native](https://reactnative.dev/) mobile app from scratch using [Expo](https://expo.dev/)! My name is Alex and I'm joined by special guest [Simon Grimm](/guest/simon-grimm), an expert in React Native and mobile development.
36+
37+
In this extensive blog post, we will:
38+
39+
- Set up a React Native development environment with Expo
40+
- Create UI components like buttons, images, links, scroll views etc.
41+
- Implement routing and navigation between screens
42+
- Fetch data and display it in the UI
43+
- Open the camera and image library to select photos
44+
- Deploy the app to mobile devices using Expo Go
45+
46+
So let's get started!
47+
48+
## Full Solution
49+
50+
## Setting up the Development Environment
51+
52+
First, we need to set up a React Native environment on our machines using Expo.
53+
54+
```bash
55+
npx create-expo-app cat-app
56+
```
57+
58+
This scaffolds a new React Native project for us called `cat-app`.
59+
60+
Inside the project, we have an `App.js` file along with other config files. This `App.js` renders the entry component for our app.
61+
62+
We can now start the Expo development server:
63+
64+
```bash
65+
npx expo start
66+
```
67+
68+
And voila! The app opens up in the iOS Simulator. Later, we'll also install the [Expo Go](https://expo.dev/client) app on an actual mobile device.
69+
70+
![App Screenshot](https://media.codingcat.dev/image/upload/h_600/v1703613845/main-codingcatdev-photo/Screenshot_2023-12-26_at_1.03.56_PM.png)
71+
72+
## Creating the Home Screen
73+
74+
Let's start building out the Home screen:
75+
76+
### Displaying the Cat Images
77+
78+
We want to fetch some cat images from an API and display them on the Home screen.
79+
80+
First, we fetch the cat images:
81+
82+
```tsx
83+
const fetchCats = async () => {
84+
const res = await fetch('https://cataas.com/cat?json=true');
85+
return res.json();
86+
};
87+
```
88+
89+
Then we store them in React state and display them in a ScrollView:
90+
91+
```tsx
92+
const index = () => {
93+
const [cats, setCats] = useState<Cat[]>([]);
94+
useEffect(() => {
95+
loadCats();
96+
}, []);
97+
98+
const loadCats = async () => {
99+
const data = await fetch('https://api.thecatapi.com/v1/images/search?limit=10');
100+
const cats: Cat[] = await data.json();
101+
setCats(cats);
102+
};
103+
return (
104+
<ScrollView contentContainerStyle={{ marginBottom: 10 }}>
105+
{cats.map((cat) => (
106+
<Link href={`/${cat.id}`} asChild key={cat.id}>
107+
<TouchableHighlight style={styles.item}>
108+
<Image source={{ uri: cat.url }} style={{ width: '100%', height: 300 }} />
109+
</TouchableHighlight>
110+
</Link>
111+
))}
112+
</ScrollView>
113+
);
114+
};
115+
```
116+
117+
This will display the cat images in a nice scrollable view.
118+
119+
We also added a "Load Cats" button to trigger fetching images:
120+
121+
```tsx
122+
<Button title="Load Cats" onPress={loadCats} />
123+
```
124+
125+
### Adding Navigation Between Screens
126+
127+
We want to navigate to a Details screen when a cat image is tapped.
128+
129+
[Expo Router](https://docs.expo.dev/router/introduction/) makes navigation really easy. We simply wrap the `Image` component in a `Link` to link to the Details screen:
130+
131+
```js
132+
{cats.map(cat => (<Link href={`/details/${cat.id}`}><Imagekey={cat.id}source={{uri: cat.url}}style={{width: 100, height: 100}}/></Link>))}
133+
```
134+
135+
Then we create a `details.js` screen that loads the specific cat details:
136+
137+
```js
138+
export default function Details() {
139+
const { id } = useParams();
140+
const [image, setImage] = useState();
141+
useEffect(() => {
142+
fetchCat(id).then(setImage);
143+
}, []);
144+
return <View>{image && <Image source={{ uri: image.url }} />}</View>;
145+
}
146+
```
147+
148+
When you tap a cat image now, it seamlessly navigates to the Details screen with the tapped cat image loaded!
149+
150+
## Opening the Camera with Expo
151+
152+
Finally, let's allow users to take or select photos using the camera. Expo makes accessing native device capabilities like camera super easy.
153+
154+
We just install the expo-image-picker package:
155+
156+
```sh
157+
npx expo install expo-image-picker
158+
```
159+
160+
And import it in our Modal screen:
161+
162+
```js
163+
import * as ImagePicker from 'expo-image-picker';
164+
export default function Modal() {
165+
const pickImage = async () => {
166+
let result = await ImagePicker.launchImageLibraryAsync();
167+
if (!result.cancelled) {
168+
setImage(result.uri);
169+
}
170+
};
171+
return <Button title="Pick an Image" onPress={pickImage} />;
172+
}
173+
```
174+
175+
That's it! We can now open up the phone's image library, select images and handle them in our React Native code.
176+
177+
## Conclusion
178+
179+
In this post, we:
180+
181+
- Created a React Native app with Expo CLI
182+
- Built out Home, Details and Modal screens
183+
- Added routing and navigation with Expo Router
184+
- Fetched and displayed data from an API
185+
- Opened up the camera picker using Expo APIs
186+
187+
As you can see, Expo simplifies React Native development tremendously allowing us to focus on the app code rather than native platform intricacies.
188+
189+
I hope you enjoyed this post and got an idea of building mobile apps with React Native and Expo! Let me know in [Discord](https://discord.com/invite/fRJTRjR) if you have any other questions.

0 commit comments

Comments
 (0)