I am studying GraphQL/Apollow and React, now I want to fetch data using useQuery(or useLazyQuery). More specifically, I have two queries, query B is dependent on the result of query A, that is, I need to skip query B for some query A results, and not skip for other results. Moreover, I want to have loading spinner while fetching data.
My current solution: useEffect with [] parameters + useLazyQuery (Apollo) to only load data for one time, and at the same time updating loading state.
export const QUERY_A = gql `
// something
`
export const QUERY_B = gql `
// something
`
export default function ExampleModal(props: SomeType) {
const [apiStatus, setApiStatus] = React.useState({
loading: false,
error: false
});
let resultA = '';
const[getA] = useLazyQuery(QUERY_A, {
onCompleted: (data) => { // won't set loading to false, as we need to queryB
resultA = data?.getAquery.status
},
onError: (error) => {
setApiStatus({
loading: false,
error: true
});
},
});
let resultB = '';
const[getB] = useLazyQuery(QUERY_B, {
onCompleted: (data) => {
resultB = data?.getBquery.result;
setApiStatus({
loading: false,
error: false,
});
},
onError: (error) => {
setApiStatus({
loading: false,
error: true
});
},
},
skip: resultA == 'something' // this situation,we skip B
);
React.useEffect( () => {
setApiStatus({ // start loading
loading: true,
error: false
});
// fetch real data from A and B,
}, []); // use [] to just load for one time, when re-render, will not call apis again
if (apiStatus.loading) return <div> loading...<div>
if (apiStatatus.error) return <div> error...<div>
return <div> real result <div>
}
I know there may be a few issues here, my questions is:
- does the useEffect will stop immediately after state changes, saying when I
setApiStatus({ // start loading
loading: true,
error: false
});
will the component re-render immediately??
- How to store resultA and resultB, to not let them don't fetched again after re-render(I mean when loading stopped and I can get real result); should I do something like
const [apiStatus, setApiStatus] = React.useState({
loading: false,
error: false,
resultA: '',
resultB: '',
});
will this work?
- I just start, any suggestions for this kind of problems? any best pratices?
thank you so much!