Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using React hooks in an external API service layer

I'm building a react app for an eCommerce site. I have a page for Product Search. I'm using the SWR library (useSWR hook), because I like it's caching ability. However, as it uses hooks, it seems I can't place this call outside of my function component. Ideally, I'd like to segment off all API functionality into a separate library / service layer.

Let me demonstrate what I'm trying to do with some extremely cut-down code:

import React, { useState } from 'react';
import { useParams } from "react-router";
import * as ProductAPI from 'common/libs/ProductAPI';

function ProductSearch() {

    const [searchResults, setSearchResults] = useState(null);

    let { keywords } = useParams();

    const results = ProductAPI.getProductSearchResults(keywords);

    if (searchResults != results)
        setSearchResults(results);

    function renderSearchResults() {
        ...
    }

    return (
        <>
            {renderSearchResults()}
        </>
    );
}

export default ProductSearch;

And the API library:

import useSWR from 'swr';

var productSearchURL = process.env.REACT_APP_API_ENDPOINT + '/product/search';

export function getProductSearchResults(keywords) {

    let url = productSearchURL;
    url += "/" + encodeURI(keywords);

    const { data } = useSWR(url);

    return data;
}

Now, React is giving met the "you're breaking the rules of hooks" error:

Invalid hook call. Hooks can only be called inside of the body of a function component.

I've been struggling to find a solution that would let me achieve this abstraction of API functionality into it's own function/component.

If there's no way to solve this using my current approach, what would be the best way to achieve this layered approach to the API implementation?

like image 685
Josh43 Avatar asked Oct 25 '25 22:10

Josh43


1 Answers

You should create a custom hook that uses useSWR to fetch data. React will allow to create a custom hook with other hooks used inside it. Somthing like this:

export function useProductSearchResults(keywords) {

    let url = productSearchURL;
    url += "/" + encodeURI(keywords);

    const { data } = useSWR(url);

    return data;
}

then use this custom hook in you code:

.
.
 let { keywords } = useParams();

    const results = useProductSearchResults(keywords);

    if (searchResults != results)
        setSearchResults(results);
.
.
.
like image 131
Lokii Avatar answered Oct 27 '25 11:10

Lokii



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!