Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to useState and useQuery in Apollo/GraphQL and React? [duplicate]

I'm struggling to understand how to best organise my code to set initial useState() in React, while using GraphQL and Apollo to bring in the data. This is my code. As you can see I want to see a part of the 'data' to set the initial state, but when I move setSTate below the loading and error lines, I get the following error:

React Hook "useState" is called conditionally. React Hooks must be called in the exact same order in every component render. Did you accidentally call a React Hook after an early return? react-hooks/rules-of-hooks

How should I be better organising this? Do I have to use Apollo's state management library because I would prefer to use React useState hooks instead.

const GET_LATEST_POSTS = gql`
query {
"graphql query is in here"
}

...

const Slider = () => {

const { data, loading, error } = useQuery(GET_LATEST_POSTS)

if (loading) return 'Loading...'
if (error) return `Error! ${error.message}`

const [ currentMovie, setMovie ] = useState(data)
}
like image 852
unicorn_surprise Avatar asked Dec 01 '22 13:12

unicorn_surprise


2 Answers

you can make use of useEffect in React, like this

const Slider = () => {

    const { data, loading, error } = useQuery(GET_LATEST_POSTS)
    const [ currentMovie, setMovie ] = useState(undefined);

    useEffect(() => {
        if(loading === false && data){
            setMovie(data);
        }
    }, [loading, data])

    if (loading) return 'Loading...'
    if (error) return `Error! ${error.message}`
    // you can check if the currentMovie is undefined and use it to return something
    if(currentMovie) return `Movie ... do something with the currentMovie`

    }
like image 171
Hemanath Avatar answered Dec 03 '22 02:12

Hemanath


Did you accidentally call a React Hook after an early return?

Your error is explained in above line.

According to rules of hook you should not call useState after your component returns something.

const Slider = () => {

const { data, loading, error } = useQuery(GET_LATEST_POSTS)


const [ currentMovie, setMovie ] = useState()

 useEffect(() => {
    if(!loading && data){
        setMovie(data);
    }
  }, [loading, data])

if (loading) return 'Loading...'               //your component's return should always be after all hook calls//
if (error) return `Error! ${error.message}`
}
like image 24
Atin Singh Avatar answered Dec 03 '22 03:12

Atin Singh