Reputation:
I am using react hook instead of class based component but it is not updating the state when i fetch data from graphql API.
Here you go for my code:
import React, { useEffect, useState } from 'react';
import client from '../gqlClient';
import { gql, ApolloClient, InMemoryCache } from '@apollo/client';
const client = new ApolloClient({
uri: 'http://localhost:8000/graphql/',
cache: new InMemoryCache(),
});
function EmpTable() {
const [employee, setEmployee] = useState({});
useEffect(() => {
client
.query({
query: gql`
query {
employees {
name
}
}
`
})
.then(result => {
setEmployee({result});
console.log(employee);
});
}, [])
return (
<div>return something</div>
)
};
export default EmpTable;
When i print the employee
It prints the initial value only.
But when print result, the console showing all the data that i have from API.
I made the useEffect only run once the page/component is loaded but it is not working.
Can anyone help me how to fix the issue?
Upvotes: 0
Views: 1277
Reputation: 4768
There is another solution that you can use a custom hook to use your returned value in any component you want to use.
import React, { useEffect, useState } from 'react';
import client from '../gqlClient';
import { gql, ApolloClient, InMemoryCache } from '@apollo/client';
const client = new ApolloClient({
uri: 'http://localhost:8000/graphql/',
cache: new InMemoryCache(),
});
const useCustomApi=()=>{
const [employee, setEmployee] = useState({});
useEffect(() => {
client
.query({
query: gql`
query {
employees {
name
}
}
`
})
.then(result => {
setEmployee({result});
});
}, [])
return employee;
}
function EmpTable() {
const employee = useCustomApi();
console.log(employee);
return (
<div>{JSON.stringify(employee,null,2)}</div>
)
};
export default EmpTable;
Upvotes: 0
Reputation: 4768
You need to use useEffect hook to achieve this.
more information about How to use setState
callback on react hooks How to use `setState` callback on react hooks
here is your code should be:
import React, { useEffect, useState } from 'react';
import client from '../gqlClient';
import { gql, ApolloClient, InMemoryCache } from '@apollo/client';
const client = new ApolloClient({
uri: 'http://localhost:8000/graphql/',
cache: new InMemoryCache(),
});
function EmpTable() {
const [employee, setEmployee] = useState({});
useEffect(() => {
client
.query({
query: gql`
query {
employees {
name
}
}
`
})
.then(result => {
setEmployee({result});
});
}, [])
useEffect(() => {
console.log(employee);
}, [employee]);
return (
<div>{JSON.stringify(employee,null,2)}</div>
)
};
export default EmpTable;
Upvotes: 0
Reputation: 8751
setEmployee
is the asynchronous method so you can't get the updated value of employee
immediately after setEmployee
.
setEmployee({result});
console.log(employee); // This will show the old `employee` value.
You should get the updated result in the useEffect
with adding a employee
dependency.
useEffect(() => {
client
.query({
query: gql`
query {
employees {
name
}
}
`
})
.then(result => {
setEmployee({result});
console.log(employee);
});
}, [])
useEffect(() => {
console.log(employee);
}, [employee]);
Upvotes: 2