Hey im pretty new to React and JS.
Im trying to implement the React Suspense boundary for a component that requires fechting data from my backend API. I used the fetchData and wrapPromise function from this example [https://dev.to/darkmavis1980/a-practical-example-of-suspense-in-react-18-3lln](A practical example of Suspense in React 18 ).
wrapPromise function:
/**
* Wraps a promise so it can be used with React Suspense
* @param {Promise} promise The promise to process
* @returns {Object} A response object compatible with Suspense
*/
function wrapPromise(promise) {
let status = "pending";
let response;
const suspender = promise.then(
(res) => {
status = "success";
response = res;
},
(err) => {
status = "error";
response = err;
}
);
const handler = {
pending: () => {
throw suspender;
},
error: () => {
throw response;
},
default: () => response,
};
const read = () => {
const result = handler[status] ? handler[status]() : handler.default();
return result;
};
return { read };
}
export default wrapPromise;
fetchData function:
* Wrap Axios Request with the wrapPromise function
* @param
* @returns {Promise} A wrapped promise
*/
function fetchData(url) {
const promise = axios.get(url).then(({ data }) => data);
return wrapPromise(promise);
}
export default fetchData;
So i created a component RecipeTableMain to render the recipe data:
import fetchData from "../../api/fetchData";
const resource = fetchData("http://localhost:3001/recipes");
...
export default function RecipeTableMain() {
const data = resource.read(); //Calling read function from wrapPromise
... some code for mui data grid
}
My Problem is: The data only gets fetched on the first render of RecipeTableMain component (After i reload my app). I tried to find a way to fetch the data again for example after deleting or creating a new recipe, but i have no idea how i could implement this in my code.
Thanks Jonas.
I think i missed some basics about how code outside of React components is executed.
Like the user from this post:
Infinite loop when using React Suspense and Axios data fetch
I ditched the wrapPromise() function, and used the useSWR hook instead.
I also modified the fetchData() function:
import axios from "axios";
/**
* Wrap Axios Request with the wrapPromise function
* @param {String} URL Endpoint
*/
async function fetchData(url) {
return axios
.get(url)
.then(({ data }) => data)
.catch((err) => console.log(err));
}
export default fetchData;
And i call it like this:
import useSWR from "swr";
import fetchData from "../../api/fetchData";
export default function RecipeTableMain() {
const url = "http://localhost:3001/recipes";
const fetcher = (url) => fetchData(url);
const { data } = useSWR(url, fetcher, {
suspense: true,
});
...
}
Now the data gets fetched on every render of the component and i can also pass an route id from react router if necessary.