Warm tip: This article is reproduced from serverfault.com, please click

GraphQL + React: Could not find "client" in the context or passed in as an option

发布于 2020-11-29 18:45:53

Spent a ton of time on this, tried several changes with packages, but still nothing works. I have the following App.js component:

import React, { Fragment } from "react";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import { ApolloClient, ApolloProvider, gql, useQuery } from "@apollo/client";
import cache from "./cache";

// Components
import Landing from "./components/layout/Landing";
import Routes from "./components/routing/Routes";
import Dashboard from "./components/dashboard/Dashboard";

export const typeDefs = gql`
  extend type Query {
    isLoggedIn: Boolean!
  }
`;

const client = new ApolloClient({
  cache,
  uri: "/",
  headers: {
    authorization: localStorage.getItem("token") || "",
  },
  typeDefs,
  resolvers: {},
  dataIdFromObject: (o) => o.id,
});

const IS_LOGGED_IN = gql`
  query IsUserLoggedIn {
    isLoggedIn @client
  }
`;

function IsLoggedIn() {
  const { data } = useQuery(IS_LOGGED_IN);
  return data.isLoggedIn ? (
    <Route exact path="/dashboard" component={Dashboard} />
  ) : (
    <Route exact path="/" component={Landing} />
  );
}

function App() {
  return (
    <ApolloProvider client={client}>
      <Router>
        <Fragment>
          <Switch>
            <Landing />
            <Route component={Routes} />
          </Switch>
        </Fragment>
      </Router>
    </ApolloProvider>
  );
}

export default App;

This component contains a Landing component:

import React from "react";

// Components
import Login from "../auth/Login";

const Landing = () => {
  return (
    <div>
      <Login />
    </div>
  );
};

export default Landing;

... Which, on its turn, contains the Login component:

import React, { Fragment, useState } from "react";
import { Redirect } from "react-router-dom";
import { useMutation } from "@apollo/react-hooks";
import LOGIN_USER from "../../mutations/Login";

const Login = () => {
  const [formData, setFormData] = useState({
    email: "",
    password: "",
  });

  const [login] = useMutation(LOGIN_USER);

  const { email, password } = formData;

  const onChange = (e) =>
    setFormData({ ...formData, [e.target.name]: e.target.value });

  const onSubmit = (formData) => {
    login({ variables: formData })
      .then((res) => {
        localStorage.setItem("token", res.data.login.token);
        localStorage.setItem("userId", res.data.login.userId);
      })
      .then(() => <Redirect to="/dashboard" />);
  };

  return (
    <Fragment>
      <form onSubmit={onSubmit}>
        <div className="form-group">
          <input
            type="email"
            placeholder="Email address"
            name="email"
            value={email}
            onChange={onChange}
          />
        </div>
        <div className="form-group">
          <input
            type="password"
            placeholder="Password"
            name="password"
            value={password}
            onChange={onChange}
          />
        </div>
        <input type="submit" className="btn-primary" value="Sign in" />
      </form>
    </Fragment>
  );
};

export default Login;

And this is the package.json

{
  "name": "client",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@apollo/client": "^3.2.9",
    "@apollo/react-hooks": "^4.0.0",
    "@testing-library/jest-dom": "^5.11.4",
    "@testing-library/react": "^11.1.0",
    "@testing-library/user-event": "^12.1.10",
    "graphql": "^15.4.0",
    "graphql-tag": "^2.11.0",
    "react": "^17.0.1",
    "react-dom": "^17.0.1",
    "react-router-dom": "^5.2.0",
    "react-scripts": "4.0.1",
    "web-vitals": "^0.2.4"
  }

When running the project, I get Could not find "client" in the context or passed in as an option. Wrap the root component in an <ApolloProvider>, or pass an ApolloClient instance in via options. And even though I have the client configured, nothing works. Seen that there's issue with some packages, but seems to me I have the proper ones installed. What am I missing here?

Questioner
Ruham
Viewed
11
nikhil sugandh 2020-11-30 03:47:00

remove:

"@apollo/react-hooks": "^4.0.0",

when using client you dont need to use hooks.

This one for your other question:

import { useMutation } from '@apollo/client';