我不能使用 useMutation 或 useQuery Apollo Client 3.0
I can't use useMutation or useQuery Apollo Client 3.0
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
Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
- 您的 React 和渲染器版本可能不匹配(例如 React DOM)
- 您可能违反了 Hooks 规则
- 您可能在同一个应用程序中拥有多个 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);
您不必在任何函数内声明。您必须在两者之间声明您的主要功能组件。像这样
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
You might be breaking the Rules of Hooks
挂钩不能在事件处理程序中使用 - 你只能在'rendering flow'(主 FC 主体)中使用它们......并且需要常量调用挂钩的顺序...所以不在条件块中 (functions/handlers/etc.).
更新:
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
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
Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
- 您的 React 和渲染器版本可能不匹配(例如 React DOM)
- 您可能违反了 Hooks 规则
- 您可能在同一个应用程序中拥有多个 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);
您不必在任何函数内声明。您必须在两者之间声明您的主要功能组件。像这样
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
You might be breaking the Rules of Hooks
挂钩不能在事件处理程序中使用 - 你只能在'rendering flow'(主 FC 主体)中使用它们......并且需要常量调用挂钩的顺序...所以不在条件块中 (functions/handlers/etc.).
更新:
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