Sitemap
AppStitch by Bharat Chhabra

AppStitch by Bharat Chhabra

React Native Developer sharing tutorials, mobile app architecture, Firebase, animations, authentication flows, debugging tips, and production-ready solutions.

🚀 The Smart Way to Call APIs in React Native Using Custom Hooks (2026 Guide)

4 min readJun 30, 2026

--

Stop writing API calls inside your components. Learn how to build a reusable useApi hook with request cancellation using AbortController for clean, scalable, and production-ready React Native applications.

Press enter or click to view image in full size

Why Most React Native Projects Become Difficult to Maintain

Every React Native application communicates with APIs.

Whether you’re building:

  • Authentication
  • E-commerce
  • Social Media
  • Food Delivery
  • Banking
  • Healthcare

Eventually you’ll write something like this:

const HomeScreen = () => {
const [posts, setPosts] = useState([]);
const [loading, setLoading] = useState(false);

useEffect(() => {
const fetchPosts = async () => {
setLoading(true);
const response = await fetch(API_URL);
const result = await response.json();
setPosts(result);
setLoading(false);
};
fetchPosts();
}, []);
return (...);
};

Looks simple.

But imagine doing this inside

  • Home Screen
  • Profile Screen
  • Product Screen
  • Search Screen
  • Wishlist
  • Orders
  • Notifications

Soon your project becomes difficult to manage.

Why API Logic Shouldn’t Live Inside Components

This is one of the biggest mistakes developers make.

Your component now has two responsibilities:

  • Rendering UI
  • Fetching data

This violates the Single Responsibility Principle.

Problems include:

❌ Duplicate code

❌ Difficult debugging

❌ Hard to reuse

❌ Poor testing

❌ Memory leaks

❌ Huge screen components

Instead…

Your component should only display UI.

Your hook should handle networking.

The Better Approach

Instead of this

HomeScreen

├── UI
├── Loading
├── Error
├── Fetch API
├── Parsing
├── Retry
├── Cancellation

We’ll split responsibilities.

HomeScreen
│
▼
useApi Hook
│
▼
Network Request

Now every screen becomes tiny.

Recommended Folder Structure

src
├── api
│ ├── api.ts
│ ├── endpoints.ts
│
├── hooks
│ ├── useApi.ts
│
├── services
│ ├── userService.ts
│
├── screens
│
└── components

Much cleaner.

Building a Reusable useApi Hook

Instead of writing fetch everywhere…

Let’s write it once.

import { useEffect, useState } from 'react';

export const useApi = <T,>(url: string) => {
const [data, setData] = useState<T | null>(null);

const [loading, setLoading] = useState(true);

const [error, setError] = useState<string | null>(null);

useEffect(() => {
const controller = new AbortController();

const fetchData = async () => {
try {
setLoading(true);

const response = await fetch(url, {
signal: controller.signal,
});

if (!response.ok) {
throw new Error('Something went wrong');
}

const result = await response.json();

setData(result);
} catch (err: any) {
if (err.name !== 'AbortError') {
setError(err.message);
}
} finally {
setLoading(false);
}
};

fetchData();

return () => controller.abort();
}, [url]);

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

Why This Hook Is Better

✅ Reusable

✅ Less Code

✅ Easy Testing

✅ Separation of Concerns

Get AppStitch by Bharat Chhabra’s stories in your inbox

Join Medium for free to get updates from this writer.

✅ Production Ready

Request Cancellation with AbortController

One of the most overlooked features in React Native is AbortController.

Imagine this scenario.

User opens:

Product Details

API takes

5 seconds

Before it finishes…

User goes back.

Without cancelling the request…

The API still finishes.

Then React tries to update a component that no longer exists.

This can lead to warnings and unnecessary work.

The Solution

const controller = new AbortController();

fetch(API_URL, {
signal: controller.signal,
});

Cleanup

return () => {
controller.abort();
};

That’s it.

When the component unmounts…

The request is cancelled automatically.

Why AbortController Matters

Imagine a user rapidly switching between screens:

Home

↓

Products

↓

Wishlist

↓

Cart

Without cancellation:

4 requests running

↓

Only Cart is visible

↓

Home request finishes

↓

Products request finishes

↓

Wishlist request finishes

All those network calls were unnecessary.

With AbortController:

Home ❌ Cancelled

Products ❌ Cancelled

Wishlist ❌ Cancelled

Cart ✅ Continues

Only the active request completes.

Using the Hook

Now your screen becomes incredibly clean.

const HomeScreen = () => {
const {
data,
loading,
error,
} = useApi<Post[]>(API_URL);

...
}

No fetch.

No useEffect.

No loading state.

No cancellation logic.

Just UI.

Benefits of This Architecture

✔ Smaller components

✔ Easier maintenance

✔ Better code reuse

✔ Cleaner folder structure

✔ Easier testing

✔ Better scalability

✔ Automatic request cancellation

Final Thoughts

As your React Native application grows, organizing API logic becomes just as important as designing the UI. By moving networking code into a reusable custom hook and using AbortController to cancel unnecessary requests, your components stay focused on presentation while your data layer remains reusable and easy to maintain.

This approach scales far better than placing fetch() calls inside every screen and provides a solid foundation for larger production applications.

🙌 Thank You for Reading!

Thank you for reading until the end. Before you go:

Please consider clapping 👏 and following if you found this article helpful.

If this guide saved you time or helped you improve your React Native architecture, your support motivates me to keep creating practical, production-focused tutorials.

🚀 Connect with AppStitch

🎥 YouTube: https://www.youtube.com/@AppStitch

📝 Medium: https://medium.com/@appstitch.dev

📸 Instagram: https://www.instagram.com/app_stitch

Happy Coding! 💙

--

--

AppStitch by Bharat Chhabra
AppStitch by Bharat Chhabra