programing

useEffect React Hook 사용 시 누락된 종속성 경고를 수정하는 방법

muds 2023. 3. 12. 11:26
반응형

useEffect React Hook 사용 시 누락된 종속성 경고를 수정하는 방법

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

./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(). 이 토론 [ESLint]'exhaustive-dep' 보풀 규칙 #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()에는 (1회)와 하고 싶다.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
      });
  };

효과와는 전혀 다른 fetchBusiness 메서드를 사용하지 않는 경우 효과로 이동하여 경고를 피할 수 있습니다.

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

효과 이외의 fetchBusiness를 사용하고 있는 경우는, 2개의 점에 주의해 주세요.

  1. 당신이 합격하지 못한 것에 무슨 문제가 있나요?fetchBusinesses마운트 중에 사용하는 방법으로는 어떤 것이 있습니까?
  2. 당신의 방법은 동봉된 폐쇄로부터 받는 변수에 따라 달라집니까?이것은 너에게 해당되지 않는다.
  3. 모든 렌더에서 fetchBusiness가 다시 생성되므로 useEffect에 전달하면 문제가 발생합니다.따라서 먼저 의존관계 배열에 전달하려면 fetchBusiness를 메모해야 합니다.

요약하자면, 만약 당신이 이 제품을 사용하고 있다면fetchBusinesses of useEffect하지 않도록 설정할 수 .// eslint-disable-next-line react-hooks/exhaustive-deps 않으면 할 수 .

규칙을 비활성화하려면 다음과 같이 작성합니다.

useEffect(() => {
   // other code
   ...
 
   // eslint-disable-next-line react-hooks/exhaustive-deps
}, []) 

새로운 앱을 만들거나 충분한 유연성을 갖춘 경우 상태 관리 라이브러리 옵션이 있습니다.리코일 좀 봐

완전성을 위해:

1.(작업정지) 기능을 다음과 같이 사용 useEffect콜백

useEffect(fetchBusinesses, [])

한다 2. 내부기능을 한다.useEffect()

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

3. 메모 작성

에 의존관계가 있는 , 그 를 「기능의존관계」에.useCallback "Dependencies Array"가 .useEffect함수의 매개 변수가 변경될 경우 다시 표시됩니다. 이 이 사람에게 .useEffect 1. useEffect(fetchBusinesses, []).

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

4. 함수의 기본 인수

베남 아지미의 제안대로

베스트 프랙티스는 아니지만 경우에 따라서는 도움이 될 수 있습니다.

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

5. 커스텀 훅을 작성하다

커스텀 훅을 생성하여 함수를 한 번만 실행해야 할 때 호출합니다.더 깨끗할 수도 있어요.필요에 따라서, 콜백을 반환해 「초기화」를 리셋 할 수도 있습니다.

// customHooks.js
const useInit = (callback, ...args) => {
  const [mounted, setMounted] = useState(false)
  
  const resetInit = () => setMounted(false)

  useEffect(() => {
     if(!mounted) {
        setMounted(true);
        callback(...args);
     }
  },[mounted, callback]);

  return [resetInit]
}

// Component.js
return ({ fetchBusiness, arg1, arg2, requiresRefetch }) => {
  const [resetInit] = useInit(fetchBusiness, arg1, arg2)

  useEffect(() => {
    resetInit()
  }, [requiresRefetch, resetInit]);

6. eslint 경고 비활성화

경고를 비활성화하는 것은 마지막 수단이 될 것입니다.그러나 비활성화 시 인라인으로 명시적으로 실행하는 것이 좋습니다.이는 미래의 개발자가 보풀이 꺼지는 줄 모르고 혼란을 겪거나 예상치 못한 버그를 일으킬 수 있기 때문입니다.

useEffect(() => {
  fetchBusinesses()
}, []) // eslint-disable-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

JavaScript/React 오류가 아니라 ESLint(eslint-plugin-React-hooks) 경고입니다.

는 기능에 .fetchBusinesses이치노

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

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

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

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

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

  /*...*/
}

왜냐하면 함수가 새로운 참조와 함께 다시 선언될 때마다.

올바른 방법은 다음과 같습니다.

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

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

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

  /*...*/
}

그냥 ''에 있는 하면 됩니다.useEffect.

상세: [ESLint] '탈진' 보풀 규칙 14920에 대한 피드백

