Programing

이것은 "조기 귀국 후 실수로 리액션 훅을 호출했는가?"를 피하는 안전한 방법이다.

c10106 2022. 4. 1. 20:23
반응형

이것은 "조기 귀국 후 실수로 리액션 훅을 호출했는가?"를 피하는 안전한 방법이다.

나는 다음과 같은 기능 구성요소를 작성했다.

export const SiteMap: React.FunctionComponent = () => {

  return useGetSetData<I.SiteMap>({
    title: "Site Map",
    getData: () => IO.getSiteMap(),
    showData: Page.SiteMap
  });
}

그것은 효과가 좋다.

그런데, 나의useGetSetData"고차 구성요소" 함수로,useState그리고useEffect데이터를 가져온 다음 해당 데이터를 (가져온 후) 표시할 전달된 프리젠테이션 구성요소로 전달한다.매개변수는 다음과 같다.

interface UseGetDataPropsT<T> {
  title: string,
  getData: () => Promise<T>,
  showData: (data: T) => ReactElement
}

어쨌든, 다음에 내가 이것을 시도할 때, URL의 다른 것에 의존하는 페이지의 내용인데, 나는 이렇게 코드화한다.

type RouterProps = ReactRouter.RouteComponentProps<any>;

export const Image: React.FunctionComponent<RouterProps> = (props: RouterProps) => {

  const imageId: number | undefined = getId(props, "Image");
  if (!imageId) {
    return NoMatch(props);

  return useGetSetData<I.Image>({
    title: "Image",
    getData: () => IO.getImage(imageId),
    showData: Page.Image
  });
}

그러면 다음과 같은 오류 메시지가 생성된다.

반응 후크 "useGetSetData"를 조건부로 부른다.리액션 후크는 모든 구성 요소 렌더에서 정확히 동일한 순서로 호출되어야 한다.일찍 돌아온 후 실수로 리액션 훅을 호출하셨습니까?리액션 훅/리액션 오프 훅

만약 내가 그것을 다음과 같이 되뇌면 그것은 효과가 있다.

export const Image: React.FunctionComponent<RouterProps> = (props: RouterProps) => {

  const imageId: number | undefined = getId(props, "Image");
  if (!imageId) {
    return NoMatch(props);

  return ImageId(imageId);
}

export const ImageId: React.FunctionComponent<number> = (imageId: number) => {
  return useGetSetData<I.Image>({
    title: "Image",
    getData: () => IO.getImage(imageId),
    showData: Page.Image
  });
}

이것은 사소한 변화, 즉 기능적으로 내가 전에 코딩했던 것과 동일하다.

위의 오류 메시지를 피하고, 올바르게 작용하는 것으로 보인다.


제 질문은:

  • 내 해결책은 안전한가? 즉, 이 코드는 괜찮은가?
  • 그렇지 않다면 어떤 상황에서 실패할 수 있는가?

안전하지 않다,react-hooks/rules-of-hooks네가 속았다는 것을 깨닫기에 충분히 현명하지 못한(기분) 에슬린트 규칙일 뿐이다.

https://overreacted.io/why-do-hooks-rely-on-call-order/에서 설명한 바와 같이, 문제는 정확히 이전과 동일하다.

해결책은 (후크를 무조건 후크라고 부르는) 개별 구성요소를 조건부로 렌더링하는 것이다. => 사용React.createElement(ImageId...)일반 함수를 호출하는 대신 JSX:

  if (!imageId) {
    return <NoMatch {...props} />};
  }

  return <ImageId {...{imageId}} />;

참조URL: https://stackoverflow.com/questions/55990985/is-this-a-safe-way-to-avoid-did-you-accidentally-call-a-react-hook-after-an-ear

반응형