In my project, I use Typescript, React and Next.js. To fetch data from a API, I did two approachs:
Approach 1
This approach works fine when I call getAllDatasets from getServerSideProps:
ckanApi.ts
// BASE_URL = http://demo.ckan.org/api/3/action/
import axios from "axios"
const ApiCkan = axios.create(process.env.BASE_URL)
export default ApiCkan
datasetLib.ts
export function listDatasets() {
return ApiCkan
.get<DatasetListResponse>( `package_list` )
.then(({ data }) => data.result )
}
export function getDataset(id: string): Promise<DatasetProps> {
return ApiCkan
.get<DatasetInfoResponse>( `package_show?id=${id}` )
.then(({ data }) => data.result)
}
export async function getAllDatasets() {
let allDatasets : DatasetProps[] = []
const datasetsIDs = (await listDatasets())
for (let i = 0; i < datasetsIDs.length; i++ ) {
allDatasets.push( await getDataset( datasetsIDs[i]) )
}
return allDatasets
}
datasets.tsx
export const getServerSideProps = async () => {
return {
props: {
allDatasets: (await getAllDatasets())
}
}
}
Approach 2
I decided put React-Query following the example: https://react-query.tanstack.com/guides/ssr#using-nextjs
_App.js
// ...
import {Hydrate, QueryClient, QueryClientProvider} from 'react-query'
import { ReactQueryDevtools } from 'react-query/devtools'
function MyApp({ Component, pageProps }) {
const [queryClient] = useState(
() =>
new QueryClient({
defaultOptions: {
queries: {
staleTime: 1000 * 120, // 120 seconds
},
},
})
)
return(
<QueryClientProvider client={queryClient}>
<Hydrate state={pageProps.dehydratedState}>
<ThemeProvider theme={theme}>
<Component {...pageProps} />
<GlobalStyle />
</ThemeProvider>
</Hydrate>
<ReactQueryDevtools />
</QueryClientProvider>
)
}
// ...
Default.tsx
//...
import {dehydrate, QueryClient, useQuery} from 'react-query'
export async function getServerSideProps() {
const queryClient = new QueryClient()
await queryClient.prefetchQuery('myData', getAllDatasets )
return {
props: {
dehydratedState: dehydrate(queryClient),
},
}
}
export default function Default({children}: Props ) {
const { data } = useQuery('myData', getAllDatasets)
// ...
In this approach I get a network error "cross-origin request blocked... ...'Access-Control-Allow-Origin' missing on CORS..."
Okay, this needs to defined on server configs. But why this error happen in the second approach but not in the first? Maybe I'm doing something wrong...
I'm trying to use React-Query lib to understand your meaning, and decide if it is good or not for the project. But I don't know yet how it works.