본문 바로가기
개발/GraphQL , Apollo

useQuery, useLazyQuery와 의존성

by 안뇽! 2022. 3. 26.
반응형

회사에서 graphQL을 주력으로 사용하고 있는데, 나는 graphQL이 익숙치 않아 graphQL연습용 사이드 프로젝트를 진행하고 있다.

useLazyQuery의 존재를 모른 상태에서, useQuery만 이용하여 데이터fetching을 시도했다.

 

버튼이 클릭될때만 데이터를 불러오게 하고 싶었지만, useQuery를 이용하면 매 순간 데이터가 fetching되었다.

 

구글링으로 두가지 사실을 알게 되었다.

  • useQuery는 콜백함수안에서 사용할 수 없고, 컴포넌트가 렌더될때마다 apollo client에 의해 자동으로 실행된다.
  • useLazyQuery는 컴포넌트가 렌더될때가 아닌, 어떠한 이벤트에 대해 Query를 실행하게 해준다.

 

처음에는 아래와 같이 적어주었다.

  const [author, setAuthor] = useState("");

  const [
    searchPoemByAuthor, //onClick안에 넣어줄 함수 이름
    { data: searchingByAuthorData, loading: searchingByAuthorLoading, error: searchingByAuthorError },
  ] = useLazyQuery(GET_POEM_BY_AUTHOR, {
    variables: { author },
    fetchPolicy: "network-only",
  });
  
  const searchTextHandler = (text: string) => {
    console.log(text);
    searchPoemByAuthor();
  };

return (
  <Wrapper>
    <input
          className="bodycontent__searchbox"
          value={author}
          onChange={(e) => {
            setAuthor(e.target.value);
          }}
          type="text"
          placeholder="작가이름 또는 시를 검색해보세요 "
        />
    <button onClick={() => searchTextHandler(author)}>검색</button>
  </Wrapper>
)

그러니 author이 바뀔때마다 useLazyQuery가 작동되는 것이었다.

input박스의 value로 사용한 author값이 바뀔때마다 데이터를 fetching 한다.

아마 매개변수로 사용하는 값에 의존성이 걸리는 것 같다.(가설)

 

그래서 state를 하나 더 만들고 의존성을 바꿔주었더니 문제가 해결 되었다.

 

변경한 코드는 아래와 같다.

  const [author, setAuthor] = useState("");
  const [searchText, setSearchText] = useState("");//추가한 state
  
  const [
    searchPoemByAuthor, //onClick안에 넣어줄 함수 이름
    { data: searchingByAuthorData, loading: searchingByAuthorLoading, error: searchingByAuthorError },
  ] = useLazyQuery(GET_POEM_BY_AUTHOR, {
    variables: { author },
    fetchPolicy: "network-only",
  });
  
  const searchTextHandler = (text: string) => {
    console.log(text);
    //버튼을 클릭할때만 searchText가 변경되고 이때 의존성에 의해 useLazyQuery가 작동되도록 함
    setSearchText(text);
    searchPoemByAuthor();
  };

return (
  <Wrapper>
    <input
          className="bodycontent__searchbox"
          value={author}
          onChange={(e) => {
            setAuthor(e.target.value);
          }}
          type="text"
          placeholder="작가이름 또는 시를 검색해보세요 "
        />
    <button onClick={() => searchTextHandler(author)}>검색</button>
  </Wrapper>
)

 

author의 변화가 아닌, 온클릭이벤트에 의해서만 data fetching이 일어난다.

useLazyQuery의 매개변수를 author(inputbox의 value)가 아닌, 다른 state로 바꿔주니 문제가 해결 되었다.

 

아마 의존성과 관련된 문제가 있는듯하다.

반응형