【问题标题】:I can't use useMutation or useQuery Apollo Client 3.0我不能使用 useMutation 或 useQuery Apollo Client 3.0
【发布时间】:2020-11-08 19:43:06
【问题描述】:
  import { useMutation } from '@apollo/client';;
        
  function LockedBlog() {
  const [lockedBlog] = useMutation(LOCKED_BLOG);
  };

  class EditBlog extends Component {
    state = {
      ...initialState
    };

index.js

import React from "react";
import ReactDOM from "react-dom";
import "./light.scss";
import App from "./components/App";
import { ApolloProvider } from '@apollo/client'
import { ApolloClient } from '@apollo/client/core';
import {ApolloLink} from 'apollo-link';
import {SubscriptionClient} from 'subscriptions-transport-ws';
import {WebSocketLink} from 'apollo-link-ws';
import {createHttpLink} from 'apollo-link-http';
import {InMemoryCache } from '@apollo/client/cache';
import { onError } from 'apollo-link-error';

const errorLink = onError(({ networkError, graphQLErrors }) => {
  if (graphQLErrors) {
    graphQLErrors.map(({ message, locations, path }) =>
      console.log(
        `[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`,
      ),
    );
  }
  if (networkError) console.log(`[Network error]: ${networkError}`);
});

const middlewareLink = new ApolloLink((operation, forward) => {
  operation.setContext({
    headers: {
      authorization: localStorage.getItem('token') || null
    }
  });
  return forward(operation);
});

const wsLink = new WebSocketLink(
  new SubscriptionClient("ws://localhost:4004/graphql", {
    reconnect: true,
  }),
);

const httpLink = middlewareLink.concat(
  createHttpLink({
    uri: "http://localhost:4004/graphql",
  })
);

const hasSubscriptionOperation = ({query: {definitions}}) => {
  return definitions.some(({kind, operation}) => kind === 'OperationDefinition' && operation === 'subscription');
}

const link = ApolloLink.split(
  hasSubscriptionOperation,
  wsLink,
  httpLink,
  errorLink,
);

const client = new ApolloClient({
  link,
  cache: new InMemoryCache(),
});

ReactDOM.render(
  <React.Fragment>
    <ApolloProvider client={client}>
      <App />
    </ApolloProvider>
  </React.Fragment>,
  document.getElementById("root")
);

我的 package.json

"@apollo/client": "^3.0.2",
"@apollo/react-hooks": "^3.1.5",
"@material-ui/core": "^4.10.2",
"@material-ui/icons": "^4.9.1",
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.3.2",
"@testing-library/user-event": "^7.1.2",
"Dante2": "^0.5.0-rc4",
"apollo-boost": "^0.4.9",
"apollo-cache-inmemory": "^1.6.6",
"apollo-client": "^2.6.10",
"apollo-link": "^1.2.14",
"apollo-link-error": "^1.1.13",
"apollo-link-http": "^1.5.17",
"apollo-link-ws": "^1.0.20",
"apollo-upload-client": "^13.0.0",
"env-cmd": "^10.1.0",
"graphql": "^15.1.0",
"graphql-tag": "^2.10.4",
"jsonwebtoken": "^8.5.1",
"lodash.flowright": "^3.5.0",
"moment": "^2.27.0",
"node-sass": "^4.14.1",
"prismjs": "^1.20.0",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-dropzone": "^11.0.1",
"react-router-dom": "^5.2.0",
"react-scripts": "3.4.1",
"subscriptions-transport-ws": "^0.9.16"

我在使用它时收到此错误。我迁移了 apollo 客户端 3.0

错误:无效的挂钩调用。 Hooks 只能在函数组件的主体内部调用。这可能是由于以下原因之一:

  1. 您可能有不匹配的 React 版本和渲染器(例如 React DOM)
  2. 您可能违反了 Hooks 规则
  3. 您可能在同一个应用中拥有多个 React 副本

这里有很多人遇到同样的错误。并没有找到解决方案。 https://github.com/apollographql/react-apollo/issues/3454

已解决

import { withApollo } from '@apollo/client/react/hoc';

// class component 

componentDidMount() {
    this.lockedBlog(true);
  }

  componentWillUnmount() {
    this.lockedBlog(false);
  }

  lockedBlog = locked => {
    const { id } = this.props.match.params;
    this.props.client
      .mutate({
        variables: { id, locked },
        mutation: gql`
          mutation($id: ID!, $locked: Boolean!) {
            lockedBlog(id: $id, data: { locked: $locked }) {
              locked
            }
          }
        `
      })
      .then(result => {
        console.log(result);
      })
      .catch(error => {
        console.log(error);
      });
  };

并导出

export default withApollo(EditBlog);

【问题讨论】:

    标签: javascript reactjs graphql apollo


    【解决方案1】:

    您不必在任何函数中声明。您必须在两者之间声明您的主要功能组件。像这样

    const [lockedBlog] = useMutation(LOCKED_BLOG);
    
    lockedBlog = locked => {
     const { id } = this.props.match.params;
     lockedBlog({variables:{ Your data that you have passed }})
     console.log(locked);
    };
    

    如果有更多关于如何使用 useMutation 的详细信息,那么这里是docs

    【讨论】:

    • const [lockedBlog] = useMutation(LOCKED_BLOG);单独使用它时也会出现错误。我不需要运行它。
    • 当我在任何地方使用 useMutation 时出现反应错误。 github.com/apollographql/react-apollo/issues/3454同样的错误
    • 这个缺少的博客是在功能组件还是类组件中?
    【解决方案2】:

    你可能违反了 Hooks 规则

    钩子不能在事件处理程序中使用 - 您只能在“渲染流程”(主要 FC 主体)中使用它们......并且需要调用挂钩的恒定顺序.. . 所以不在条件块中(函数/处理程序/等)。

    更新:

    const LockedBlog = (props) => {
      const [lockedBlog] = useMutation(LOCKED_BLOG);
      
      lockedBlogHandler = (e, someId) => {
        // const { id } = props.match.params;
        lockedBlog({variables:{ Your data that you have passed }}) // call invoker returned from useMutation
        // with variables prepared from component props, handler passed someId, etc.
        console.log(someId);
      };
      return (
        <Button onClick={lockedBlogHandler} >
        // search docs how to pass args into handler
    

    【讨论】:

    • 这并不重要,现在我这样做是为了测试目的,我在任何地方都会遇到同样的错误。 * 你不需要给 - 分。 @xadm
    • bad usage 不需要解决方案,根据文档中描述的环境要求调整代码 .... 整个组件/应用程序代码以显示使用上下文?
    • 谢谢,我有问题。这个功能已经在课堂上工作了。像这样。 ''' componentDidMount() { this.lockedBlog(true); ' 并且我想在页面加载时运行此功能,除了组件我将如何做呢?它适用于componentDidmount。没有它我该怎么办? @xadm
    • 我在问题中写得很清楚。该功能已经在课堂上。我更新了代码
    • 钩子仅用于功能组件 - 在类中使用&lt;Mutation/&gt; 组件
    猜你喜欢
    • 2020-08-10
    • 2020-06-04
    • 1970-01-01
    • 2021-05-27
    • 2022-06-21
    • 2021-08-25
    • 2021-03-11
    • 2021-04-04
    • 2023-04-10
    相关资源
    最近更新 更多