Custom API layer in React

Asked
Active3 hr before
Viewed126 times

10 Answers

customreact
90%

You need to add await in your useEffect function:,I am working on a little project to learn React. It is a movie app listing and its fetching data from themoviedb.org.,However as it stands I have four listings on landing page and each is a individual component and in each I have separate API call with slightly different parameters., By clicking “Accept all cookies”, you agree Stack Exchange can store cookies on your device and disclose information in accordance with our Cookie Policy.

You need to add await in your useEffect function:

useEffect(() => {
   async function fetchData() {
      const results = await API.get("movie/popular")
      setMovies(results)
   }
   fetchData();
}, []);
88%

There are several ways to use React.js. The simplest way is just to include React libraries in the <script> tags on the page. ,Listing 1.1. Including the React.js library in the HTML page:,Before starting development, we need to set up a React.js development environment.,Jest - Testing React applications.

xxxxxxxxxx
load more v
72%

If you are starting a new app or already have an app but are not sure how to add API layer to your application then this is the right place. I would like to share my experience on how we currently maintain an API layer. (Remember this is not the only way to do it),The approach which we have taken helps us to use a single layer for both our React and React Native projects with very minor changes.,I have seen many projects in React where API’s are included in each component and as the application grows it becomes difficult to keep track of all the endpoints that are getting used.,It might be a pain point initially to figure out how to maintain and structure your API layer, but once done it saves a lot of time in future.

The components might be infected with fetch requests and might look like the one below:

