React native moving large code into separate file - is it a hook?

Viewed 370

I have a react native screen that has a very long code that I would like to refractor.

Say my screen.jsx is (simplified, of course):

import React, { useState, useCallback, useEffect } from 'react';
import useLocation from '../hooks/useLocation'; // A custom hook I wrote. This one makes sense to use as a hook. It's a function that returns a location.
...

export default function Screen() {
  const [fetchingLocation, region, setRegion] = useLocation();
  
  // FROM HERE DOWN
  const [fetchingRestaurants, setFetchingRestaurants] = useState(false);
  const [restaurants, setRestaurants] = useState([]);
  const [errorMessage, setErrorMessage] = useState('');

  const initSearch = useCallback(async ({ searchQuery, region }) => {
    setFetchingRestaurants(true);
    try {
      const response = await remoteApi.get('/search', {
        params: {
          term: searchQuery,
          latitude: region.latitude,
          longitude: region.longitude,
        },
      });
      const fetchedRestaurants = response.data.businesses;
      const fetchedRestaurantsArray = fetchedRestaurants.map((restaurant) => ({
        id: restaurant.id,
        name: restaurant.name,
      }));
      setRestaurants(fetchedRestaurantsArray);
      setFetchingRestaurants(false);
    } catch (e) {
      setRestaurants([]);
      setFetchingRestaurants(false);
    }
  }, []);

  return (
    <View>...</View>
  );
}

To better structure my code, I would like to move all the code you see below "FROM HERE DOWN" (initSearch as well as the three state management useState hooks above it) into another file and import it.

At the moment I created a custom useRestaurantSearch hook in the hooks folder like so:

export default function useRestaurantSearch() {
  // The code I mentioned goes here
  return [initSearch, errorMessage, restaurants, setRestaurants, fetchingRestaurants];
}

Then in my Screen.jsx file I import it import useRestaurantSearch from '../hooks/useRestaurantSearch'; and inside function Screen() I grab the consts I need with

const [
  initSearch,
  errorMessage,
  restaurants,
  setRestaurants,
  fetchingRestaurants,
] = useRestaurantSearch();

This works, but I feel like it can be better written and this whole approach seems weird - is it really a custom hook? If it's not a custom hook, does it belong in a util folder as a utility?

How would you approach this?

1 Answers

Yes this would be considered a custom hook since according to the React docs, custom hooks are just a mechanism to reuse stateful logic.

One thing that could help simplify it is:

  • using a library like TanStack Query (formerly React Query). You could create a query to fetch the restaurants and then you could use the data and fetchStatus from the query instead of adding them to state.
Related