StarWarsAPI : 2021.02.27 Error: Invalid hook call using 'useQuery' from 'apollo-client'

오범준·2021년 2월 27일
0

PB : Redux-Saga Handler Function > Api Request using 'useQuery' from 'apollo/client' > above Error

Handler Function

function* getShipsSaga(action){
    try{
        
        // call : Want this Req to finish Before move on
        const response = yield call(ReqGetAllShips)
        
        const {data} = response
        
        yield put(setShips(data))
        return;
    }catch(error){
        console.log(error)
        return
    }
    yield put(getShips()) // put : 새로운 액션을 디스패치 시키기
}

API CALL

export const ReqGetAllShips = () => {
    const { loading, error, data } = useQuery(ALL_SHIPS)
    
    return data
}



❤ What is 'Invalid Hook Call' ?

link : https://ko.reactjs.org/docs/hooks-rules.html

Hooks Rule

1) Only call 'Hook' in React Function , Not in Normal Javascript Function

Call Hook in React Function Component

OR

Call Hook in 'Custom Hook'



Trial 1 : change 'ReqGetAllShips ' function into Custom Hook

link : https://ko.reactjs.org/docs/hooks-rules.html

simple way to change normal javascript function into Custom Hook is 'add "use"' in front of function's "name"

function useFriendStatus(friendID) {
  const [isOnline, setIsOnline] = useState(null);

  // ...

  return isOnline;
}

Based on this principal, I can write as

export const useReqGetAllShips = () => {
    const { loading, error, data } = useQuery(ALL_SHIPS)
    return data
}

💔 But, Same Error is occuring



2) Do not call Hooks in class components./ Do not call in event handlers./ Do not call Hooks inside functions passed to useMemo, useReducer, or useEffect.

If you see above,
core menaing of 'breaking rule' is that
calling 'Hook' in place where is 'not' Funcional Component

Component : part of User Interface( place where human and machine interaction occurs ) in React


And let's also see Meaning of 'useQuery' in Apollo

The useQuery React hook is the primary API for executing queries in an Apollo application. To run a query within a React component, call useQuery and pass it a GraphQL query string. When your component renders, useQuery returns an object from Apollo Client that contains loading, error, and data properties you can use to render your UI.

That is,
you use 'useQuery' Hook in
'React Component'


PB : Me calling 'useQuery' hook along the middleware process in which 'Component' is not needed

export const useReqGetAllShips = () => {
    const { loading, error, data } = useQuery(ALL_SHIPS)
    return data
}

it's not a component.
it's job is to fetch api request call and get the data

it's not where machine and human interfactions occur


🧡 Solution : 'grahql-request' library

import { request } from 'graphql-request'
import {ALL_ROCKETS, ALL_SHIPS  } from '../../graphql/queries'

export const useReqGetAllShips = async () => {
    console.log("Api Call happening here")
    
    const data = await request( 'https://spacexdata.herokuapp.com/graphql' , ALL_SHIPS)
    // console.log(JSON.stringify(data['ships'], undefined, 2))
    return data['ships']

};


by above code,
I can make request using graphql-queries and properly pass the data after middleware process

profile
Dream of being "물빵개" ( Go abroad for Dance and Programming)

0개의 댓글