gpt4 book ai didi

javascript - 使用带有 "async"的 useEffect 钩子(Hook)

转载 作者:行者123 更新时间:2023-12-02 16:43:29 26 4
gpt4 key购买 nike

如何清理 react Hook 中的 react 请求。我读到需要在我的钩子(Hook) AbortController 中输入,但我不知道如何输入。我使用 next.js。消除此问题的最佳方法是什么?我收到这个警告:

Warning: can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.

这是我用来获取数据的自定义钩子(Hook):

import { useState, useEffect, useCallback } from 'react'
import { MOVIE_API_URL, MOVIE_KEY } from '../../config'

export const useMovieDetailsFetch = (movieId) => {
const [state, setState] = useState({})
const [loading, setLoading] = useState(true)
const [error, setError] = useState(false)

const fetchData = useCallback(async () => {
setError(false)
setLoading(true)

try {
const movieDetailsEndpoint = `${MOVIE_API_URL}movie/${movieId}?api_key=${MOVIE_KEY}`
const result = await (await fetch(movieDetailsEndpoint)).json()
const creditsEndpoint = `${MOVIE_API_URL}movie/${movieId}/credits?api_key=${MOVIE_KEY}`
const creditsResult = await (await fetch(creditsEndpoint)).json()
// Filtring in crew for directors only
const movieDirectors = creditsResult.crew.filter(
(member) => member.job === 'Director'
)

setState({
...result,
movieDirectors,
actors: creditsResult.cast,
})
} catch (error) {
setError(true)
}
setLoading(false)
}, [movieId])

useEffect(() => {

fetchData()
}, [fetchData])

return [state, loading, error]
}

最佳答案

使用 abort controller ,以最原始的形式:

const controller = new AbortController();
const { signal } = controller;
...

fetch(url, { signal });

...
// abort
controller.abort();

中止飞行中的 fetch 效果 Hook

useEffect(() => {
const controller = new AbortController();
const { signal } = controller;
fetch(url, { signal });

return () => {
controller.abort(); // abort on unmount for cleanup
};
}, []);

我找到了这个 article当我需要开发一种取消获取请求的方法时,非常有用。

编辑

signal 需要添加到 fetch 请求选项对象。您还可以在效果中定义 async fetchData 函数(这是正常的),因此它都包含在效果 Hook 的回调范围内。

export const useMovieDetailsFetch = (movieId) => {
const [state, setState] = useState({})
const [loading, setLoading] = useState(true)
const [error, setError] = useState(false)

useEffect(() => {
const controller = new AbortController();
const { signal } = controller;

const fetchData = async () => {
setError(false);
setLoading(true);

try {
const movieDetailsEndpoint = `${MOVIE_API_URL}movie/${movieId}?api_key=${MOVIE_KEY}`;
const result = await (
await fetch(movieDetailsEndpoint, { signal })
).json();
const creditsEndpoint = `${MOVIE_API_URL}movie/${movieId}/credits?api_key=${MOVIE_KEY}`;
const creditsResult = await (
await fetch(creditsEndpoint, { signal })
).json();
// Filtring in crew for directors only
const movieDirectors = creditsResult.crew.filter(
(member) => member.job === 'Director'
);

setState({
...result,
movieDirectors,
actors: creditsResult.cast,
});
} catch (error) {
setError(true);
}
setLoading(false);
}

fetchData();

return () => controller.abort();
}, [movieId]);

return [state, loading, error];
}

关于javascript - 使用带有 "async"的 useEffect 钩子(Hook),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61056095/

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