Services in React Example

React is a powerful JavaScript toolkit for creating user interfaces, particularly single-page apps that require a quick and efficient mechanism to handle UI changes. Understanding how to use services properly is critical for designing robust React apps.

Services in React are used to handle data collection, state management, and other tasks required for constructing scalable apps.

In this article, we will look at the concept of services in React, services in react examples, and go over react services folder.

What Are Services in React?

Services are a React design pattern that abstracts business functionality and data collection from the component layer. This helps to maintain a clear separation of concerns, making the program more maintainable and testable.

Services can be viewed as utilities that offer specialized functionalities, like:

  • Data Fetching: Data fetching is the process of sending HTTP requests to APIs in order to retrieve data.
  • State Management: Managing the application’s global state.
  • Business Logic: Business logic encapsulates sophisticated business rules and computations.

1. Data Fetching Services

Data fetching is one of React’s most prevalent usage cases. Typically, a service is developed to handle HTTP requests from a backend API. This keeps the component code simple and focuses on rendering the UI.

Data Fetching Service Examples

Let’s develop a basic service that retrieves data from a public API. We’ll use the fetch API for this. First, we create a service to handle the API requests.

javascript

// services/apiService.js

const API_URL = "https://jsonplaceholder.typicode.com";

export const fetchUsers = async () => {

try {

const response = await fetch(`${API_URL}/users`);

if (!response.ok) {

throw new Error("Network response was not ok");

}

const data = await response.json();

return data;

} catch (error) {

console.error("Fetch error:", error);

throw error;

}

};

In this example, fetchUsers is an asynchronous function that retrieves user information from the API and returns it. If there is a problem, it will throw an exception.

Next, we apply this service to a React component:

javascript

// components/UserList.js

import React, { useEffect, useState } from "react";

import { fetchUsers } from "../services/apiService";

const UserList = () => {

const [users, setUsers] = useState([]);

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

const [error, setError] = useState(null);

useEffect(() => {

const getUsers = async () => {

try {

const usersData = await fetchUsers();

setUsers(usersData);

} catch (err) {

setError(err.message);

} finally {

setLoading(false);

}

};

getUsers();

}, []);

if (loading) return <p>Loading...</p>;

if (error) return <p>Error: {error}</p>;

return (

<ul>

{users.map(user => (

<li key={user.id}>{user.name}</li>

))}

</ul>

);

};

export default UserList;

The useEffect hook was used to get data when the component mounts. The fetchUsers service is invoked, and based on the response, the component’s state is changed to show the data.

2. State Management Services

Managing state in a React application may get complicated, especially as the application expands. Using services for state management separates state logic from UI components. This strategy is frequently done with state management tools such as Redux or the Context API.

State Management with Context API Example

Let’s make a basic example that uses the Context API to manage global state. We’ll create a service that manages the state of a counter.

javascript

// services/counterService.js

import React, { createContext, useReducer, useContext } from "react";

const CounterContext = createContext();

const initialState = { count: 0 };

const counterReducer = (state, action) => {

switch (action.type) {

case "INCREMENT":

return { count: state.count + 1 };

case "DECREMENT":

return { count: state.count - 1 };

default:

return state;

}

};

export const CounterProvider = ({ children }) => {

const [state, dispatch] = useReducer(counterReducer, initialState);

return (

<CounterContext.Provider value={{ state, dispatch }}>

{children}

</CounterContext.Provider>

);

};

export const useCounter = () => {

return useContext(CounterContext);

};

In this example, CounterProvider is a context provider component that manages the counter state using the useReducer hook. The useCounter hook is a custom hook that allows components to access the counter’s status and perform actions.

Next, we use this service in a component:

// components/Counter.js

import React from "react";

import { useCounter } from "../services/counterService";

const Counter = () => {

const { state, dispatch } = useCounter();

return (

<div>

<p>Count: {state.count}</p>

<button onClick={() => dispatch({ type: "INCREMENT" })}>Increment</button>

<button onClick={() => dispatch({ type: "DECREMENT" })}>Decrement</button>

</div>

);

};

export default Counter;

The Counter component uses the useCounter hook to access the counter state and perform actions to increase or decrease the count.

3. Business Logic Services

Applications may require extensive business logic that cannot be directly embodied in components. This is where business logic services come in. These services encapsulate the logic, simplifying the components and improving code maintainability.

Business Logic Service Example

Consider an application that determines a product discount based on a variety of criteria. We can develop a service that handles this logic.

javascript

// services/discountService.js

export const calculateDiscount = (price, customerType) => {

let discount = 0;

if (customerType === "VIP") {

discount = 0.2;

} else if (customerType === "Regular") {

discount = 0.1;

}

return price - price * discount;

};

 

This service determines the discount based on the customer type. We can use this service in a component.

// components/Product.js

import React from "react";

import { calculateDiscount } from "../services/discountService";

