Victor Escalona
Victor Escalona

Reputation: 615

I can't save data inside a Hook

I'm learning Hooks with React and I'm trying to do a simple fetch to an API then I'm trying to save that data inside a Hook but It has not been possible for me.

import React, { useState, useEffect } from "react";

function useDogs() {
  const [dogs, setDogs] = useState({
    data: {}
  });

  useEffect(() => {
    const fectData = async () => {
      const data = await fetch("https://dog.ceo/api/breeds/image/random");
      setDogs({ data: data.url });
      console.log(data.url);
    };
    fectData();
  }, []);
}

function Dogs() {
  const dogs = useDogs();
  console.log("dogs", dogs);
  return <ul>{dogs} dogy</ul>;
}

export default Dogs;

In component Dogs() I'm having dogs as undefined

Upvotes: 0

Views: 719

Answers (2)

Taghi Khavari
Taghi Khavari

Reputation: 6582

Custom Hooks are just javascript functions if you want to assign them to a variable you need to return something in your custom hook,

In some situations you need to set Something into your custom hook which you can do that by returning both value and setValue functions, for example in your case like below:

import React, { useState, useEffect } from "react";

function useDogs() {
  const [dogs, setDogs] = useState({
    data: {},
  });

  useEffect(() => {
    const getData = async () => {
      const resp = await fetch("https://dog.ceo/api/breeds/image/random");
      const data = await resp.json();  // <-- this
      setDogs({ data });
      console.log(resp, data);
    };
    getData();
  }, []);
  return [dogs, setDogs];  // <-- this
}

and when you want to use it you just destructure it like this:

function Dogs() {
  const [dogs, setDogs] = useDogs();
  console.log("dogs", dogs);
  return <ul>{dogs} dogy</ul>;
}

export default Dogs;

now you can read the data and also in future cases if you'ld like you can set the data too,

Upvotes: 0

AKX
AKX

Reputation: 169062

You aren't returning dogs from your useDogs hook.

(Also, to get at the response data, you need to await on .json() from the fetch response.)

import React, { useState, useEffect } from "react";

function useDogs() {
  const [dogs, setDogs] = useState({
    data: {},
  });

  useEffect(() => {
    const getData = async () => {
      const resp = await fetch("https://dog.ceo/api/breeds/image/random");
      const data = await resp.json();  // <-- this
      setDogs({ data });
      console.log(resp, data);
    };
    getData();
  }, []);
  return dogs;  // <-- this
}

function Dogs() {
  const dogs = useDogs();
  console.log("dogs", dogs);
  return <ul>{dogs} dogy</ul>;
}

export default Dogs;

Upvotes: 5

Related Questions