zustand + useEffect + cleanup function

PHOTO EMBED

Sun Sep 08 2024 05:11:37 GMT+0000 (Coordinated Universal Time)

Saved by @StefanoGi

import create from 'zustand';

const useRequestStore = create((set) => ({
  data: null,
  error: null,
  loading: true,
  abortController: null,  // Mantiene l'AbortController

  // Funzione per fare la richiesta
  fetchData: async (url) => {
    const controller = new AbortController();  // Crea un nuovo AbortController
    const signal = controller.signal;
    set({ loading: true, error: null, abortController: controller }); // Aggiorna lo stato con l'AbortController

    try {
      const response = await fetch(url, { signal });
      if (!response.ok) {
        throw new Error('Errore nella richiesta');
      }
      const result = await response.json();
      set({ data: result, loading: false });
    } catch (err) {
      if (err.name === 'AbortError') {
        console.log('Richiesta annullata');
      } else {
        set({ error: err.message, loading: false });
      }
    }
  },

  // Funzione per annullare la richiesta
  cancelRequest: () => {
    const state = get(); // Ottieni lo stato corrente
    if (state.abortController) {
      state.abortController.abort();  // Annulla la richiesta
      set({ loading: false, error: 'Richiesta annullata' });
    }
  },

  reset: () => set({ data: null, error: null, loading: true, abortController: null }),
}));

export default useRequestStore;






import React, { useEffect } from 'react';
import useRequestStore from './useRequestStore';

const DataFetchingComponent = () => {
  const { data, error, loading, fetchData, cancelRequest } = useRequestStore();

  useEffect(() => {
    fetchData('https://jsonplaceholder.typicode.com/posts');

    // Cleanup function: annulla la richiesta quando il componente si smonta
    return () => {
      cancelRequest();
    };
  }, [fetchData, cancelRequest]);

  if (loading) return <p>Caricamento in corso...</p>;
  if (error) return <p>Errore: {error}</p>;

  return (
    <div>
      <h2>Posts</h2>
      <ul>
        {data && data.map((post) => (
          <li key={post.id}>{post.title}</li>
        ))}
      </ul>
    </div>
  );
};

export default DataFetchingComponent;
content_copyCOPY