다음 경고는 지속적으로 업데이트되지 않는 구성 요소를 찾는 데 매우 유용합니다.종속성 목록에서 기능을 생략하는 것이 안전한가?

그러나 프로젝트 전체에서 경고를 제거하려면 ESLint 구성에 다음을 추가할 수 있습니다.

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

반응하다은 에게 사용하라고 한다.useCallback그러면 기능의 메모화 버전이 반환됩니다.

'fetchBusinesss' 함수는 모든 렌더에서 useEffect Hook(라인 NN)의 종속성을 변경합니다.이 문제를 해결하려면 fetch Businesss 정의를 자체 useCallback() Hook react-hooks/exhaustive-deps로 랩합니다.

useCallback는, is as as as as의 가 에, 할 수 .useEffectuse Callback을 사용하다음음음같 뭇매하다

 const fetchBusinesses = useCallback( () => {
        return fetch("theURL", {method: "GET"}
    )
    .then(() => { /* Some stuff */ })
    .catch(() => { /* Some error handling */ })
  }, [/* deps */])
  // We have a first effect that uses fetchBusinesses
  useEffect(() => {
    // Do things and then fetchBusinesses
    fetchBusinesses();
  }, [fetchBusinesses]);
   // We can have many effects that use fetchBusinesses
  useEffect(() => {
    // Do other things and then fetchBusinesses
    fetchBusinesses();
  }, [fetchBusinesses]);
const [mount, setMount] = useState(false)
const fetchBusinesses = () => {
   // Function definition
}
useEffect(() => {
   if(!mount) {
      setMount(true);
      fetchBusinesses();
   }
},[fetchBusinesses, mount]);

이 솔루션은 매우 간단하며 ESLint 경고를 무시할 필요가 없습니다.플래그를 유지하여 컴포넌트의 장착 여부를 확인합니다.

다음 줄에 대해 ESLint를 비활성화합니다.

useEffect(() => {
   fetchBusinesses();
// eslint-disable-next-line
}, []);

이렇게 하면 컴포넌트가 마운트된 것처럼(한 번이라고 함) 사용할 수 있습니다.

갱신했다

또는

const fetchBusinesses = useCallback(() => {
 // Your logic in here
 }, [someDeps])

useEffect(() => {
   fetchBusinesses();
// No need to skip the ESLint warning
}, [fetchBusinesses]);

fetchBusiness는 일부 Dep가 변경될 때마다 호출됩니다.

이 문서는 훅을 사용하여 데이터를 가져오는 방법에 대한 좋은 입문 자료입니다.https://www.robinwieruch.de/react-hooks-fetch-data/

함수 는 fetch function 정의를 fetch fetch function에 합니다.useEffect:

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

  fetchBusinesses();
}, []);

실제로 경고는 후크를 사용하여 개발할 때 매우 유용합니다.하지만 어떤 경우에는, 그것은 당신을 괴롭힐 수 있습니다.특히 종속성의 변화를 들을 필요가 없는 경우.

fetchBusinesses 훅의 콜백을 할 수 .fetchBusinesses디폴트값으로서 다음과 같이 설정합니다.

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

베스트 프랙티스는 아니지만 경우에 따라서는 도움이 될 수 있습니다.

또한 Shubham이 쓴 것처럼 ESLint에 후크 체크를 무시하도록 하기 위해 아래 코드를 추가할 수 있습니다.

// eslint-disable-next-line react-hooks/exhaustive-deps

다음과 같이 시도합니다.

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
        });
  };

그리고.

useEffect(() => {
    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();
}, []);

ID를 경우 에 useEffect ID를 합니다.[id]할 수 React Hook useEffect has a missing dependency: 'any thing'. Either include it or remove the dependency array

배열은 할 수 .[] ,는fetchBusinesses()한또또 업 때 때 、 마 호 、 다 다 다 다 、 해서 '어울리지 않다'를 수 있어요.IF the에 기술하다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]);

  // ...
}

이 좀 더 리액트 에서 리액트가 없는 것, 즉 리액트하지 않는 것, 즉 리액트 옵션이 어떤 .exhaustive-deps효과 내에서 폐쇄 기능을 사용하면 안 되는 이유 중 하나는 모든 렌더에서 다시 생성/파괴됩니다.

