React Using APIs: Difference between revisions
Line 272: | Line 272: | ||
===Add Thunk Middleware=== | ===Add Thunk Middleware=== | ||
We now need to add our redux-thunk middleware to the user. Similar to express we create an instance and add it to the arguments of the store. | We now need to add our redux-thunk middleware to the user. Similar to express we create an instance and add it to the arguments of the store. | ||
<syntaxhighlight lang="js" highlight=" | <syntaxhighlight lang="js" highlight="3,6,7"> | ||
import { createStore, applyMiddleware } from "redux"; | import { createStore, applyMiddleware } from "redux"; | ||
import thunkMiddleware from "redux-thunk"; | import thunkMiddleware from "redux-thunk"; |
Revision as of 11:42, 23 June 2021
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
Create the GET function
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;
}
Wrap the CRUD Functions
Now we create function for each CRUD operation and we wrap it in a function that returns the cart and accepts dispatch and getState as the arguments. 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 });
}
}
Change Reducer Accept Generic CRUD Functions
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;
Implement new calls to helper functions
Using the this we can create an instance of dispatch and pass the addCart function.
...
const dispatch = useDispatch();
<button> type="button" ... onClick={() => dispatch(addCart()event.id)}...</button>
Change UI from Promises Object
We now return an object and now a promise so.
const state = CartStore.getState();
if (state) {
state.then((state) = {
const cart = state.cart;
const totalAmount = state.cart.reduce((p, n) => p + n.quantity * n.price, 0);
setCart(cart);
setTotalAmount(totalAmount);
})
}
};
Becomes
const state = CartStore.getState();
if (state) {
const cart = state.cart;
const totalAmount = state.cart.reduce((p, n) => p + n.quantity * n.price, 0);
setCart(cart);
setTotalAmount(totalAmount);
}
};
Add Thunk Middleware
We now need to add our redux-thunk middleware to the user. Similar to express we create an instance and add it to the arguments of the store.
import { createStore, applyMiddleware } from "redux";
import thunkMiddleware from "redux-thunk";
import CartReducer from "./CartReducer";
const thunkMiddle = applyMiddleware(thunkMiddleware);
const CartStore = createStore(CartReducer, thunkMiddle);
export default CartStore;