[reactjs] useEffect React Hook를 사용할 때 누락 된 종속성 경고를 수정하는 방법?

React 16.8.6 (이전 버전 16.8.3에서는 좋았 음)으로 가져 오기 요청에서 무한 루프를 방지하려고하면이 오류가 발생합니다.

./src/components/BusinessesList.js
Line 51:  React Hook useEffect has a missing dependency: 'fetchBusinesses'.
Either include it or remove the dependency array  react-hooks/exhaustive-deps

무한 루프를 멈추는 해결책을 찾지 못했습니다. 사용하지 않고 싶습니다 useReducer(). 가능한 해결책이 내가하는 일에 확신이없는 https://github.com/facebook/react/issues/14920 이 토론을 찾았습니다. You can always // eslint-disable-next-line react-hooks/exhaustive-deps if you think you know what you're doing.그래서 아직 구현을 시도하지 않았습니다.

나는이 현재 설정을 가지고 있습니다 .React hook useEffect는 영원히 / 무한 루프를 계속 실행 하며 유일한 의견은 useCallback()내가 익숙하지 않은 것입니다.

현재 사용중인 방법 useEffect()(와 비슷한 처음에 한 번만 실행하고 싶습니다 componentDidMount())

useEffect(() => {
    fetchBusinesses();
  }, []);
const fetchBusinesses = () => {
    return fetch("theURL", {method: "GET"}
    )
      .then(res => normalizeResponseErrors(res))
      .then(res => {
        return res.json();
      })
      .then(rcvdBusinesses => {
        // some stuff
      })
      .catch(err => {
        // some error handling
      });
  };



답변

효과 외의 다른 곳에서 fetchBusinesses 메서드를 사용하지 않는 경우 단순히 효과로 옮기고 경고를 피할 수 있습니다.

useEffect(() => {
    const fetchBusinesses = () => {
       return fetch("theURL", {method: "GET"}
    )
      .then(res => normalizeResponseErrors(res))
      .then(res => {
        return res.json();
      })
      .then(rcvdBusinesses => {
        // some stuff
      })
      .catch(err => {
        // some error handling
      });
  };
  fetchBusinesses();
}, []);

그러나 렌더링 외부에서 fetchBusinesses를 사용하는 경우 두 가지 사항에 유의해야합니다.

  1. 마운트가 닫힌 상태에서 마운트 중에 사용될 때 메소드로 전달 되지 않는 문제가 fetchBusinesses있습니까?
  2. 메소드가 엔 클로징 클로저에서받는 일부 변수에 의존합니까? 이것은 당신에게 해당되지 않습니다.
  3. 모든 렌더에서 fetchBusinesses가 다시 작성되므로 useEffect로 전달하면 문제가 발생합니다. 따라서 먼저 fetchBusinesses를 종속성 배열에 전달하려면 메모해야합니다.

요약하면 fetchBusinesses외부에서 useEffect사용하는 경우 규칙을 사용 // eslint-disable-next-line react-hooks/exhaustive-deps하지 않도록 설정할 수 있으며 그렇지 않으면 useEffect 내에서 메소드를 이동할 수 있습니다

규칙을 비활성화하려면 다음과 같이 작성하십시오.

useEffect(() => {
   // other code
   ...

   // eslint-disable-next-line react-hooks/exhaustive-deps
}, []) 


답변

./src/components/BusinessesList.js
Line 51:  React Hook useEffect has a missing dependency: 'fetchBusinesses'.
Either include it or remove the dependency array  react-hooks/exhaustive-deps

JS / React 오류는 아니지만 eslint (eslint-plugin-react-hooks) 경고입니다.

hook은 function에 의존한다는 것을 알려주 fetchBusinesses므로 의존성으로 전달해야합니다.

useEffect(() => {
  fetchBusinesses();
}, [fetchBusinesses]);

함수가 다음과 같이 컴포넌트에서 선언되면 렌더링 할 때마다 함수를 호출 할 수 있습니다.

const Component = () => {
  /*...*/

  //new function declaration every render
  const fetchBusinesses = () => {
    fetch('/api/businesses/')
      .then(...)
  }

  useEffect(() => {
    fetchBusinesses();
  }, [fetchBusinesses]);

  /*...*/
}

매번 함수가 새로운 참조로 다시 선언되기 때문에

이 일을하는 올바른 방법은 다음과 같습니다.

const Component = () => {
  /*...*/

  // keep function reference
  const fetchBusinesses = useCallback(() => {
    fetch('/api/businesses/')
      .then(...)
  }, [/* additional dependencies */])

  useEffect(() => {
    fetchBusinesses();
  }, [fetchBusinesses]);

  /*...*/
}

