Wat is Axios?
Axios is een populaire library om HTTP requests te maken naar een API. Het is een alternatief voor de ingebouwde fetch() functie, maar met meer features.
Waarom Axios?
- Simpeler: Minder code nodig dan fetch()
- Automatisch JSON: Geen .json() nodig
- Error handling: Betere foutafhandeling
- Interceptors: Request/response aanpassen
- Timeout: Ingebouwde timeout support
Installatie
Installeer Axios via npm:
npm install axios
Import
import axios from 'axios';
GET Request - Data Ophalen
Gebruik axios.get() om data op te halen van een API.
Basis Voorbeeld
import { useState } from 'react';
import { View, Pressable, Text, StyleSheet } from 'react-native';
import axios from 'axios';
export default function App() {
const [data, setData] = useState(null);
const fetchData = async () => {
try {
const response = await axios.get('https://jsonplaceholder.typicode.com/users/1');
setData(response.data);
console.log(response.data);
} catch (error) {
console.error('Error:', error);
}
};
return (
<View style={styles.container}>
<Pressable style={styles.button} onPress={fetchData}>
<Text style={styles.buttonText}>Haal Data Op</Text>
</Pressable>
{data && (
<View style={styles.dataContainer}>
<Text style={styles.name}>{data.name}</Text>
<Text>{data.email}</Text>
</View>
)}
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 20,
},
button: {
backgroundColor: '#007AFF',
padding: 15,
borderRadius: 8,
alignItems: 'center',
},
buttonText: {
color: 'white',
fontWeight: 'bold',
},
dataContainer: {
marginTop: 20,
padding: 15,
backgroundColor: '#f5f5f5',
borderRadius: 8,
},
name: {
fontSize: 18,
fontWeight: 'bold',
marginBottom: 5,
},
});
response.data bevat:
response.data- De response body (automatisch parsed als JSON)response.status- Status code (200, 404, etc.)response.headers- Response headers
Lijst Ophalen
import { useState } from 'react';
import { FlatList, View, Text, StyleSheet } from 'react-native';
import axios from 'axios';
export default function UserList() {
const [users, setUsers] = useState([]);
const fetchUsers = async () => {
try {
const response = await axios.get('https://jsonplaceholder.typicode.com/users');
setUsers(response.data);
} catch (error) {
console.error('Error:', error);
}
};
return (
<View style={styles.container}>
<FlatList
data={users}
keyExtractor={(item) => item.id.toString()}
renderItem={({ item }) => (
<View style={styles.userCard}>
<Text style={styles.name}>{item.name}</Text>
<Text>{item.email}</Text>
</View>
)}
/>
</View>
);
}
POST Request - Data Versturen
Gebruik axios.post() om data naar een API te sturen.
Data Verzenden
import { useState } from 'react';
import { View, TextInput, Pressable, Text, Alert, StyleSheet } from 'react-native';
import axios from 'axios';
export default function CreateUser() {
const [name, setName] = useState('');
const [email, setEmail] = useState('');
const createUser = async () => {
try {
const response = await axios.post(
'https://jsonplaceholder.typicode.com/users',
{
name: name,
email: email,
}
);
console.log('Created:', response.data);
Alert.alert('Success', 'User aangemaakt!');
// Reset form
setName('');
setEmail('');
} catch (error) {
console.error('Error:', error);
Alert.alert('Fout', 'Er ging iets mis');
}
};
return (
<View style={styles.container}>
<TextInput
style={styles.input}
placeholder="Naam"
value={name}
onChangeText={setName}
/>
<TextInput
style={styles.input}
placeholder="Email"
value={email}
onChangeText={setEmail}
keyboardType="email-address"
/>
<Pressable style={styles.button} onPress={createUser}>
<Text style={styles.buttonText}>Aanmaken</Text>
</Pressable>
</View>
);
}
const styles = StyleSheet.create({
container: {
padding: 20,
},
input: {
borderWidth: 1,
borderColor: '#ddd',
padding: 12,
borderRadius: 8,
marginBottom: 15,
},
button: {
backgroundColor: '#007AFF',
padding: 15,
borderRadius: 8,
alignItems: 'center',
},
buttonText: {
color: 'white',
fontWeight: 'bold',
},
});
Andere HTTP Methodes
// PUT - Update
await axios.put('https://api.com/users/1', { name: 'Nieuwe Naam' });
// PATCH - Partial Update
await axios.patch('https://api.com/users/1', { email: 'new@email.com' });
// DELETE - Verwijderen
await axios.delete('https://api.com/users/1');
Loading States & Error Handling
Toon loading indicator en errors aan gebruikers.
Met Loading State
import { useState } from 'react';
import { View, Text, ActivityIndicator, StyleSheet } from 'react-native';
import axios from 'axios';
export default function App() {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const fetchData = async () => {
setLoading(true);
setError(null);
try {
const response = await axios.get('https://jsonplaceholder.typicode.com/users/1');
setData(response.data);
} catch (error) {
setError('Er ging iets mis bij het ophalen van data');
console.error('Error:', error);
} finally {
setLoading(false);
}
};
return (
<View style={styles.container}>
{loading && <ActivityIndicator size="large" color="#007AFF" />}
{error && (
<View style={styles.errorBox}>
<Text style={styles.errorText}>{error}</Text>
</View>
)}
{data && !loading && (
<View style={styles.dataContainer}>
<Text>{data.name}</Text>
</View>
)}
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 20,
justifyContent: 'center',
},
errorBox: {
backgroundColor: '#ffebee',
padding: 15,
borderRadius: 8,
borderLeftWidth: 4,
borderLeftColor: '#f44336',
},
errorText: {
color: '#c62828',
},
dataContainer: {
padding: 15,
backgroundColor: '#f5f5f5',
borderRadius: 8,
},
});
Best practices:
- Altijd try-catch gebruiken
- Loading state tonen tijdens request
- Errors tonen aan gebruiker
- finally block voor cleanup
Data Ophalen bij Component Mount
Gebruik useEffect om data automatisch op te halen als component laadt.
import { useState, useEffect } from 'react';
import { View, Text, FlatList, ActivityIndicator, StyleSheet } from 'react-native';
import axios from 'axios';
export default function PostList() {
const [posts, setPosts] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetchPosts();
}, []);
const fetchPosts = async () => {
try {
const response = await axios.get('https://jsonplaceholder.typicode.com/posts');
setPosts(response.data);
} catch (error) {
console.error('Error:', error);
} finally {
setLoading(false);
}
};
if (loading) {
return (
<View style={styles.centered}>
<ActivityIndicator size="large" color="#007AFF" />
</View>
);
}
return (
<FlatList
data={posts}
keyExtractor={(item) => item.id.toString()}
renderItem={({ item }) => (
<View style={styles.postCard}>
<Text style={styles.title}>{item.title}</Text>
<Text style={styles.body}>{item.body}</Text>
</View>
)}
/>
);
}
const styles = StyleSheet.create({
centered: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
postCard: {
backgroundColor: 'white',
padding: 15,
marginVertical: 8,
marginHorizontal: 16,
borderRadius: 8,
shadowColor: '#000',
shadowOpacity: 0.1,
shadowRadius: 3,
elevation: 2,
},
title: {
fontSize: 16,
fontWeight: 'bold',
marginBottom: 5,
},
body: {
fontSize: 14,
color: '#666',
},
});
Volledig Voorbeeld - Todo App met API
import { useState, useEffect } from 'react';
import { View, TextInput, Pressable, Text, FlatList, ActivityIndicator, StyleSheet } from 'react-native';
import axios from 'axios';
const API_URL = 'https://jsonplaceholder.typicode.com/todos';
export default function TodoApp() {
const [todos, setTodos] = useState([]);
const [text, setText] = useState('');
const [loading, setLoading] = useState(true);
useEffect(() => {
fetchTodos();
}, []);
const fetchTodos = async () => {
try {
const response = await axios.get(API_URL + '?_limit=10');
setTodos(response.data);
} catch (error) {
console.error('Error:', error);
} finally {
setLoading(false);
}
};
const addTodo = async () => {
if (!text.trim()) return;
try {
const response = await axios.post(API_URL, {
title: text,
completed: false,
});
setTodos([response.data, ...todos]);
setText('');
} catch (error) {
console.error('Error:', error);
}
};
const toggleTodo = async (id) => {
const todo = todos.find(t => t.id === id);
try {
await axios.patch(`${API_URL}/${id}`, {
completed: !todo.completed,
});
setTodos(
todos.map(t =>
t.id === id ? { ...t, completed: !t.completed } : t
)
);
} catch (error) {
console.error('Error:', error);
}
};
const deleteTodo = async (id) => {
try {
await axios.delete(`${API_URL}/${id}`);
setTodos(todos.filter(t => t.id !== id));
} catch (error) {
console.error('Error:', error);
}
};
if (loading) {
return (
<View style={styles.centered}>
<ActivityIndicator size="large" color="#007AFF" />
</View>
);
}
return (
<View style={styles.container}>
<Text style={styles.title}>Todos</Text>
<View style={styles.inputContainer}>
<TextInput
style={styles.input}
placeholder="Nieuwe todo..."
value={text}
onChangeText={setText}
onSubmitEditing={addTodo}
/>
<Pressable style={styles.addButton} onPress={addTodo}>
<Text style={styles.addButtonText}>+</Text>
</Pressable>
</View>
<FlatList
data={todos}
keyExtractor={(item) => item.id.toString()}
renderItem={({ item }) => (
<View style={styles.todoItem}>
<Pressable
style={styles.todoText}
onPress={() => toggleTodo(item.id)}
>
<Text
style={[
styles.text,
item.completed && styles.completedText,
]}
>
{item.title}
</Text>
</Pressable>
<Pressable onPress={() => deleteTodo(item.id)}>
<Text style={styles.deleteButton}>X</Text>
</Pressable>
</View>
)}
/>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 20,
backgroundColor: '#f5f5f5',
},
centered: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
title: {
fontSize: 32,
fontWeight: 'bold',
marginBottom: 20,
},
inputContainer: {
flexDirection: 'row',
marginBottom: 20,
},
input: {
flex: 1,
borderWidth: 1,
borderColor: '#ddd',
padding: 12,
borderRadius: 8,
backgroundColor: 'white',
marginRight: 10,
},
addButton: {
backgroundColor: '#007AFF',
width: 50,
borderRadius: 8,
justifyContent: 'center',
alignItems: 'center',
},
addButtonText: {
color: 'white',
fontSize: 24,
fontWeight: 'bold',
},
todoItem: {
flexDirection: 'row',
alignItems: 'center',
backgroundColor: 'white',
padding: 15,
borderRadius: 8,
marginBottom: 10,
},
todoText: {
flex: 1,
},
text: {
fontSize: 16,
},
completedText: {
textDecorationLine: 'line-through',
color: '#999',
},
deleteButton: {
color: 'red',
fontSize: 18,
fontWeight: 'bold',
padding: 5,
},
});
Dit voorbeeld toont:
- GET - Todos ophalen bij mount
- POST - Nieuwe todo aanmaken
- PATCH - Todo status updaten
- DELETE - Todo verwijderen
- Loading state met ActivityIndicator
- Error handling met try-catch
Samenvatting
axios.get()
Data ophalen
axios.post()
Data versturen
try-catch
Error handling
useEffect
Data bij mount ophalen
Je hebt nu geleerd:
- Axios installeren en gebruiken
- GET requests om data op te halen
- POST requests om data te versturen
- Loading states en error handling
- Data ophalen bij component mount met useEffect
- Complete CRUD app met API integratie