const Product = ({ price, customerType }) => {

const finalPrice = calculateDiscount(price, customerType);

return (

<div>

<p>Original Price: ${price}</p>

<p>Final Price: ${finalPrice}</p>

</div>

);

};

export default Product;

In this case, the Product component utilizes the calculateDiscount service to determine the final price based on the customer type.

What is Services in React Example Github

To show how to construct services in React, we’ll use an example from a GitHub repository. The example will entail developing a service to retrieve data from an API and using it in a React component.

Step 1: First, create a new React project using Create React App. Open your terminal and execute the following commands:

bash

npx create-react-app react-services-example

cd react-services-example

npm start

This will generate a new React project and launch the development server.

Step 2: Next, let’s build a service that retrieves data from a public API. Create a new file called apiService.js in the src directory and include the following code:

Javascript

// src/apiService.js

const API_URL = 'https://jsonplaceholder.typicode.com/posts';

export const fetchPosts = async () => {

try {

const response = await fetch(API_URL);

if (!response.ok) {

throw new Error('Failed to fetch posts');

}

const data = await response.json();

return data;

} catch (error) {

console.error(error);

throw error;

}

};

In this file, we define the function fetchPosts, which retrieves data from the JSONPlaceholder API. This function makes a GET request via the Fetch API and returns JSON data.

Step 3:  Let’s use this service in a React component. Create a new file called Posts.js in the src directory and include the following code:

javascript

// src/Posts.js

import React, { useState, useEffect } from 'react';

import { fetchPosts } from './apiService';

const Posts = () => {

const [posts, setPosts] = useState([]);

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

const [error, setError] = useState(null);

useEffect(() => {

const getPosts = async () => {

try {

const postsData = await fetchPosts();

setPosts(postsData);

setLoading(false);

} catch (error) {

setError(error.message);

setLoading(false);

}

};

getPosts();

}, []);

if (loading) {

return <div>Loading...</div>;

}

if (error) {

return <div>Error: {error}</div>;

}

return (

<div>

<h1>Posts</h1>

<ul>

{posts.map((post) => (

<li key={post.id}>{post.title}</li>

))}

</ul>

</div>

);

};

export default Posts;

We use the useEffect hook in this component to fetch posts when it is mounted. The fetchPosts function from our service is run, and the results are saved in the component’s state. We also manage loading and error states to provide feedback to the user.

Step 4: Finally, we’ll add the Posts component to our main App.js file.

javascript

// src/App.js

import React from 'react';

import Posts from './Posts';

function App() {

return (

<div className="App">

<Posts />

</div>

);

}

export default App;

Now, when you start your application, you should see a list of posts retrieved from the API.

The Top 3 React Service Providers

1. Softblues Solutions LTD

SoftBlues is an AI development company with 15 years of JavaScript expertise, helping businesses evolve with scalable, hi-tech solutions by top developers.

2. Syon GmbH

Syon is a German full-service agency that specializes in end-to-end development. SYON offers digital and innovative solutions that can revolutionize or improve your business.

3. Nicolas Welitzki IT Consulting

Nicolas Welitzki IT Consulting has over twenty years of experience as a professional software developer and business analyst. He is a Full-stack developer for online apps that use technologies like JavaScript, React, Vue, Node.js, and Express.

In addition, he has experience in a variety of businesses (including real estate, finance, e-commerce, and autos), and project implementation using a combination of permanent personnel and partners. He also provides site design, software development, and SEO services across Germany.

4. Bee Base GmbH

BeeBase GmbH specializes in helping small and medium-sized businesses (SMEs) become digital entities.

By providing a variety of internet-based services, the company focuses on digital transformation methods, which include the creation of digital tools and solutions adapted to the specific needs of SMEs.

BeeBase GmbH uses its experience to help businesses navigate the hurdles of digital adoption, assuring their success in an increasingly digital business context.

The company’s approach comprises personalized advice, the creation of customized digital solutions, and continuing assistance to ensure successful implementation and adaptation.

What is React Services folder?

The “services” folder is frequently used to store code for making API queries and handling data from external sources. This React Services folder helps to divide your application’s concerns by segregating data fetching and manipulation code from the components that generate the user interface.

React services folder example

apiClient.js

This file creates a basic client for making HTTP requests. It can include configurations like as the base URL, headers, and request and response interceptors.

javascript

// src/services/apiClient.js

import axios from 'axios';

const apiClient = axios.create({

baseURL: process.env.REACT_APP_API_BASE_URL,

headers: {

'Content-Type': 'application/json',

},

});

apiClient.interceptors.response.use(

response => response,

error => {

// Handle error responses globally

return Promise.reject(error);

}

);

export default apiClient;

userService.js

This file provides routines for performing user-related actions, such as retrieving user data and updating user profiles.

javascript

// src/services/userService.js

import apiClient from './apiClient';

