Reactjs 使用GraphQL:TypeError:parse不是函数

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"

我目前正在尝试用对graphql端点的调用替换restful调用,以从服务器检索我的所有
文章。我用
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 v
14.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>
     );
   }
}