使用 typescript、react 和 graphql 以正确方式进行查询的问题
Posted
技术标签:
【中文标题】使用 typescript、react 和 graphql 以正确方式进行查询的问题【英文标题】:Problem with make query in correct way using typescript, react and graphql 【发布时间】:2021-01-26 05:18:13 【问题描述】:请原谅我这个可能很愚蠢的问题,但这是我使用 graphql 并做出反应的第一步。我尝试创建内部是 GraphQL 查询和传入道具的组件。 Props 是一个应该传递给 GraphQL 查询的查询。我知道我做错了什么,但我不知道是什么。我将带有 apollo 提供程序的客户端之类的所有内容添加到我的应用程序组件结构中。 在主页(index.js)上,我的布局很简单:
import Layout from "../components/layout"
import SearchForm from "../components/searchForm"
export default function Home()
return (
<Layout pageTitle="React App" headerTitle="Search repositories on Github">
<SearchForm repositoryNameDefaultValue='' />
</Layout>
);
然后我有一个名为 searchForm 的组件:
import Component, ChangeEvent from "react";
import Input from "./input";
import Button from "./button";
import style from "./searchForm.module.scss";
import FindRepositoryResults from "./test";
interface IMyComponentErrors
repositoryNameError: string;
interface IMyComponentProps
repositoryNameDefaultValue: string;
interface IMyComponentState
repositoryName: string;
formIsSend: boolean;
errors: IMyComponentErrors;
const validateForm = (errors: IMyComponentErrors): boolean =>
let valid = true;
Object.values(errors).forEach((val) => val.length > 0 && (valid = false));
return valid;
;
const validRepositoryNameRegex = RegExp(/^[A-Za-z0-9 _]*[A-Za-z0-9][A-Za-z0-9 _]*$/i);
export default class SignUpFormContainer extends Component<
IMyComponentProps,
IMyComponentState
>
constructor(props: IMyComponentProps)
super(props);
this.state =
repositoryName: this.props.repositoryNameDefaultValue,
formIsSend: false,
errors:
repositoryNameError: "",
;
this.handleFormSubmit = this.handleFormSubmit.bind(this);
this.handleClearForm = this.handleClearForm.bind(this);
this.handleChangeRepositoryName = this.handleChangeRepositoryName.bind(this);
handleChangeRepositoryName(event: ChangeEvent<htmlInputElement>): void
event.preventDefault();
const value = event.target;
let errors = this.state.errors;
if (!validRepositoryNameRegex.test(value))
errors.repositoryNameError = "Invalid repository name";
else if (!value)
errors.repositoryNameError = "Repository name is required";
else
errors.repositoryNameError = "";
this.setState( errors, repositoryName: value );
handleClearForm()
this.setState(
repositoryName: "",
formIsSend: false
);
handleFormSubmit(event)
event.preventDefault();
const repositoryName = this.state;
let errors = this.state.errors;
if (!repositoryName)
errors.repositoryNameError = "Repository name is required";
this.setState( errors );
if (!validateForm(this.state.errors))
return;
else
this.setState( formIsSend: true );
render()
const errors = this.state;
return (
<div>
!this.state.formIsSend ? (
<form
aria-label="Search repositories by name"
autoComplete="off"
onSubmit=this.handleFormSubmit
className = style.formSearchRepository
>
<Input
type="text"
title="Repository name:"
name="repositoryName"
placeholder="Enter name of repository"
value=this.state.repositoryName
error=errors.repositoryNameError.length > 0
errorMessage=errors.repositoryNameError
onChange=this.handleChangeRepositoryName
required
/>
<Button
onClick=this.handleFormSubmit
title="Search repository in Github by name"
children="Search"
/>
</form>
) : <FindRepositoryResults repositoryName=this.state.repositoryName/>
</div>
);
最后一个更成问题的查询在哪里:
import React from "react";
import gql, useQuery from "@apollo/client";
const SEARCH_REPOSITORY = gql`
query findRepositories($query: String!)
search(first: 10, query: $query, type: REPOSITORY)
nodes
... on Repository
name,
owner
login
primaryLanguage
name
,
stargazers
totalCount
,
stargazerCount,
languages(first: 20, orderBy: field: SIZE, direction: ASC )
totalCount
nodes
name
,
issues
totalCount
shortDescriptionHTML,
updatedAt,
watchers
totalCount
`;
interface IFindRepositoryComponentProps
repositoryName: string;
interface IFindRepositoryComponentState
detailsAreOpen: boolean;
interface RepositoryData
data: any;
interface RepositoryVars
query: string;
export default class FindRepositoryResults extends React.Component<IFindRepositoryComponentProps, IFindRepositoryComponentState>
constructor(props: IFindRepositoryComponentProps)
super(props);
this.state = detailsAreOpen: false ;
this.showDetails = this.showDetails.bind(this);
showDetails()
this.setState(state => (
detailsAreOpen: !state.detailsAreOpen
));
render()
const loading, data, error = useQuery<any, RepositoryVars>(
SEARCH_REPOSITORY ,
variables: query: this.props.repositoryName
);
return (
<section>
<h3>Results</h3>
loading ? (
<p>Loading ...</p>
) : error ? (<p>Error error</p>) : (
<div>
data.search.nodes.length == 0 ? (<p>No results found.</p>) : data && data.search.nodes.map((repo) => (
<div>
<p>Name: repo.name</p>
<p>Owner: repo.owner.login</p>
<p>Number of stars (total): repo.stargazerCount</p>
<p>Primary language: repo.primaryLanguage.name</p>
<button onClick=this.showDetails>this.state.detailsAreOpen ? 'Show less' : 'Show more'</button>
<div>
Details:
repo.issues.totalCount
repo.languages.totalCount
repo.shortDescriptionHTML
repo.stargazers.totalCount
repo.updatedAt
repo.watchers.totalCount
</div>
</div>
))
</div>
)
</section>
);
在上面的这个组件中,我进行了查询,但没有得到结果。我不确定,但版本不匹配(DOM 渲染),我在与 typescript、react 和 apollo 一起正确执行此操作时遇到问题。如果有人能告诉我正确的方法和例子,我会很高兴。谢谢
【问题讨论】:
【参考方案1】:我没有使用 typescript,但使用了 React hooks 和 GraphQL。因此,您进行了查询,但没有得到任何结果?如果执行查询,则应该有结果或错误。如果它走得那么远,它可能有助于下载 Apollo-Graphql 插件(也许是谷歌浏览器?)。
例如,我会在 graphi-ql 游乐场中尝试查询。
此外,查询中的变量名查询有点混乱。
最好的,J
【讨论】:
以上是关于使用 typescript、react 和 graphql 以正确方式进行查询的问题的主要内容,如果未能解决你的问题,请参考以下文章
使用 TypeScript 反应 Apollo useQuery 钩子