import { useState, useEffect } from 'react';
import { View, Text, ActivityIndicator, FlatList } from 'react-native';
function UserList() {
const [users, setUsers] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
fetchUsers();
}, []);
const fetchUsers = async () => {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/users');
if (!response.ok) {
throw new Error('网络请求失败');
}
const data = await response.json();
setUsers(data);
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
};
if (loading) {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<ActivityIndicator size="large" color="#007AFF" />
</View>
);
}
if (error) {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text style={{ color: 'red' }}>错误: {error}</Text>
</View>
);
}
return (
<FlatList
data={users}
keyExtractor={item => item.id.toString()}
renderItem={({ item }) => (
<View style={{ padding: 15, borderBottomWidth: 1, borderBottomColor: '#eee' }}>
<Text style={{ fontSize: 16, fontWeight: 'bold' }}>{item.name}</Text>
<Text style={{ color: '#666' }}>{item.email}</Text>
</View>
)}
/>
);
}
import { useState } from 'react';
import { View, TextInput, TouchableOpacity, Text, Alert } from 'react-native';
function CreateUser() {
const [name, setName] = useState('');
const [email, setEmail] = useState('');
const [loading, setLoading] = useState(false);
const handleSubmit = async () => {
if (!name || !email) {
Alert.alert('错误', '请填写所有字段');
return;
}
setLoading(true);
try {
const response = await fetch('https://jsonplaceholder.typicode.com/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
name,
email
})
});
if (!response.ok) {
throw new Error('创建失败');
}
const data = await response.json();
Alert.alert('成功', `用户创建成功,ID: ${data.id}`);
setName('');
setEmail('');
} catch (error) {
Alert.alert('错误', error.message);
} finally {
setLoading(false);
}
};
return (
<View style={{ padding: 20 }}>
<TextInput
style={{
borderWidth: 1,
borderColor: '#ddd',
padding: 10,
marginBottom: 10,
borderRadius: 5
}}
placeholder="姓名"
value={name}
onChangeText={setName}
/>
<TextInput
style={{
borderWidth: 1,
borderColor: '#ddd',
padding: 10,
marginBottom: 20,
borderRadius: 5
}}
placeholder="邮箱"
value={email}
onChangeText={setEmail}
keyboardType="email-address"
/>
<TouchableOpacity
style={{
backgroundColor: loading ? '#ccc' : '#007AFF',
padding: 15,
borderRadius: 5,
alignItems: 'center'
}}
onPress={handleSubmit}
disabled={loading}
>
<Text style={{ color: '#fff', fontWeight: 'bold' }}>
{loading ? '提交中...' : '提交'}
</Text>
</TouchableOpacity>
</View>
);
}
const updateUser = async (id, updates) => {
try {
const response = await fetch(`https://api.example.com/users/${id}`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(updates)
});
const data = await response.json();
return data;
} catch (error) {
console.error('更新失败:', error);
throw error;
}
};
const deleteUser = async (id) => {
try {
const response = await fetch(`https://api.example.com/users/${id}`, {
method: 'DELETE'
});
if (response.ok) {
Alert.alert('成功', '删除成功');
}
} catch (error) {
Alert.alert('错误', '删除失败');
}
};
import axios from 'axios';
import { useState, useEffect } from 'react';
function UserList() {
const [users, setUsers] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
axios.get('https://jsonplaceholder.typicode.com/users')
.then(response => {
setUsers(response.data);
setLoading(false);
})
.catch(error => {
console.error(error);
setLoading(false);
});
}, []);
}
import axios from 'axios';
import AsyncStorage from '@react-native-async-storage/async-storage';
const apiClient = axios.create({
baseURL: 'https://api.example.com',
timeout: 10000,
headers: {
'Content-Type': 'application/json'
}
});
apiClient.interceptors.request.use(
async (config) => {
const token = await AsyncStorage.getItem('token');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
console.log('请求:', config.method.toUpperCase(), config.url);
return config;
},
(error) => {
return Promise.reject(error);
}
);
apiClient.interceptors.response.use(
(response) => {
console.log('响应:', response.status, response.config.url);
return response.data;
},
async (error) => {
if (error.response) {
const { status, data } = error.response;
if (status === 401) {
await AsyncStorage.removeItem('token');
} else if (status === 403) {
Alert.alert('错误', '没有权限');
} else if (status === 500) {
Alert.alert('错误', '服务器错误');
}
return Promise.reject(data);
} else if (error.request) {
Alert.alert('错误', '网络连接失败');
} else {
Alert.alert('错误', error.message);
}
return Promise.reject(error);
}
);
export default apiClient;
import apiClient from './client';
export const userAPI = {
getUsers: () => apiClient.get('/users'),
getUser: (id) => apiClient.get(`/users/${id}`),
createUser: (data) => apiClient.post('/users', data),
updateUser: (id, data) => apiClient.put(`/users/${id}`, data),
deleteUser: (id) => apiClient.delete(`/users/${id}`),
login: (credentials) => apiClient.post('/auth/login', credentials),
register: (data) => apiClient.post('/auth/register', data)
};
import { useState, useEffect } from 'react';
import { userAPI } from './api/user';
function UserList() {
const [users, setUsers] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
loadUsers();
}, []);
const loadUsers = async () => {
try {
const data = await userAPI.getUsers();
setUsers(data);
} catch (error) {
console.error('加载失败:', error);
} finally {
setLoading(false);
}
};
const handleDelete = async (id) => {
try {
await userAPI.deleteUser(id);
setUsers(users.filter(u => u.id !== id));
Alert.alert('成功', '删除成功');
} catch (error) {
Alert.alert('错误', '删除失败');
}
};
}
import { useState, useEffect } from 'react';
function useFetch(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
let isMounted = true;
const fetchData = async () => {
try {
setLoading(true);
const response = await fetch(url);
if (!response.ok) {
throw new Error('请求失败');
}
const json = await response.json();
if (isMounted) {
setData(json);
setError(null);
}
} catch (err) {
if (isMounted) {
setError(err.message);
}
} finally {
if (isMounted) {
setLoading(false);
}
}
};
fetchData();
return () => {
isMounted = false;
};
}, [url]);
return { data, loading, error };
}
function UserList() {
const { data: users, loading, error } = useFetch(
'https://jsonplaceholder.typicode.com/users'
);
if (loading) return <ActivityIndicator />;
if (error) return <Text>错误: {error}</Text>;
return (
<FlatList
data={users}
keyExtractor={item => item.id.toString()}
renderItem={({ item }) => <Text>{item.name}</Text>}
/>
);
}
import { useState } from 'react';
function useAPI(apiFunc) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const execute = async (...args) => {
try {
setLoading(true);
setError(null);
const result = await apiFunc(...args);
setData(result);
return result;
} catch (err) {
setError(err.message);
throw err;
} finally {
setLoading(false);
}
};
return { data, loading, error, execute };
}
function CreateUser() {
const { loading, error, execute } = useAPI(userAPI.createUser);
const handleSubmit = async () => {
try {
const result = await execute({ name: 'John', email: 'john@example.com' });
Alert.alert('成功', `用户创建成功,ID: ${result.id}`);
} catch (error) {
Alert.alert('错误', '创建失败');
}
};
return (
<TouchableOpacity onPress={handleSubmit} disabled={loading}>
<Text>{loading ? '提交中...' : '提交'}</Text>
</TouchableOpacity>
);
}
import { useState } from 'react';
import { View, Image, TouchableOpacity, Text, Alert } from 'react-native';
import { launchImageLibrary } from 'react-native-image-picker';
function ImageUpload() {
const [image, setImage] = useState(null);
const [uploading, setUploading] = useState(false);
const selectImage = () => {
launchImageLibrary(
{
mediaType: 'photo',
quality: 0.8
},
(response) => {
if (response.didCancel) {
return;
}
if (response.errorCode) {
Alert.alert('错误', response.errorMessage);
return;
}
setImage(response.assets[0]);
}
);
};
const uploadImage = async () => {
if (!image) {
Alert.alert('提示', '请先选择图片');
return;
}
setUploading(true);
const formData = new FormData();
formData.append('file', {
uri: image.uri,
type: image.type,
name: image.fileName || 'image.jpg'
});
try {
const response = await fetch('https://api.example.com/upload', {
method: 'POST',
headers: {
'Content-Type': 'multipart/form-data',
},
body: formData
});
const data = await response.json();
Alert.alert('成功', '上传成功');
} catch (error) {
Alert.alert('错误', '上传失败');
} finally {
setUploading(false);
}
};
return (
<View style={{ padding: 20 }}>
{image && (
<Image
source={{ uri: image.uri }}
style={{ width: 200, height: 200, marginBottom: 20 }}
/>
)}
<TouchableOpacity
style={{
backgroundColor: '#007AFF',
padding: 15,
borderRadius: 5,
marginBottom: 10
}}
onPress={selectImage}
>
<Text style={{ color: '#fff', textAlign: 'center' }}>选择图片</Text>
</TouchableOpacity>
<TouchableOpacity
style={{
backgroundColor: uploading ? '#ccc' : '#34C759',
padding: 15,
borderRadius: 5
}}
onPress={uploadImage}
disabled={uploading || !image}
>
<Text style={{ color: '#fff', textAlign: 'center' }}>
{uploading ? '上传中...' : '上传图片'}
</Text>
</TouchableOpacity>
</View>
);
}
import React, { useState } from 'react';
import {
View,
Text,
TextInput,
TouchableOpacity,
StyleSheet,
Alert,
ActivityIndicator
} from 'react-native';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { userAPI } from '../api/user';
function LoginScreen({ navigation }) {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [loading, setLoading] = useState(false);
const handleLogin = async () => {
if (!email || !password) {
Alert.alert('错误', '请填写所有字段');
return;
}
setLoading(true);
try {
const response = await userAPI.login({ email, password });
await AsyncStorage.setItem('token', response.token);
await AsyncStorage.setItem('user', JSON.stringify(response.user));
navigation.replace('Home');
} catch (error) {
Alert.alert('登录失败', error.message || '请检查用户名和密码');
} finally {
setLoading(false);
}
};
return (
<View style={styles.container}>
<Text style={styles.title}>登录</Text>
<TextInput
style={styles.input}
placeholder="邮箱"
value={email}
onChangeText={setEmail}
keyboardType="email-address"
autoCapitalize="none"
/>
<TextInput
style={styles.input}
placeholder="密码"
value={password}
onChangeText={setPassword}
secureTextEntry
/>
<TouchableOpacity
style={[styles.button, loading && styles.buttonDisabled]}
onPress={handleLogin}
disabled={loading}
>
{loading ? (
<ActivityIndicator color="#fff" />
) : (
<Text style={styles.buttonText}>登录</Text>
)}
</TouchableOpacity>
<TouchableOpacity onPress={() => navigation.navigate('Register')}>
<Text style={styles.link}>还没有账号?立即注册</Text>
</TouchableOpacity>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 20,
justifyContent: 'center',
backgroundColor: '#fff'
},
title: {
fontSize: 32,
fontWeight: 'bold',
marginBottom: 40,
textAlign: 'center'
},
input: {
borderWidth: 1,
borderColor: '#ddd',
padding: 15,
borderRadius: 8,
marginBottom: 15,
fontSize: 16
},
button: {
backgroundColor: '#007AFF',
padding: 15,
borderRadius: 8,
marginTop: 10
},
buttonDisabled: {
backgroundColor: '#ccc'
},
buttonText: {
color: '#fff',
textAlign: 'center',
fontSize: 16,
fontWeight: 'bold'
},
link: {
color: '#007AFF',
textAlign: 'center',
marginTop: 20
}
});
export default LoginScreen;