我正在尝试下面的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
其他答案已经有很多例子给出了,并且解释得很清楚,所以我将从TypeScript类型定义的角度来解释它们。
useEffect钩子TypeScript签名:
function useEffect(effect: EffectCallback, deps?: DependencyList): void;
效果类型:
// NOTE: callbacks are _only_ allowed to return either void, or a destructor.
type EffectCallback = () => (void | Destructor);
// Destructors are only allowed to return void.
type Destructor = () => void | { [UNDEFINED_VOID_ONLY]: never };
现在我们应该知道为什么effect不能是一个异步函数了。
useEffect(async () => {
//...
}, [])
async函数将返回一个带有隐式未定义值的JS promise。这不是useEffect的期望。
我通读了这个问题,觉得答案中没有提到实现useEffect的最佳方法。
假设您有一个网络呼叫,并且希望在得到响应后执行一些操作。
为了简单起见,让我们将网络响应存储在一个状态变量中。
人们可能希望使用action/reducer来更新存储与网络响应。
const [data, setData] = useState(null);
/* This would be called on initial page load */
useEffect(()=>{
fetch(`https://www.reddit.com/r/${subreddit}.json`)
.then(data => {
setData(data);
})
.catch(err => {
/* perform error handling if desired */
});
}, [])
/* This would be called when store/state data is updated */
useEffect(()=>{
if (data) {
setPosts(data.children.map(it => {
/* do what you want */
}));
}
}, [data]);
参考=> https://reactjs.org/docs/hooks-effect.html#tip-optimizing-performance-by-skipping-effects