gpt4 book ai didi

javascript - useEffect 中异步函数的 React Hook 警告 : useEffect function must return a cleanup function or nothing

转载 作者:IT王子 更新时间:2023-10-29 03:14:06 29 4
gpt4 key购买 nike

我正在尝试像下面这样的 useEffect 示例:

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);
}
}, []);

然后我在我的控制台中收到此警告。但我认为清理对于异步调用是可选的。我不确定为什么会收到此警告。链接沙箱的例子。 https://codesandbox.io/s/24rj871r0p enter image description here

最佳答案

我建议看看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.

您可以阅读更多关于 experimental suspense here 的信息.


如果你想在 eslint 之外使用函数。

 function OutsideUsageExample({ userId }) {
const [data, dataSet] = useState<any>(null)

const fetchMyAPI = useCallback(async () => {
let response = await fetch('api/data/' + userId)
response = await response.json()
dataSet(response)
}, [userId]) // if userId changes, useEffect will run again

useEffect(() => {
fetchMyAPI()
}, [fetchMyAPI])

return (
<div>
<div>data: {JSON.stringify(data)}</div>
<div>
<button onClick={fetchMyAPI}>manual fetch</button>
</div>
</div>
)
}

如果您使用 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>
);
}

关于javascript - useEffect 中异步函数的 React Hook 警告 : useEffect function must return a cleanup function or nothing,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53332321/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com