에는 여러 메서드는 "React"에 할 필요가 .useEffect 그리고 로, 존관ment depend, 리 의 규칙을 어기지 .react-hooks/exhaustive-deps 두 인 "" " " " " " 입니다.useReducer ★★★★★★★★★★★★★★★★★」useState수입니니다다

const [,dispatch] = useReducer(reducer, {});

useEffect(() => {
    dispatch(); // Non-exhausted - ESLint won't nag about this
}, []);

그 결과, 모든 외부 의존 관계가 리듀서 기능 내에서 현재의 의존 관계와 공존할 수 있습니다.

const [,dispatch] = useReducer((current, update) => {
    const { foobar } = update;
    // Logic

    return { ...current, ...update };
}), {});

const [foobar, setFoobar] = useState(false);

useEffect(() => {
    dispatch({ foobar }); // non-exhausted `dispatch` function
}, [foobar]);

제 경우, 지역 변수와 함께 경고가 표시되었습니다.organization 「 」를 붙이면, 「 」organization에서 " " " "''입니다.useEffect무한정 팔릴 거야따라서 저와 같은 문제가 있으면useEffect'이것'은 다음과 같습니다.

개 API가 됩니다.useEffect러러번 。

송신원:

  const { organization } = useSelector(withOrganization)
  const dispatch = useDispatch()

  useEffect(() => {
    dispatch(getOrganization({}))
    dispatch(getSettings({}))
    dispatch(getMembers({}))
  }, [dispatch, organization])

수신인:

  const { organization } = useSelector(withOrganization)
  const dispatch = useDispatch()

  useEffect(() => {
    dispatch(getOrganization({}))
    dispatch(getSettings({}))
  }, [dispatch, organization])

  useEffect(() => {
    dispatch(getMembers({}))
  }, [dispatch])

이는 질문의 사용 사례에 고유한 답변이 아니라 보다 일반적인 사례이며 useEffect 또는 추출 및 Import가 작동하지 않는 경우를 대상으로 합니다.useRef senario:

경우에 따라서는 useEffect에 빈 배열이 있어야 하지만 여전히 상태의 useEffect 부분 내에서 사용하고 싶지만 의존관계로 삽입하고 싶지 않을 수도 있습니다.useCallback을 시도하면 useCallback의 의존관계에 대해 불만을 표시하여 stuck이 됩니다.이 경우 다음과 같이 useRef를 사용할 수 있습니다.

const locationRef = useRef(location);
useEffect(()=>{
const qs = locationRef.current.search
...
},[])

이 기술을 사용할 때는 주의해야 하며 useRef는 렌더링 프로세스를 활성화하지 않습니다.

이 Es-lint 경고는 참조를 전달하여 제거할 수 있습니다.

아래에 기재되어 있는 예이지만, 이 링크에서는 솔루션을 보실 수 있습니다.https://www.youtube.com/watch?v=r4A46oBIwZk&t=8s

경고: 13:8 행: React Hook React.useEffect에 'history' 및 'currentUser' 종속성이 없습니다.역할'을 포함하거나 종속 배열 react-hooks/exhaustive-deps를 삭제합니다.

React.useEffect(() => {
    if (currentUser?.role !== "Student") {
        return history.push("/")
    }
}, [])

해상도:1단계: 비즈니스 로직을 다른 Const로 이동합니다.

이 경고는 다음과 같습니다.React Hook React.useEffect에는 의존관계가 누락되어 있습니다.RoleChecking' 입니다.

const roleChecking = () =>{
   if (currentUser?.role !== "Student") {
        return history.push("/")
    }
}

React.useEffect(() => {
    roleChecking()
}, [])

마지막 단계는 함수에 대한 참조를 만드는 것입니다.

  const roleRef = React.useRef();

  const roleChecking = () => {
    if (currentUser?.role !== "Student") {
      return history.push("/");
    }
  };
  roleRef.current = roleChecking;

  React.useEffect(() => {
   return roleRef.current();
  }, [currentUser?.role]);

그런 것 같아요fetchBusinesses이치노는 모든 합니다.

이 문제를 해결하려면 두 가지 방법이 있습니다.

  1. fetchBusinesses구성 요소에서 함수 선언이 발생했습니다.

  2. 를를 wrap wrap fetchBusinesses useCallback

첫 번째 옵션이 바람직합니다.

