Reactjs 使用GraphQL:TypeError:parse不是函数
我目前正在尝试用对graphql端点的调用替换restful调用,以从服务器检索我的所有Reactjs 使用GraphQL:TypeError:parse不是函数,reactjs,.net-core,graphql,apollo,react-apollo,Reactjs,.net Core,Graphql,Apollo,React Apollo,我目前正在尝试用对graphql端点的调用替换restful调用,以从服务器检索我的所有文章。我用GraphiQL测试了以下查询,它返回了预期的数据。我还使用fiddler手动发布到端点,它的功能与预期一样。我的问题是尝试使用Apollo从react组件调用端点 我目前收到以下错误: TypeError: parse is not a function 从graphql查询返回的数据示例: { "data": { "articles": [ { "id"
文章。我用GraphiQL
测试了以下查询,它返回了预期的数据。我还使用fiddler手动发布到端点,它的功能与预期一样。我的问题是尝试使用Apollo
从react组件调用端点
我目前收到以下错误:
TypeError: parse is not a function
从graphql查询返回的数据示例:
{
"data": {
"articles": [
{
"id": 1,
"description": "desc1"
},
{
"id": 2,
"description": "desc2"
}
]
}
}
以及该部分的全部内容:
import React, { Component } from 'react';
import { Glyphicon } from 'react-bootstrap';
import { LinkContainer } from 'react-router-bootstrap';
import { Query } from "react-apollo";
import gql from "graphql-tag";
export class ArticlesIndex extends Component {
displayName = ArticlesIndex.name
constructor(props) {
super(props);
this.state = { articles: [], loading: true };
}
componentDidMount () {
<Query
query={gql`
query GetArticleData {
articles {
id
description
}
}
`}
>
{({ loading, error, data }) => {
if (loading) return <p>Loading...</p>;
if (error) return <p>Error :(</p>;
console.log(data.articles);
this.setState({articles: data.articles, loading: false});
}}
</Query>
}
renderArticlesTable = articles => {
return (
<table className='table'>
<thead>
<tr>
<th>Id</th>
<th>Title</th>
<th>Description</th>
<th>Edit</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
{articles.map(article =>
<tr key={article.id}>
<td>{article.id}</td>
<td>{article.title}</td>
<td dangerouslySetInnerHTML={{ __html: article.description }}></td>
<td>
<LinkContainer to={'/articles/edit/' + article.id}>
<Glyphicon glyph='edit' />
</LinkContainer>
</td>
<td onClick={(e) => this.deleteArticle(e, article.id) }>
<Glyphicon glyph='trash' />
</td>
</tr>
)}
</tbody>
</table>
);
}
render() {
let contents = this.state.loading
? <p><em>Loading...</em></p>
: this.renderArticlesTable(this.state.articles);
return (
<div>
<h1>Articles</h1>
<LinkContainer to={'/articles/create'}>
<button type="button" className="btn btn-default">New Article</button>
</LinkContainer>
{contents}
</div>
);
}
deleteArticle(event, id) {
fetch('https://localhost:44360/api/articles/' + id, {
method: 'DELETE'
}).then((response) => response.json())
.then((responseJson) => {
var deletedId = responseJson.id;
this.setState({
articles: this.state.articles.filter(function( obj ) {
return obj.id !== deletedId;
})
});
})
}
}
为什么会发生这种情况?我如何克服它
编辑:正如我在别处看到的建议,我将graphql
npm包降级为版本0.12.3
,它在控制台或其他地方没有导致任何错误,但屏幕保持在Loading…
状态,仍然没有向服务器发送任何请求
编辑2:我现在已经尝试了列出的每一种解决方法,在尝试修改webpack配置的建议后,页面不会像以前那样出错,但是没有请求仍然发送到服务器,加载…
永远停留在页面上。正在命中我的componentDidMount
函数中的断点,但似乎什么也没有发生
编辑3:如果我用下面的restful调用替换graphql调用来获取数据,那么一切都会正常进行,但是这个项目的目的是探索如何使用graphql进行反应。我正在尝试替换的正常运行的restful调用如下:
fetch('https://localhost:44360/api/Articles/')
.then(response => response.json())
.then(data => {
this.setState({ articles: data, loading: false });
});
您在componentDidMount
中使用了JSX,而您可以执行this.props.client.query({query:GET_ARTICLES})
,我测试了它,它正在工作
将您的文章/index.js
更改为
import React, { Component } from "react";
import { Glyphicon } from "react-bootstrap";
import { LinkContainer } from "react-router-bootstrap";
import { Query, withApollo } from "react-apollo";
import gql from "graphql-tag";
const GET_ARTICLES = gql`
query GetArticleData {
articles {
id
description
}
}
`;
class ArticlesIndex extends Component {
state = { articles: [], loading: true };
displayName = ArticlesIndex.name;
componentDidMount = () => {
const { client } = this.props;
client
.query({ query: GET_ARTICLES })
.then(({ data: { articles } }) => {
if (articles) {
this.setState({ loading: false, articles });
}
})
.catch(err => {
console.log("err", err);
});
};
renderArticlesTable = articles => {
return (
<table className="table">
<thead>
<tr>
<th>Id</th>
<th>Title</th>
<th>Description</th>
<th>Edit</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
{articles.map(article => (
<tr key={article.id}>
<td>{article.id}</td>
<td>{article.title}</td>
<td dangerouslySetInnerHTML={{ __html: article.description }} />
<td>
<LinkContainer to={"/articles/edit/" + article.id}>
<Glyphicon glyph="edit" />
</LinkContainer>
</td>
<td onClick={e => this.deleteArticle(e, article.id)}>
<Glyphicon glyph="trash" />
</td>
</tr>
))}
</tbody>
</table>
);
};
render() {
let contents = this.state.loading ? (
<p>
<em>Loading...</em>
</p>
) : (
this.renderArticlesTable(this.state.articles)
);
return (
<div>
<h1>Articles</h1>
<LinkContainer to={"/articles/create"}>
<button type="button" className="btn btn-default">
New Article
</button>
</LinkContainer>
{contents}
</div>
);
}
deleteArticle(event, id) {
fetch("https://localhost:44360/api/articles/" + id, {
method: "DELETE"
})
.then(response => response.json())
.then(responseJson => {
var deletedId = responseJson.id;
this.setState({
articles: this.state.articles.filter(function(obj) {
return obj.id !== deletedId;
})
});
});
}
}
export default withApollo(ArticlesIndex);
import React, { Component } from "react";
import { Route } from "react-router";
import { Layout } from "./components/Layout";
import { Home } from "./components/Home";
import ArticlesIndex from "./components/articles/Index";
import { ArticlesCreate } from "./components/articles/Create";
import { ArticlesEdit } from "./components/articles/Edit";
import { ApolloProvider } from "react-apollo";
import ApolloClient from "apollo-boost";
export default class App extends Component {
displayName = App.name;
client = new ApolloClient({
uri: "https://localhost:44360/graphql"
});
render() {
return (
<ApolloProvider client={this.client}>
<Layout>
<Route exact path="/" component={Home} exact={true} />
<Route path="/articles" component={ArticlesIndex} exact={true} />
<Route
path="/articles/create"
component={ArticlesCreate}
exact={true}
/>
<Route
path="/articles/edit/:id"
component={ArticlesEdit}
exact={true}
/>
</Layout>
</ApolloProvider>
);
}
}
问题是您在ComponentDidMount
的内部使用了JSX,这在react中不受支持,为了在生命周期方法中使用查询,您应该使用Apollo
将组件包装成,这样会将客户端添加到道具中(因此使用Apollo导出默认值(ArticlesIndex);
),然后你可以在componentDidMount
中执行this.props.client.query
,然后你可以设置state.你是否有一个模式来检查你编写的查询,我怀疑这是正确的编写方式,但如果你有模式双重检查。这是Graphql版本的问题,你能分享你使用的版本吗?您可能需要对其进行降级或升级。@RachidRhafour I最初使用graphql版本14.1.1,并尝试降级到0.12.3以解决导致我的帖子“编辑”部分中所述行为的问题。我不确定哪个版本可以工作,但我正在使用graphql v14.0.2
和“graphql标签”:“2.10.0”npm版本是5.6.0
更改为您提到的包,但仍然得到相同的错误TypeError:parse不是一个函数
我的用法和您的相同吗?我仍然没有收到任何发送到服务器的请求,这个错误发生在导航到页面时
import React, { Component } from "react";
import { Route } from "react-router";
import { Layout } from "./components/Layout";
import { Home } from "./components/Home";
import ArticlesIndex from "./components/articles/Index";
import { ArticlesCreate } from "./components/articles/Create";
import { ArticlesEdit } from "./components/articles/Edit";
import { ApolloProvider } from "react-apollo";
import ApolloClient from "apollo-boost";
export default class App extends Component {
displayName = App.name;
client = new ApolloClient({
uri: "https://localhost:44360/graphql"
});
render() {
return (
<ApolloProvider client={this.client}>
<Layout>
<Route exact path="/" component={Home} exact={true} />
<Route path="/articles" component={ArticlesIndex} exact={true} />
<Route
path="/articles/create"
component={ArticlesCreate}
exact={true}
/>
<Route
path="/articles/edit/:id"
component={ArticlesEdit}
exact={true}
/>
</Layout>
</ApolloProvider>
);
}
}