0

i made a custom hook for fetching data the problem is when i use <React.StrictMode> the fetch singal for aborting gets fire but some how it works if i remove strict mode

this is the fetch hook

import { useEffect, useReducer } from 'react';
import { ApiResponse } from '../interfaces/ApiResponse';

const initialState: ApiResponse = {
  loading: false,
  data: null,
  error: null,
};

type Action =
  | { type: 'start' }
  | { type: 'error'; payload: Error }
  | { type: 'success'; payload: JSON };

const reducer = (state: ApiResponse, action: Action) => {
  switch (action.type) {
    case 'start':
      return {
        loading: true,
        data: null,
        error: null,
      };
    case 'success':
      return {
        loading: false,
        data: action.payload,
        error: null,
      };
    case 'error':
      return {
        loading: false,
        data: null,
        error: action.payload,
      };

    default:
      return state;
  }
};

export const useFetch = (url: string): ApiResponse => {
  const [response, dispatch] = useReducer(reducer, initialState);
  useEffect(() => {
    const controller: AbortController = new AbortController();
    const signal: AbortSignal = controller.signal;
    const fetchData = async () => {
      dispatch({ type: 'start' });
      try {
        const response: Response = await fetch(url, { signal: signal });
        if (response.ok) {
          const json = await response.json();
          dispatch({
            type: 'success',
            payload: json,
          });
        } else {
          dispatch({
            type: 'error',
            payload: new Error(response.statusText),
          });
        }
      } catch (error: any) {
        dispatch({
          type: 'error',
          payload: new Error(error),
        });
      }
    };
    fetchData();
    return () => {
      controller.abort();
    };
  }, [url]);
  return response;
};

when i call this hook in one of my components like this:

const Grid = () => {
  const response = useFetch(`${BASE_API_URL}/games`);
  useEffect(() => {
    console.log(response);
  }, [response]);

  return (
    <div className='grid__wrapper'>
      <div className='grid__content'>
        {response.loading && <h4>Loading...</h4>}
        <h4>helo</h4>
      </div>
    </div>
  );
};

export default Grid;

the response.loading is never set to true and i can see an abort error in the logs but if i remove strict mode it works fine

jsejcksn
  • 27,667
  • 4
  • 38
  • 62
ludinj
  • 107
  • 7
  • 1
    Does this answer your question? [React 18, useEffect is getting called two times on mount](https://stackoverflow.com/questions/72238175/react-18-useeffect-is-getting-called-two-times-on-mount) – Youssouf Oumar Sep 22 '22 at 09:20
  • Yes thank you tha gave me a good idea, i will post my anwser soon – ludinj Sep 22 '22 at 17:47

0 Answers0