我有一个使用 typescript 的 nextjs 应用程序和一个带有 graphql 的 Strapi 后端
我正在尝试简单地从strapi获取graphql并将其显示在react应用程序中。
我正在尝试显示字体名称列表。
在反应中我有这个查询,这在操场上有效
import { gql } from "@/node_modules/@apollo/client/core/index";
export const FONT_DATA = gql`
query font_data{
fonts{
data{
attributes{
font_name
}
}
}
}
`
我正在使用 codegen 生成类型。
export type Font = {
__typename?: 'Font';
createdAt?: Maybe<Scalars['DateTime']['output']>;
font_name?: Maybe<Scalars['String']['output']>;
publishedAt?: Maybe<Scalars['DateTime']['output']>;
updatedAt?: Maybe<Scalars['DateTime']['output']>;
};
export type FontEntity = {
__typename?: 'FontEntity';
attributes?: Maybe<Font>;
id?: Maybe<Scalars['ID']['output']>;
};
export type FontEntityResponse = {
__typename?: 'FontEntityResponse';
data?: Maybe<FontEntity>;
};
export type FontEntityResponseCollection = {
__typename?: 'FontEntityResponseCollection';
data: Array<FontEntity>;
meta: ResponseCollectionMeta;
};
export type FontFiltersInput = {
and?: InputMaybe<Array<InputMaybe<FontFiltersInput>>>;
createdAt?: InputMaybe<DateTimeFilterInput>;
font_name?: InputMaybe<StringFilterInput>;
id?: InputMaybe<IdFilterInput>;
not?: InputMaybe<FontFiltersInput>;
or?: InputMaybe<Array<InputMaybe<FontFiltersInput>>>;
publishedAt?: InputMaybe<DateTimeFilterInput>;
updatedAt?: InputMaybe<DateTimeFilterInput>;
};
export type FontInput = {
font_name?: InputMaybe<Scalars['String']['input']>;
publishedAt?: InputMaybe<Scalars['DateTime']['input']>;
};
在反应中,我有一个简单的页面,我在其中调用查询并尝试显示字体名称
'use client'
import { getDataFromTree } from '@apollo/client/react/ssr'
import withApollo from '../lib/withApollo'
import { FontEntity, FontEntityResponse, FontEntityResponseCollection} from '@/generated'
import { useQuery } from '@apollo/client'
import { FONT_DATA } from '@/graphql/queries'
const Home = () => {
// const data: FontEntityResponse = useThemeContext()?.data;
const {data, loading} = useQuery<FontEntityResponse, FontEntity>(FONT_DATA)
if(loading || !data) return <div>Loading</div>
console.log(Array.isArray(data))
return (
<div>
<ul>
{data?.data?.attributes?.map((font:FontEntity) => (
<li key={font.id}>{font?.font_name}</li>
))}
</ul>
</div>
);
}
export default withApollo(Home, { getDataFromTree });
地图出现
Property 'map' does not exist on type 'Font'
错误,这是因为它不是数组。
console.log 还说它不是数组。
graphql 返回一个对象,但我如何将其与地图一起使用,或者我使用了错误的类型。
更新
如果我这样做
console.log(JSON.stringify(data, null, 2))
我明白了
{
"fonts": {
"__typename": "FontEntityResponseCollection",
"data": [
{
"__typename": "FontEntity",
"attributes": {
"__typename": "Font",
"font_name": "Black"
}
},
{
"__typename": "FontEntity",
"attributes": {
"__typename": "Font",
"font_name": "Jasper"
}
},
{
"__typename": "FontEntity",
"attributes": {
"__typename": "Font",
"font_name": "Varly"
}
},
{
"__typename": "FontEntity",
"attributes": {
"__typename": "Font",
"font_name": "Brother"
}
}
]
}
}
我不确定它如何与 Strapi 一起使用,但通常 graphql 响应看起来像这样:
data.nameOfYourResolver.arrayObjectOrOtherTypeOfData
你的类型全错了。 在你的情况下,它应该看起来像这样:
export type FontEntityResponse = {
fonts: Maybe<FontEntityData>; //object
};
export type FontEntityData = {
data: Maybe<FontEntity[]> //Array
};
export type FontEntity = {
attributes: Maybe<Font>; //Object
export type Font = {
fontName: Maybe<string>; //string
data.fonts.data(attribute => {
console.log(attribute.font_name)
//...
})
再次,我不知道它到底是什么类型的数据,但你的属性名称命名错误
您需要做的就是检查这些属性的类型
fonts{
data{
attributes{
font_name }}}
您可以
console.log(JSON.stringify(data, null, 2))
查看里面的所有数据
另外,我认为在
const {data, loading} = useQuery<FontEntityResponse, FontEntity>(FONT_DATA)
FontEntity 应该用于获取此解析器时使用的变量类型。