또는 그냥 함수를 정의 useEffect

더 : https://github.com/facebook/react/issues/14920


답변

useEffect콜백으로 직접 설정할 수 있습니다 .

useEffect(fetchBusinesses, [])

한 번만 트리거되므로 모든 함수의 종속성이 올바르게 설정되어 있는지 확인하십시오 (을 사용하는 것과 동일 componentDidMount/componentWillMount...)


02/21/2020 수정

완전성을 위해 :

1. useEffect위와 같이 함수를 콜백으로 사용

useEffect(fetchBusinesses, [])

2. 내부 기능 선언 useEffect()

useEffect(() => {
  function fetchBusinesses() {
    ...
  }
  fetchBusinesses()
}, [])

3.와 메모 useCallback()

이 경우 함수에 종속성이 있으면 useCallback종속성 배열 에 포함시켜야 useEffect하며 함수의 매개 변수가 변경되면 다시 트리거됩니다 . 게다가, 그것은 많은 상용구입니다 … 그래서 그냥 useEffect에서처럼 함수를 전달하십시오 1. useEffect(fetchBusinesses, []).

const fetchBusinesses = useCallback(() => {
  ...
}, [])
useEffect(() => {
  fetchBusinesses()
}, [fetchBusinesses])

4. eslint의 경고를 비활성화

useEffect(() => {
  fetchBusinesses()
}, []) // eslint-disable-line react-hooks/exhaustive-deps


답변

솔루션은 반응에 의해 제공되며, useCallback함수의 메모 버전을 반환하는 조언을 사용 합니다.

‘fetchBusinesses’함수는 렌더마다 useEffect Hook (NN 라인)의 종속성을 변경합니다. 이 문제를 해결하려면 ‘fetchBusinesses’정의를 자체 useCallback () Hook react-hooks / exhaustive-deps로 랩핑하십시오.

useCallbackuseEffect차이점은 useCallback이 함수를 반환한다는 차이점 과 동일한 서명 을 갖기 때문에 사용이 간단 합니다. 다음과 같이 보일 것입니다 :

 const fetchBusinesses = useCallback( () => {
        return fetch("theURL", {method: "GET"}
    )
    .then(() => { /* some stuff */ })
    .catch(() => { /* some error handling */ })
  }, [/* deps */])
  // We have a first effect thant uses fetchBusinesses
  useEffect(() => {
    // do things and then fetchBusinesses
    fetchBusinesses();
  }, [fetchBusinesses]);
   // We can have many effect thant uses fetchBusinesses
  useEffect(() => {
    // do other things and then fetchBusinesses
    fetchBusinesses();
  }, [fetchBusinesses]);


답변

이러한 경고는 지속적으로 업데이트되지 않는 구성 요소를 찾는 데 매우 유용합니다. https://reactjs.org/docs/hooks-faq.html#is-it-safe-to-omit-functions-from-the-list-of- 의존성 .

그러나 프로젝트 전체에서 경고를 제거하려면 eslint 구성에 추가하십시오.

  {
  "plugins": ["react-hooks"],
  "rules": {
    "react-hooks/exhaustive-deps": 0
    }
  }


답변

이 기사는 후크로 데이터를 가져 오는 좋은 입문서입니다 : https://www.robinwieruch.de/react-hooks-fetch-data/

기본적으로 페치 함수 정의를 다음과 같이 포함하십시오 useEffect.

useEffect(() => {
  const fetchBusinesses = () => {
    return fetch("theUrl"...
      // ...your fetch implementation
    );
  }

  fetchBusinesses();
}, []);


답변

두 번째 인수 유형 배열을 제거 할 수 []있지만 fetchBusinesses()매 업데이트마다 호출됩니다. 원하는 경우 구현에 IF명령문을 추가 할 수 있습니다 fetchBusinesses().

React.useEffect(() => {
  fetchBusinesses();
});

다른 하나는 fetchBusinesses()구성 요소 외부 에서 기능 을 구현하는 것입니다. 의존성 인수를 fetchBusinesses(dependency)호출 에 전달하는 것을 잊지 마십시오 .

function fetchBusinesses (fetch) {
  return fetch("theURL", { method: "GET" })
    .then(res => normalizeResponseErrors(res))
    .then(res => res.json())
    .then(rcvdBusinesses => {
      // some stuff
    })
    .catch(err => {
      // some error handling
    });
}

function YourComponent (props) {
  const { fetch } = props;

  React.useEffect(() => {
    fetchBusinesses(fetch);
  }, [fetch]);

  // ...
}