class Home extends React.Component {
      fetchUserDetails = () => {
            fetch('/user-url').then(res => { // successCallback   })   .catch(err => {     // errorCallback   }) }}
load more v
65%

In the services folder, we're going to create a few utilities to make our APIs reusable and standardized for all components and team members. We'll be making use of the JavaScript axios library and JavaScript classes in this example to create our API utilities. ,I got an error on exporting individual api when creating a custom function.,Here is a link to the collection of files discussed in this article: Gist Link,We're going to focus on three main files here:

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

let API_URL_TASKS = 'https://url.com/api/v1/tasks';

export function Tasks() {
  const [tasks, setTasks] = useState([]);

  useEffect(() => {
    _getTasks();
  }, []);

  function _getTasks() {
    axios
      .get(API_URL_TASKS)
      .then((res) => {
        let arr = _parseTasks(res.results.data);
        setTasks(arr);
      })
      .catch((err) => {
        _handleError(err, type);
      });
  }

  function _parseTasks(tasks) {
    return tasks.map((task) => {
      // Parse task information
      return task;
    });
  }

  function _createTask(task) {
    axios
      .post(url, task)
      .then((res) => {
        _handleSuccess(res, 'post');
        // etc...
      })
      .catch((err) => {
        _handleError(err, 'post');
      });
  }

  function _updateTask(task) {
    let url = `${API_URL_TASKS}/${id}`;
    axios
      .patch(url, task)
      .then((res) => {
        _handleSuccess(res, 'patch');
        // etc...
      })
      .catch((err) => {
        _handleError(err, 'patch');
      });
  }

  function _removeTask(id) {
    let url = `${API_URL_TASKS}/${id}`;
    axios
      .delete(url)
      .then((res) => {
        _handleSuccess(res, 'delete');
        // etc...
      })
      .catch((err) => {
        _handleError(err, 'delete');
      });
  }

  function _handleSuccess(response, type) {
    // success message
    // actions against state with type
  }

  function _handleError(error, type) {
    // error message
    // actions based on type
    // etc...
  }

  return (
    <ul>
      {tasks.map((task) => (
        <li key={task.id}>{task.name}</li>
      ))}
    </ul>
  );
}

load more v
75%

This brief tutorial will help you understand a few concepts you need to know so as to integrate a RESTful API into a React application.,Below is a typical JSON response from the contact list dump:,Install create-react-app,This will generate some scaffolds you need to get your React application running as quick as possible.

We will be creating our React Application using a neat tool called create-react-app, this is a boilerplate that helps you set up a proper folder structure and assets binding for your React application. Run this command on your terminal.

    npm i create - react - app
load more v
40%

It’s pretty much the same thing we did above with the exception of it being a function that takes in query and returns status and data. And, that’s a useFetch hook that we could use in several components in our React application.,That’s really what it is, and along with a JavaScript function, it allows you to reuse some piece of code in several parts of your app.,Throughout this article, we’ll be making use of Hacker News Search API to build a custom hook which we can use to fetch data. While this tutorial will cover the Hacker News Search API, we’ll have the hook work in a way that it will return response from any valid API link we pass to it.,Memoization is a technique we would use to make sure that we don’t hit the hackernews endpoint if we have made some kind of request to fetch it at some initial phase. Storing the result of expensive fetch calls will save the users some load time, therefore, increasing overall performance.

componentDidMount() {
   const fetchData = async () => {
      const response = await fetch(
         `https://hn.algolia.com/api/v1/search?query=JavaScript`
      );
      const data = await response.json();
      this.setState({
         data
      });
   };

   fetchData();
}

componentDidUpdate(previousProps, previousState) {
   if (previousState.query !== this.state.query) {
      const fetchData = async () => {
         const response = await fetch(
            `https://hn.algolia.com/api/v1/search?query=${this.state.query}`
         );
         const data = await response.json();
         this.setState({
            data
         });
      };

      fetchData();
   }
}
load more v
22%

We have the following components:,In this example, we intend to change the theme and perform translation basis the selected language.,P.S: In case you missed reading our in-depth introduction to Render Props, you can find it here.,This means Context API helps us to skip the mandatory hierarchy of passing props for each component in its component tree.

Provider pattern, however, is not only about react context. You might have used a state management library like redux and mobX. Here provider is the top most component and it is provided by react-redux. We write it the following way:

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import store from './store';
import App from './App';

const rootElement = document.getElementById('root');
ReactDOM.render(  
   <Provider store={store}>    
     <App />  
   </Provider>,  
   rootElement
);
load more v
60%

This new API solves one major problem–prop drilling. Even if you’re not familiar with the term, if you’ve worked on a React.js app, it has probably happened to you. Prop drilling is the processing of getting data from component A to component Z by passing it through multiple layers of intermediary React components. Component will receive props indirectly and you, the React Developer will have to ensure everything works out right.,React's context allows you to share information to any component, by storing it in a central place and allowing access to any component that requests it (usually you are only able to pass data from parent to child via props).,What did we forget? The ProductList! This is where the benefit becomes apparent. We don’t pass any data or methods. The component is simplified because it only needs to render a few components.,No, you can’t. In React, data flows from the root level parents to the most deeply nested child. This is why it can be necessary to keep a central store of data and access it where you need it instead of endlessly passing it from parent to child.

App.js

class App extends Component {
    state = {
        cars: {
            car001: { name: 'Honda', price: 100 },
            car002: { name: 'BMW', price: 150 },
            car003: { name: 'Mercedes', price: 200 }
        }
    };
    incrementCarPrice = this.incrementCarPrice.bind(this);
    decrementCarPrice = this.decrementCarPrice.bind(this);

    incrementCarPrice(selectedID) {
        // a simple method that manipulates the state
        const cars = Object.assign({}, this.state.cars);
        cars[selectedID].price = cars[selectedID].price + 1;
        this.setState({
            cars
        });
    }

    decrementCarPrice(selectedID) {
        // a simple method that manipulates the state
        const cars = Object.assign({}, this.state.cars);
        cars[selectedID].price = cars[selectedID].price - 1;
        this.setState({
            cars
        });
    }

    render() {
        return (
            <div className="App">
                <header className="App-header">
                    <img src={logo} className="App-logo" alt="logo" />
                    <h1 className="App-title">Welcome to my web store</h1>
                </header>
                {/* Pass props twice */}
                <ProductList
                    cars={this.state.cars}
                    incrementCarPrice={this.incrementCarPrice}
                    decrementCarPrice={this.decrementCarPrice}
                />
            </div>
        );
    }
}
load more v
48%

In this guide, we'll take a look at how to build a simple backend server using Javascript Node.js as the application layer and React.js as the view layer that interacts with the backend to simulate the full stack experience.,Creating the React.js Frontend,The server application you'll be creating will be a mock API endpoint that returns JSON data. Start off by creating a Javascript file called app.js with the following content:,This vanilla component will simply display the firstName and lastName state values. Initially, these values are set as an empty string.

1
var http = require('http');
2
3
var hostname = '127.0.0.1';
4
var port = 3000;
5
6
var app = http.createServer(function(req, res) {
   7 res.setHeader('Content-Type', 'application/json');
   8
   9 res.end(
      10 JSON.stringify({
         11 firstName: "John",
         12 lastName: "Doe"
         13
      }) 14);
   15
});
16
17 app.listen(port, hostname);
load more v
23%

After documenting your plan of action, it's time to look at some details necessary to setup the app’s data layer, covered in the next section.,Implementing it this way can cause issues in large apps as there is no central view of the history object. In addition, components that are not rendered via the route component like this cannot access it:,In the above snippet, formatTweet function inserts a new key parent to the tweet object of the frontend app and returns data based on parameters, without affecting outside data.,The parts I describe in this section will be directly used by redux actions, to modify the state. Depending on the size of the app (and also the time you have) you can go about setting the datastore in one of the two ways.

Make a list of such data in your application as this will constitute the models of the app, and based on these values you'll create your app’s reducers.

products: {
   productId: {
      productId,
      productName,
      category,
      image,
      price
   },
   productId: {
      productId,
      productName,
      category,
      image,
      price
   },
   productId: {
      productId,
      productName,
      category,
      image,
      price
   },
}
load more v

Other "custom-react" queries related to "Custom API layer in React"