React Using APIs

From bibbleWiki
Jump to navigation Jump to search

Introduction

This page is for how to use APIs with React.

When to call APIs

When using API here is where you should call the APIs

API for calling APIs

Options

There were 4 options offered.

  • Fetch API (Newish but OK)
  • Axios (Believe it is popular and have used)
  • JQuery (Never used)
  • XMLHttpRequest (old and liked - no surprise there)

Using Fetch

Here are the to ways to use fetch.

fetch("/path/to/API")
    .then(response => response.json())
    .then(data => {/* */})

const response = await fetch("/path/to/API");
const data = await response.json();

fetch("/path/to/API", {
    method: "POST",
    body: JSON.stringify(data),
    headers: { 'Content-Type': 'application/json'}
})

So within React this would look like this

const [events, setEvents] = useState([])

useEffect(() => {
    fetch("/path/to/API")
    .then(response => response.json())
    .then(data => {
        setEvents(data)
    })
}, [])

Example Reducer

Here is an example of using a reducer with an API

import UuidStore from "./UuidStore";

const CartReducer = async (state = { cart: [] }, action) => {
    let cart = state.cart;
    let response;

    switch (action.type) {
        case "add": 
            await fetch(
                "http://localhost:3333/cart",
                {
                    method: "POST",
                    headers: {
                        "Content-Type": "application/json",
                        "X-SESSION-TOKEN": UuidStore.value
                    },
                    body: JSON.stringify({
                        id: action.payload.id
                    })
                }
            );
            response = await fetch(
                "http://localhost:3333/cart",
                {
                    method: "GET",
                    headers: {
                        "X-SESSION-TOKEN": UuidStore.value
                    }
                }
            );

            cart = await response.json();
            return {
                ...state,
                cart: cart
            };
 
        case "update":
            if (action.payload.quantity === 0) {
                await fetch(
                    "http://localhost:3333/cart", {
                        method: "DELETE",
                        headers: { 
                            "Content-Type": "application/json",
                            "X-SESSION-TOKEN": UuidStore.value
                        },
                        body: JSON.stringify({
                            id: action.payload.event_id
                        })
                    });
            } else {
                await fetch(
                    "http://localhost:3333/cart", {
                        method: "PATCH",
                        headers: { 
                            "Content-Type": "application/json",
                            "X-SESSION-TOKEN": UuidStore.value
                        },
                        body: JSON.stringify({
                            id: action.payload.event_id,
                            quantity: action.payload.quantity
                        })
                    });    
            }
            response = await fetch(
                "http://localhost:3333/cart", {
                    method: "GET",
                    headers: { 
                        "X-SESSION-TOKEN": UuidStore.value
                    }
                });
                
            cart = await response.json();
            return {
                ...state,
                cart: cart
            };
        case "delete":
            await fetch(
                "http://localhost:3333/cart", {
                    method: "DELETE",
                    headers: { 
                        "Content-Type": "application/json",
                        "X-SESSION-TOKEN": UuidStore.value
                    },
                    body: JSON.stringify({
                        id: action.payload.event_id
                    })
                });
            response = await fetch(
                "http://localhost:3333/cart", {
                    method: "GET",
                    headers: { 
                        "X-SESSION-TOKEN": UuidStore.value
                    }
                });
                
            cart = await response.json();
            return {
                ...state,
                cart: cart
            };
        case "clear":
            await fetch(
                "http://localhost:3333/cart", {
                    method: "DELETE",
                    headers: { 
                        "Content-Type": "application/json",
                        "X-SESSION-TOKEN": UuidStore.value
                    }
                });
            response = await fetch(
                "http://localhost:3333/cart", {
                    method: "GET",
                    headers: { 
                        "X-SESSION-TOKEN": UuidStore.value
                    }
                });
                
            cart = await response.json();
            return {
                ...state,
                cart: cart
            };
        default:
            return {
                ...state,
                cart: cart
            };
    }
};

export default CartReducer;

Refactoring Thunk

Let make the GET a function.

 
async function _getCart() {
    response = await fetch(
        "http://localhost:3333/cart", {
            method: "GET",
            headers: {
                "X-SESSION-TOKEN": UuidStore.value
            }
        });

    cart = await response.json();
    return cart;
}

Now we create function for each CRUD operation and we wrap it in a . Here is ADD.

 
export function addCart(id) {
   return async function addCartThunk(dispatch, getState) {
       await fetch(
           "http://localhost:3333/cart", {
           method: "POST",
           headers: {
               "Content-Type": "application/json",
               "X-SESSION-TOKEN": UuidStore.value
           },
           body: JSON.stringify({
               id: id
           })
       });
       let cart = await _getCart();
       dispatch({type: "refresh". payload: cart });
   }
}

Within the original reducer we now have this becase the "refresh" functions passes the action to the refresh function which we will see in a moment.

 
const CartReducer = (state = { cart: [] }, action) => {
    let cart = state.cart;

    switch (action.type) {
        case "refresh": 
            return {
                ...state,
                cart: action.payload
            };
        default:
            return {
                ...state,
                cart: cart
            };
    }
};
export default CartReducer;