[英]Trying to fetch data from a GraphQL API and then pass it as props to a component
我現在很喜歡 GraphQL 和 TypeScript,所以我正在嘗試通過使用這個 API https://github.com/trevorblades/countries來學習它。 我試圖從 API 獲取數據到我的 HomeComponent 中的 React 應用程序,然后將數據傳遞到我的 CountryTable 組件,它是 MUI 庫中的一個表組件。 但是我得到這些錯誤,因為“類型參數不可分配給參數”,“TypeError:countries.map 不是函數”。
這就是我的 HomeComponent 的樣子:
import { Grid } from '@mui/material';
import Typography from '@mui/material/Typography';
import { ApolloClient, InMemoryCache, gql, useLazyQuery, ApolloProvider, useQuery, TypedDocumentNode} from '@apollo/client';
import { useEffect, useState } from 'react';
import React from 'react';
import CountryTable from '../components/CountryTable';
const client = new ApolloClient({
cache: new InMemoryCache(),
uri: 'https://countries.trevorblades.com'
});
const LIST_COUNTRIES = gql`
query getCountries {
countries {
name
code
capital
}}`;
export interface Country {
name: string;
code: string;
capital: string;
}
export interface Countries {
getAllCountries: Country[];
}
export default function Home() {
const {loading, data, error} = useQuery<Countries>(LIST_COUNTRIES, {client});
const [allcountries, setAllcountries] = useState([]);
useEffect(() => {
setAllcountries(data);
}, [data])
if (loading) return <p>Loading...</p>;
if (error) return <p>Error : {error.message}</p>;
return (
<ApolloProvider client={client}>
<Grid container alignItems="center" justifyContent="center">
<Grid item>
<CountryTable countries={allcountries}/>
</Grid>
</Grid>
</ApolloProvider>
)
}
這是我的 CountryTable 組件:
import { Paper, Table, TableBody, TableCell, TableContainer, TableHead, TableRow } from "@mui/material";
import { Country } from "../pages";
export interface CountryProps {
countries: Country[];
}
export default function CountryTable({countries}: CountryProps) {
return(
<TableContainer component={Paper}>
<Table sx={{ minWidth: 650 }} aria-label="simple table">
<TableHead>
<TableRow>
<TableCell align="right">Name</TableCell>
<TableCell align="right">Code</TableCell>
<TableCell align="right">Capital</TableCell>
</TableRow>
</TableHead>
<TableBody>
{countries?.map((row: any) => (
<TableRow key={row.name}>
<TableCell align="right">{row.name}</TableCell>
<TableCell align="right">{row.code}</TableCell>
<TableCell align="right">{row.capital}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
);
}
項目結構: ProjectStructure
您在包裝ApolloProvider
的同一級別調用useQuery
掛鈎。
// Home.js
const {loading, data, error} = useQuery<Countries>(LIST_COUNTRIES, {client}); // 👈 same level
...
...
return (
<ApolloProvider client={client}> {/* 👈 Same level */}
..
..
</ApolloProvider>
)
將您擁有的useQuery
掛鈎從Home
移動到CountryTable
組件的原因是因為現在
CountryTable
在ApolloProvider
里面。useQuery
掛鈎可以訪問它需要的client
數據,這在之前它們被定義在同一級別時是不可能的。 要使其在同一級別工作,請將ApolloProvider
上移一個級別。
這可以是
Home
組件的父組件,如果有的話,_app.js
組件,如果你使用NextJS
[1]參考:
我無法從 GraphQL API 獲取數據的問題是因為我正在檢索的數據是一個整體 object 和我用來保存數據的 useState 變量,因此我可以將它作為道具傳遞給另一個component 是接口 Country 的 ArrayType。 所以我刪除了接口 Countries,然后將我的 const variabel 定義如下:
const {loading, data, error} = useQuery<{countries: Country[]}>(LIST_COUNTRIES, {client});
const [allcountries, setAllcountries] = useState<Country[]>();
然后我接收道具的組件具有以下代碼:
import { Box, Paper, Table, TableBody, TableCell, TableContainer, TableHead, TableRow } from "@mui/material";
import Link from "next/link";
import { useRouter } from "next/router";
import { FC } from "react";
import { Country } from "../pages";
export interface CountryProps {
countries: Country[] | undefined;
}
const CountryTable: FC<CountryProps> = ({countries}) => {
const router = useRouter();
return(
<TableContainer component={Paper}>
<Table sx={{ minWidth: 650 }} aria-label="simple table">
<TableHead>
<TableRow>
<TableCell align="right">Name</TableCell>
<TableCell align="right">Code</TableCell>
<TableCell align="right">Capital</TableCell>
</TableRow>
</TableHead>
<TableBody>
{countries?.map(({name, code, capital}: Country) => (
<TableRow key={name}>
<TableCell align="right">
<Box>
<Link href={{pathname: "/detail/[name]", query: {name: name}}}>
{name}
</Link>
</Box>
</TableCell>
<TableCell align="right">{code}</TableCell>
<TableCell align="right">{capital}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
);
}
export default CountryTable;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.