React에서 API 호출을 취소해야 하는 이유는 무엇입니까?

11723 단어 reactjavascript

설명



우리 모두는 알고 있습니다. 모든 웹 애플리케이션은 API 호출을 합니다. (고양이 API로 만든 첫 번째 Todo 앱을 기억하십니까?).

일부 데이터를 수집하고 렌더링하고 웹 사이트에서 원하는 대로 수행합니다. 인터넷이 느리거나 수집해야 하는 데이터가 방대할 때 실제 문제가 발생합니다.

간신히 Edge 연결로 엄청난 양의 데이터를 수집해야 한다고 상상해 보세요. API 끝점에서 모든 것을 가져오려면 적어도 몇 초는 걸릴 것입니다. 사용자가 다른 페이지로 이동하면 어떻게 됩니까?

당신이 생각하는 경우:

« 어 - 별거 아니야, 어차피 별거 아니야. 기껏해야 데이터가 업로드되고 아무 일도 일어나지 않습니다. »

음 .. 당신이 부분적으로 옳습니다. 아무 일도 일어나지 않을 것입니다. 우리의 업무 덕분에 실수를 저지르는 것은 위험하지 않습니다. 적어도 대부분의 경우에는 항상 개선의 여지가 있으며 가능한 한 많은 네트워크 공간을 확보하고 앱의 데이터 소비를 줄이는 것이 우리의 의무입니다.

끝없이 놀리지 않고 바로 뛰어들자.

통화 취소



먼저 2개의 구성 요소만 렌더링하는 간단한 앱을 만들었습니다.
  • API 호출을 담당하고 리디렉션을 처리할 버튼을 렌더링하는 사람입니다.
  • 다른 구성 요소는 문자열만 렌더링합니다.

  • const App = () => {
        const [apiCallDone, setApiCallDone] = useState(false);
    
        return (
            <div className="App">
                {apiCallDone
                    ? <AnotherComponent />
                    : <ApiCallComponent redirectToOtherComponent={setApiCallDone} />
                }
            </div>
        );
    }
    


    보시다시피 apiCall이 true로 설정되면 App.js는 다시 렌더링하고 다른 구성 요소를 표시합니다.

    이제 실제 호출을 수행하는 구성 요소를 살펴보겠습니다.

    const ApiCallComponent = ({ redirectToOtherComponent }) => {
    
        const [result, setResult] = useState([]);
    
        useEffect(() => {
            fetch('https://pokeapi.co/api/v2/pokemon/12')
                .then(res => res.json())
                .then(data => setResult(data))
        },[]);
    
        const redirect = () => {
           redirectToOtherComponent(true)
        };
    
        return (
            <button onClick={redirect} > Let's call the APi </button>
    )
    };
    
    


    보시다시피 정말 간단한 구성 요소를 재생산합니다. 이 구성 요소는 마운트되는 즉시 Pokémon API를 호출합니다. 그리고 버튼은 props에서 전달한 함수를 트리거합니다.

    멋지지 않습니까? 우리는 문자 그대로 모든 앱의 최소한의 표현을 만들었습니다. 즉, 데이터를 수집하고 소비하며 다른 보기/리디렉션을 표시할 수 있습니다.

    이제 시간 초과를 추가하여 호출에 약간의 지연을 추가해 보겠습니다. 이렇게 하면 느린 인터넷을 모방하게 됩니다.

      useEffect(() => {
            setTimeout(() => {
                fetch('https://pokeapi.co/api/v2/pokemon/12')
                    .then(res => res.json())
                    .then(data => setResult(data))
                    .catch(err => {
                        // Handle error ..
                    })
                }, 3000);
        });
    


    이제 전화를 걸고 3초 타이머 안에 버튼을 클릭해 봅시다..



    여기 우리가 찾고 있던 것이 있습니다. 그리고 이 오류가 무엇인지 아시리라 확신합니다. 이는 구성 요소가 마운트 해제된 동안 구성 요소 상태를 업데이트하려고 한다는 의미입니다. 우리의 예에서는 문자 그대로 마운트 해제 시 API 호출을 취소하지 않았기 때문입니다.

    가져오기 취소



    가져오기 API로 이 문제를 해결하려면 다음을 수행하십시오.

    useEffect(() => {
        // First, create a controller, more infos there : https://developer.mozilla.org/en-US/docs/Web/API/AbortController
        const controller = new AbortController();
    
        setTimeout(() => {
            // Then give it in the fetch options, so the controller is properly linked
            fetch('https://pokeapi.co/api/v2/pokemon/12', {signal: controller.signal})
                .then(res => res.json())
                .then(data => setResult(data))
                .catch(err => {
                    // Handle error ..
                })
        }, 3000);
    
        // Then on the "unmount" of the component, abort the API call ..
        return () => controller.abort();
    }, []);
    


    그게 다야 !

    악시오스




    useEffect(() => {
        // More informations about the cancelation for the axios library here : https://github.com/axios/axios#cancellation
    
        const CancelToken = axios.CancelToken;
        const source = CancelToken.source();
    
        setTimeout(() => {
            axios('https://pokeapi.co/api/v2/pokemon/12', { cancelToken: source.token })
                .then((res) => setResult(res.data) )
                .catch((err) => {
                    // Handle error..
                } )
        }, 3000);
    
        return () => source.cancel();
    }, []);
    


    축하합니다! 이제 이 더러운 오류로부터 콘솔을 지웠습니다!

    API 호출을 생성할 때 더 이상 변명할 필요가 없습니다. 이제 적절하게 처리할 수 있는 모든 도구가 있습니다.

    Othrys website에서 원본 기사를 찾을 수 있으며 이 기사에 대해 토론하기 위해 여기에서 나를 팔로우하거나 나를 태그할 수 있습니다.

    좋은 하루 되세요 !

    좋은 웹페이지 즐겨찾기