React Hook Warnings for async function in useEffect: useEffect function must return a cleanup function or nothing

I was trying the useEffect example something like below:

useEffect(async () => {

try {

const response = await fetch(`https://www.reddit.com/r/${subreddit}.json`);

const json = await response.json();

setPosts(json.data.children.map(it => it.data));

} catch (e) {

console.error(e);

}

}, []);

and I get this warning in my console. But the cleanup is optional for async calls I think. I am not sure why I get this warning. Linking sandbox for examples. https://codesandbox.io/s/24rj871r0p

enter image description here

Answer

I suggest to look at Dan Abramov (one of the React core maintainers) answer here:

I think you're making it more complicated than it needs to be.

function Example() {

const [data, dataSet] = useState<any>(null)

useEffect(() => {

async function fetchMyAPI() {

let response = await fetch('api/data')

response = await response.json()

dataSet(response)

}

fetchMyAPI()

}, [])

return <div>{JSON.stringify(data)}</div>

}

Longer term we'll discourage this pattern because it encourages race conditions. Such as — anything could happen between your call starts and ends, and you could have gotten new props. Instead, we'll recommend Suspense for data fetching which will look more like

const response = MyAPIResource.read();

and no effects. But in the meantime you can move the async stuff to a separate function and call it.

You can read more about experimental suspense here.


If you want to use functions outside with eslint.

 function OutsideUsageExample() {

const [data, dataSet] = useState<any>(null)

const fetchMyAPI = useCallback(async () => {

let response = await fetch('api/data')

response = await response.json()

dataSet(response)

}, [])

useEffect(() => {

fetchMyAPI()

}, [fetchMyAPI])

return (

<div>

<div>data: {JSON.stringify(data)}</div>

<div>

<button onClick={fetchMyAPI}>manual fetch</button>

</div>

</div>

)

}


With useCallback useCallback. Sandbox.

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

export default function App() {

const [counter, setCounter] = useState(1);

// if counter is changed, than fn will be updated with new counter value

const fn = useCallback(() => {

setCounter(counter + 1);

}, [counter]);

// if counter is changed, than fn will not be updated and counter will be always 1 inside fn

/*const fnBad = useCallback(() => {

setCounter(counter + 1);

}, []);*/

// if fn or counter is changed, than useEffect will rerun

useEffect(() => {

if (!(counter % 2)) return; // this will stop the loop if counter is not even

fn();

}, [fn, counter]);

// this will be infinite loop because fn is always changing with new counter value

/*useEffect(() => {

fn();

}, [fn]);*/

return (

<div>

<div>Counter is {counter}</div>

<button onClick={fn}>add +1 count</button>

</div>

);

}

以上是 React Hook Warnings for async function in useEffect: useEffect function must return a cleanup function or nothing 的全部内容, 来源链接: utcz.com/a/23654.html

回到顶部