export const getUser = async (userId) => {

try {

const response = await apiClient.get(`/users/${userId}`);

return response.data;

} catch (error) {

console.error('Failed to fetch user', error);

throw error;

}

};

export const updateUser = async (userId, userData) => {

try {

const response = await apiClient.put(`/users/${userId}`, userData);

return response.data;

} catch (error) {

console.error('Failed to update user', error);

throw error;

}

};

authService.js

This file manages authentication-related actions like login and logout.

javascript

// src/services/authService.js

import apiClient from './apiClient';

export const login = async (credentials) => {

try {

const response = await apiClient.post('/auth/login', credentials);

return response.data;

} catch (error) {

console.error('Failed to login', error);

throw error;

}

};

export const logout = async () => {

try {

const response = await apiClient.post('/auth/logout');

return response.data;

} catch (error) {

console.error('Failed to logout', error);

throw error;

}

};

productService.js

This file handles product-related activities, such as retrieving product listings or individual product information.

javascript

// src/services/productService.js

import apiClient from './apiClient';

export const getProducts = async () => {

try {

const response = await apiClient.get('/products');

return response.data;

} catch (error) {

console.error('Failed to fetch products', error);

throw error;

}

};

export const getProductById = async (productId) => {

try {

const response = await apiClient.get(`/products/${productId}`);

return response.data;

} catch (error) {

console.error('Failed to fetch product', error);

throw error;

}

};

How to Consume APIs Using The Fetch API

The Fetch API is a JavaScript built-in function that retrieves resources from a server or an API endpoint. It is built-in, so there is no need to install any dependencies or packages.

The fetch() method has a necessary argument, which is the path or URL of the resource you wish to retrieve. Then it returns a Promise, allowing you to manage success and failure with the then() and catch() methods.

A basic fetch request is relatively easy to write and looks like the code below. We are just retrieving data from a URL that returns data in JSON format and then logging it to the console:

fetch('https://jsonplaceholder.typicode.com/posts?_limit=10')

.then(response => response.json())

.then(data => console.log(data));

The default response is typically a regular HTTP response rather than JSON, but we can obtain our output as a JSON object by calling the response’s json() method.

How to Perform a GET Request in React With Fetch API

You can use the HTTP GET technique to get data from an endpoint. As previously noted, the Fetch API takes one necessary argument, which is correct. It also allows an option parameter, which is unnecessary, particularly when utilizing the default GET method.

However, for other methods like POST and DELETE, you will need to attach the method to the options array.

fetch(url, {

method: "GET" // default, so we can ignore

})

Now that we’ve learned how things operate, let’s put it all together and use a get request to retrieve data from our API.

Again, we’ll use the free web API JSONPlaceholder to get a list of posts into our app:

import React, { useState, useEffect } from 'react';

const App = () => {

const [posts, setPosts] = useState([]);

useEffect(() => {

fetch('https://jsonplaceholder.typicode.com/posts?_limit=10')

.then((response) => response.json())

.then((data) => {

console.log(data);

setPosts(data);

})

.catch((err) => {

console.log(err.message);

});

}, []);

return (

// ... consume here

);

};

In the preceding code, we defined a state to store the data we would obtain from the API, which we will then consume in our application. We also changed the default value to an empty array.

var [setPosts, posts] = useState([]);

The major operation then took place in the useEffect state, ensuring that the data/posts were fetched as soon as the application loaded. The fetch request returns a promise that we can accept or reject:

useEffect(() => {

fetch('https://jsonplaceholder.typicode.com/posts?_limit=10').then(

(response) => console.log(response)

);

}, []);

 

This response provides a considerable amount of data, including the status code, text, and other information required to address issues later.

How to Perform a POST Request in React With Fetch API

You can use HTTP POST to transmit data to an endpoint. It functions similarly to the GET request, with the primary distinction being that you must include the method and two additional parameters in the optional object:

const addPosts = async (title, body) => {

await fetch('https://jsonplaceholder.typicode.com/posts', {

method: 'POST',

body: JSON.stringify({

title: title,

body: body,

userId: Math.random().toString(36).slice(2),

}),

headers: {

'Content-type': 'application/json; charset=UTF-8',

},

})

.then((response) => response.json())

.then((data) => {

setPosts((posts) => [data, ...posts]);

setTitle('');

setBody('');

})

.catch((err) => {

console.log(err.message);

});

};

Frequently Asked Questions

What are services in React?

In React, a service is often a collection of methods that perform data gathering, processing, or any other functionality unrelated to UI rendering.

How do you call a service in React?

These steps are needed to call a service in React:

  • Installing & running a new React app with Axios.
  • Setting up a basic structure.
  • Making the API call with useEffect.
  • Making the API call from a click event.

How do I inject services in React?

In React, an IoC (Inversion of Control) container is a tool for managing dependencies across multiple components and services in your application. It allows you to define and register services or objects (dependencies) once, and then inject them into other components that rely on them.

Leave a comment

Index