Home > Enterprise >  How to change the data received from a custom hook?
How to change the data received from a custom hook?

Time:04-04

I just got into custom hooks and i created a custom hook that fetches data from an API.

interface DataProps<Type> {
  results: Type[];
  isLoading: boolean;
  LIMIT: number;
  offset: number;
}

interface Pokemon {
  name: string;
  url: string;
}

const useGetData = (url: string) => {
  const [data, setData] = useState<DataProps<Pokemon>>({
    results: [],
    isLoading: true,
    LIMIT: 80,
    offset: 0
  });

  const fetchData = async () => {
    const res = await fetch(
      url  
        new URLSearchParams({
          limit: data.LIMIT   "",
          offset: data.offset   ""
        })
    );
    const { results } = await res.json();
    setData((prevValue) => ({
      ...prevValue,
      results: [...prevValue.results, ...results],
      isLoading: false,
      offset: prevValue.offset   prevValue.LIMIT
    }));
  };

  useEffect(() => {
    fetchData();
  }, []);

  return data;
};

In my App component, I use it like this:

export default function App() {
  let data = useGetData(
    `https://pokeapi.co/api/v2/pokemon?`
  );

  return (
    <div className="App">
      {data.isLoading && <div>Loading...</div>}
      <ul>
        {data.results.map((pokemon) => (
          <li key={pokemon.name}>{pokemon.name}</li>
        ))}
      </ul>
    </div>
  );
}

Works great, but this is only for displaying purposes. I would like, for example, to remove an element from the results array. How would I achieve that since I don't have a setData() to do that? From what I know, mutating state without a set...() is bad when you want the change in state to generate a rerender (like in my case, where I want the delete operation to remove the selected element from screen).

CodePudding user response:

In your hook instead of return data use return [data, setData]

Then in your component instead of

let data = useGetData('https://pokeapi.co/api/v2/pokemon?');

do

const [data, setData] = useGetData('https://pokeapi.co/api/v2/pokemon?');

You now have access to your setter in the component and can manipulate the state.

  • Related