각 경고에 대한 자세한 내용을 보려면 키워드를 검색하십시오.무시하려면 // eslint-disable-next-line을 앞의 행에 추가합니다.

예:useEffect에서 사용된 함수가 경고를 발생시키고 있습니다.

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

경고를 무시하려면 경고 줄 앞에 "// eslint-disable-next-line"을 추가합니다.

useEffect(() => {
  handleConnectWallet();
  // eslint-disable-next-line
}, []);

이 불필요한 메시지를 비활성화하려면 파일 시작 부분에 이 메시지를 추가하십시오.

/* eslint-disable react-hooks/exhaustive-deps */

그러면 파일 전체에 대한 경고가 비활성화됩니다.

이 하고 있는 가 있는 경우 useEffect컴포넌트 내부에서 정의되거나 컴포넌트에 소품으로 전달됩니다.「 」를 정의했기 에,fetchBusinesses() 컴포넌트 및 " " " "eslint이 규칙에 따라 종속 배열에 전달해야 합니다.를 그냥 .

만, 만약 「 」가 하면 어떻게 됩니까?fetchBusinesses컴포넌트가 되므로 setState가 다시 됩니다.★★★★★★★★★★★★★★★★★★,fetchBusinesses루프가 됩니다.useEffect는 무한 루프를 생성합니다.따라서 맹목적으로 eslint를 따르는 것은 추가적인 버그를 유발할 수 있습니다.

eslint를 를 행복하게 하는 useCallback[ ] [ [ [

const memoizedFetchBusinesses=useCallback(
        fetchBusinesses,
        [] // unlike useEffect you always have to pass a dependency array
       )

렌더링될 때 '''''라고.fetchBusinessess되어 「」가 됩니다.memoizedFetchBusinesses메모리 내의 동일한 기능을 참조하는 변수가 생성됩니다.

리렌더 뒤에 fetchBusinessess[ ](으)는 [ 으)는 [ ](으)로 있기 됩니다.useCallback,memoizedFetchBusinesses을 .fetchBusinesses같은 메모리내에서 기능합니다. useCallback여기에서는 컴포넌트의 첫 번째 렌더링에서 생성된 함수와 동일한 참조를 제공합니다.

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

대신 다음과 같은 함수를 정의할 수 있습니다.

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

그 후 사용효과

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

함수를 useEffect 배열의 인수로 전달하기만 하면 됩니다.

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

UseEffect ★fetchBusinesses는 " "로 합니다.useEffect()의 이름을 한 후에 으로써 const를 선언합니다

useEffect(()=>{
const fetchBusinesses=()=>{
   console.log(useeffect fetchbussinesses functions)
}
 fetchBusinesses();
},[declare the variable used in useeffect hooks ])

프로젝트에서 이 경고를 실행 중지하려면 다음과 같이 하십시오.

말을 덧붙이다"react-hooks/exhaustive-deps": "off"로로 합니다..eslintrc.js

이 말을 쓰고 있어요.useEffect이 경우 컴포넌트 내부의 소품이나 스테이트로 사용되는 변수를 자주 사용하게 됩니다.

에는 eslint 어떤 수 있는 .이 규칙은 다른 소품이나 상태의 일부를 참조하도록 합니다.useEffect배열은 언제가 될지를 입니다.useEffect 되도록 하고, 그 배열에 따라 합니다.이것에 의해, 재실행의 타이밍이 정해집니다.useEffect★★★★★★ 。

때문에 '아까운데'를 할 거예요.[fetchBusinesses]경고는 사라져야 합니다.

자, 왜 그 규칙에서 그걸 넣어야 하죠?

를 들어, '어느 정도'를 .useEffect어레이 내의 모든 상태 및 소품을 올바르게 나열하지 않으면 이상하고 디버깅하기 어려운 문제가 발생할 수 있습니다.

이 은 이해하기 입니다.useEffect.

이 어레이에 임의로 추가해도 버그가 발생할 수 있습니다.어느 쪽이든 버그에 부딪혔을 때는 해결해야 합니다.이 될 것 , 만약 이 두 번째 를 얻을 수 더 것입니다.GETChrome의 [네트워크(Network)]에서 요청을 합니다.fetchBusinessesuseEffectmanager.manager로 하다

언급URL : https://stackoverflow.com/questions/55840294/how-to-fix-missing-dependency-warning-when-using-useeffect-react-hook

반응형