Kodax

التعامل مع APIs — أساسيات React Native

التعامل مع APIs في React Native

1. Fetch API

// GET Request
const fetchUsers = async () => {
  try {
    const response = await fetch('https://jsonplaceholder.typicode.com/users');
    const data = await response.json();
    return data;
  } catch (error) {
    console.error('Error:', error);
    throw error;
  }
};

// POST Request
const createUser = async (userData) => {
  try {
    const response = await fetch('https://api.example.com/users', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer YOUR_TOKEN',
      },
      body: JSON.stringify(userData),
    });
    const data = await response.json();
    return data;
  } catch (error) {
    console.error('Error:', error);
    throw error;
  }
};

2. Axios (أسهل وأقوى)

npm install axios
import axios from 'axios';

// إعداد Axios
const api = axios.create({
  baseURL: 'https://api.example.com',
  timeout: 10000,
  headers: {
    'Content-Type': 'application/json',
  },
});

// Interceptors
api.interceptors.request.use(config => {
  // إضافة token
  config.headers.Authorization = `Bearer ${getToken()}`;
  return config;
});

api.interceptors.response.use(
  response => response,
  error => {
    if (error.response?.status === 401) {
      // Token expired - logout
    }
    return Promise.reject(error);
  }
);

// GET
const getUsers = () => api.get('/users');

// POST
const createUser = (data) => api.post('/users', data);

// PUT
const updateUser = (id, data) => api.put(`/users/${id}`, data);

// DELETE
const deleteUser = (id) => api.delete(`/users/${id}`);

3. Custom Hook للـ API

// useFetch.js
import { useState, useEffect } from 'react';

function useFetch(url) {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    const fetchData = async () => {
      try {
        setLoading(true);
        const response = await fetch(url);
        if (!response.ok) throw new Error('Failed to fetch');
        const json = await response.json();
        setData(json);
        setError(null);
      } catch (err) {
        setError(err.message);
        setData(null);
      } finally {
        setLoading(false);
      }
    };

    fetchData();
  }, [url]);

  const refetch = () => {
    setLoading(true);
    fetchData();
  };

  return { data, loading, error, refetch };
}

// الاستخدام
function UsersList() {
  const { data: users, loading, error, refetch } = useFetch(
    'https://jsonplaceholder.typicode.com/users'
  );

  if (loading) return <ActivityIndicator />;
  if (error) return <Text>خطأ: {error}</Text>;

  return (
    <FlatList
      data={users}
      onRefresh={refetch}
      refreshing={loading}
      renderItem={({ item }) => <Text>{item.name}</Text>}
    />
  );
}

4. React Query (الأفضل للمشاريع الكبيرة)

npm install @tanstack/react-query
import { QueryClient, QueryClientProvider, useQuery, useMutation } from '@tanstack/react-query';

const queryClient = new QueryClient();

// في App.js
function App() {
  return (
    <QueryClientProvider client={queryClient}>
      <UsersList />
    </QueryClientProvider>
  );
}

// استخدام useQuery
function UsersList() {
  const { data, isLoading, error, refetch } = useQuery({
    queryKey: ['users'],
    queryFn: () => fetch('/api/users').then(res => res.json()),
    staleTime: 5 * 60 * 1000, // 5 دقائق
  });

  if (isLoading) return <ActivityIndicator />;
  if (error) return <Text>خطأ!</Text>;

  return (
    <FlatList
      data={data}
      renderItem={({ item }) => <Text>{item.name}</Text>}
    />
  );
}

// استخدام useMutation
function CreateUserForm() {
  const mutation = useMutation({
    mutationFn: (newUser) => api.post('/users', newUser),
    onSuccess: () => {
      queryClient.invalidateQueries(['users']);
      Alert.alert('تم إنشاء المستخدم!');
    },
    onError: (error) => {
      Alert.alert('خطأ', error.message);
    },
  });

  const handleSubmit = (data) => {
    mutation.mutate(data);
  };

  return (
    <View>
      {/* Form fields */}
      <TouchableOpacity 
        onPress={() => handleSubmit({ name: 'أحمد' })}
        disabled={mutation.isPending}
      >
        <Text>{mutation.isPending ? 'جاري...' : 'إنشاء'}</Text>
      </TouchableOpacity>
    </View>
  );
}

5. معالجة الأخطاء

function ErrorBoundary({ children }) {
  const [hasError, setHasError] = useState(false);

  if (hasError) {
    return (
      <View style={styles.errorContainer}>
        <Text style={styles.errorText}>حدث خطأ ما!</Text>
        <TouchableOpacity onPress={() => setHasError(false)}>
          <Text>إعادة المحاولة</Text>
        </TouchableOpacity>
      </View>
    );
  }

  return children;
}
اختبر فهمك