compose未从react-apollo导出。

12
我正在遵循一个关于GraphQL的YouTube教程(链接为:https://www.youtube.com/watch?v=ed8SzALpx1Q,在3小时16分钟处),其中一部分使用了来自“react-apollo”的compose。然而,由于新版本的react-apollo不再导出它,所以我遇到了错误。
我在网上读到,需要将import { compose } from "react-apollo"替换为import { compose } from "recompose",但是这样做会产生错误TypeError: Cannot read property 'loading' of undefined。我还读到说应该用import * as compose from "lodash"替换来自react-apollo的导入,但是当我这样做时,就会出现其他错误,指出× TypeError:lodash__WEBPACK_IMPORTED_MODULE_2__(...)不是一个函数 App.js:
import React from "react";
import ApolloClient from "apollo-boost";
import { ApolloProvider } from "react-apollo";

import BookList from "./components/BookList";
import AddBook from "./components/AddBook";

//apollo client setup
const client = new ApolloClient({
  uri: "http://localhost:4000/graphql"
});

function App() {
  return (
    <ApolloProvider client={client}>
      <div className="main">
        <h1>My Reading List</h1>
        <BookList />
        <AddBook />
      </div>
    </ApolloProvider>
  );
}

export default App;

queries.js:

import { gql } from "apollo-boost";

const getBooksQuery = gql`
  {
    books {
      name
      id
    }
  }
`;

const getAuthorsQuery = gql`
  {
    authors {
      name
      id
    }
  }
`;

const addBookMutation = gql`
  mutation {
    addBook(name: "", genre: "", authorId: "") {
      name
      id
    }
  }
`;

export { getAuthorsQuery, getBooksQuery, addBookMutation };

AddBooks.js:

import React, { Component } from "react";
import { graphql } from "react-apollo";
import { compose } from "recompose";
// import * as compose from "lodash";
import { getAuthorsQuery, addBookMutation } from "../queries/queries";

class AddBook extends Component {
  state = {
    name: "",
    genre: "",
    authorId: ""
  };

  displayAuthors = () => {
    let data = this.props.data;
    if (data.loading) {
      return <option>loading authors...</option>;
    } else {
      return data.authors.map(author => {
        return (
          <option key={author.id} value={author.id}>
            {author.name}
          </option>
        );
      });
    }
  };

  submitForm(e) {
    e.preventDefault();
    console.log(this.state);
  }

  render() {
    return (
      <form onSubmit={this.submitForm.bind(this)}>
        <div className="field">
          <label>Book name: </label>
          <input
            type="text"
            onChange={e => {
              this.setState({ name: e.target.value });
            }}
          />
        </div>
        <div className="field">
          <label>Genre: </label>
          <input
            type="text"
            onChange={e => {
              this.setState({ genre: e.target.value });
            }}
          />
        </div>
        <div className="field">
          <label>Author: </label>
          <select
            onChange={e => {
              this.setState({ authorId: e.target.value });
            }}
          >
            <option>Select author</option>
            {this.displayAuthors()}
          </select>
        </div>
        <button>+</button>
      </form>
    );
  }
}

export default compose(
  graphql(getAuthorsQuery, { name: "getAuthorsQuery" }),
  graphql(addBookMutation, { name: "addBookMutation" })
)(AddBook);

我原本期望从react-apollo中导入compose,并将查询和变异使它们在AddBook的props内可用,以便我可以在displayAuthors()和submitForm()函数中使用它们,但实际上我得到了错误提示,称它没有从react-apollo中导出,当我尝试在线找到的建议解决方案时,我遇到了以上提到的其他错误。

10个回答

20

compose已从React Apollo 3.0.0中删除。如果您想使用相同的HOC模式,请使用lodash的相同副本flowRight

在您的客户端文件夹中安装lodash。

npm install lodash 

使用这个来从lodash导入compose函数(在flowRight中使用大写的R)

import {flowRight as compose} from 'lodash';

关于重大变更的参考资料


你有一个纯净的解决方案吗? - Kevin
2
我想知道为什么“composer”被移除,在开始使用hack解决方案之前。如果移除了compose,那是因为它是一个不好的实践或者其他原因,那么更好的方法是什么? - Victor Santos
1
compose已被移除 https://github.com/apollographql/react-apollo/blob/e9190fac891dd7af3a1690a5d2a1305953fd5a6f/Changelog.md#breaking-changes,它只是lodash的flowRight的一个副本 https://github.com/apollographql/react-apollo/issues/3330。 - Stéphane Gerber

6

compose在React Apollo 3中已被移除(请查看Breaking Changes). 现在,要使用compose,请使用lodash的flowRight。

安装flowright:

yarn add lodash.flowright

在您的代码中进行替换:

import { compose } from 'react-apollo'

改为:

import {flowRight as compose} from 'lodash';


2

以下是我如何解决这个问题的方法:

  1. 安装lodash.flowright

    npm install lodash.flowright

  2. 在AddBook.js或您想要使用compose的文件中导入它

    import compose from 'lodash.flowright'


2
问题不在于compose。 每当我们合并两个或更多查询时,我们就无法获取“data”属性。 你应该尝试: let data = this.props.getAuthorsQuery;

2

0

这是我在不使用Compose的情况下使其工作的方法。

我使用了useQuery来查询作者,然后使用graphql进行变异。简单地避免嵌套查询,这需要使用compose。

这只是一种绕过Compose(避免)并让教程继续进行的方法,时间非常重要。

import {useQuery} from "@apollo/react-hooks";
import React, {useState} from "react";
import {getAuthorsQuery, addBookMutation} from "../queries/queries.js";
import { graphql } from "react-apollo";
// import { flowRight as compose } from "lodash";
// import {* as compose} from "lodash.flowRight";


const AddBook = (props) => {
const [formData, setFormData] = useState({
    name : "",
    genre : "",
    authorId : ""
});

const authorsData = useQuery(getAuthorsQuery);


function displayAuthors(){

    console.log(authorsData)

    if(authorsData.loading){
        return( <option disabled >Loading Authors...</option> )
    }
    else{
        return( authorsData.data.authors.map(author => {
            return( <option key={author.id} value={author.id}>{author.name}</option>)
        }))
    }
}

function submitForm(e){
    e.preventDefault();
    console.log(formData);
}
    
return(
        <form id="add-book" onSubmit={(e) => submitForm(e)}>
            <div className="field" >  
                <label>Book Name:</label>
                <input type="text" onChange={(e) => setFormData({name : 
e.target.value})}/>
            </div>

            <div className="field" >  
                <label>Genre:</label>
                <input type="text" onChange={(e) => setFormData({genre : 
e.target.value})}/>
            </div>

            <div className="field" >  
                <label>Author:</label>
                <select onChange={(e) => setFormData({authorId : e.target.value})}>
                    <option>Select Author</option>
                    {displayAuthors()}
                </select>
            </div>

        <button>+</button>
    </form>
)}
export default graphql(addBookMutation)(AddBook);

希望这能帮助你完成GraphQL教程,但如果你正在寻找解决组合问题的方法?那么我也在苦苦挣扎。


0

哇,我也在按照Net Ninja的YouTube教程做同样的项目,遇到了同样的错误。实际上,随着时间的推移,react-oppollo的版本已经发生了变化。


0
import React, {Component} from 'react';
import {getAuthersQuery , AddBookMutation } from '../quearies/quearies'

import { gql } from 'apollo-boost'            

import { graphql } from 'react-apollo'        
import {flowRight as compose} from 'lodash';   

2
请不要仅仅发布代码作为答案,还要提供解释您的代码是如何解决问题的。带有解释的答案通常更有帮助和更高质量,并且更有可能吸引赞同。 - Mark Rotteveel

0

我也在尝试跟随他的教程 "https://www.youtube.com/watch?v=rHw0_A4SJxo&list=PL4cUxeGkcC9iK6Qhn-QLcXCXPQUov1U7f&index=31",但在组合网站时卡住了,以下是我如何解决它的方法: - 安装lodash:npm lodash - 导入flowRight:

import React, { Component } from 'react';
//import { compose } from "recompose";
import {flowRight as compose} from 'lodash';
import {graphql} from 'react-apollo';
import {getAuthorsQuery,addBookMutation} from '../queries/queries';

-2

对于这个问题,你不必至少使用lodash

只需嵌套graphql函数即可

export default graphql(addBookMutation)(graphql(getAuthorsQuery)(AddBook))

您可以参考此处

Apollo概念


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接