React useEffect async warning?

Viewed 3235

I'm trying to get rid of React's warning "It looks like you wrote useEffect(async () => ...) or returned a Promise. Instead, write the async function inside your effect and call it immediately".

I've been referencing this article https://www.robinwieruch.de/react-hooks-fetch-data to attempt to get rid of it, but alas, am unable to.

My useEffect:

  useEffect(() => api.getAllPokemon(setResponse),[])

And my api.getAllPokemon async function which I've defined in an imported file:

const api = {}

api.getAllPokemon = async (cb) => {
  await fetch('http://localhost:8080/pokemon', {
    headers: {
      'Content-Type': 'application/json',
      'Accept': 'application/json'
    }
  })
  .then(async (pokemon) => await pokemon.json())
  .then((pokemon) => pokemon.rows.map(({ name }) => name))
  .then(pokemon => cb(pokemon))
};

export default api;
3 Answers

useEffect can only return a cleanup function or nothing. In your case, add brackets to your arrow function or use the normal function syntax to avoid returning a Promise:

useEffect(() => {
  api.getAllPokemon(setResponse)
}, [])

or

useEffect(function () { 
  api.getAllPokemon(setResponse) 
}, [])

u cant combine await and also promise

and also async in useEffect has a little different.

when you async your fetch .then doesn't work but it returns the response for you

so we need to write try and catch

useEffect(() => {
    try {
      const fetchData = async () => {
        const res = await fetch("http://localhost:8080/pokemon");
        setBaseExperience(res);
      };

      fetchData();
    } catch (err) {
      console.log(err);
    }
  }, []);

JSON fetching example using fetch wrapper (Live Demo)

import React, { useState } from "react";
import { useAsyncEffect } from "use-async-effect2";
import cpFetch from "cp-fetch"; //cancellable c-promise fetch wrapper

export default function TestComponent(props) {
  const [text, setText] = useState("");

  useAsyncEffect(
    function* () {
      setText("fetching...");
      const response = yield cpFetch(props.url);
      const json = yield response.json();
      setText(`Success: ${JSON.stringify(json)}`);
    },
    [props.url]
  );

  return <div>{text}</div>;
}

According to your code:

const api = {}

api.getAllPokemon = function*() => {
  const respose= yield cpFetch('http://localhost:8080/pokemon', {
    headers: {
      'Content-Type': 'application/json',
      'Accept': 'application/json'
    }
  });

  const pokemon= yield response.json();
  return pokemon.rows.map(({ name }) => name));
};

export default API;

Inside the functional component body:

useAsyncEffect(function*(){
   const names= yield* api.getAllPokemon(setResponse);
   // changeState here
},[])
Related