blade-sensei/learning

Could not find "client" in the context of Apollo(MyComponent). Wrap the root component in an <ApolloProvider> Gatsby

Closed this issue · 3 comments

Context

I want to request GraphQL Server (external API) in the BROWSER (runtime) with Apollo module in Gastby

Solution

  • Instead of wrapping components to get the Apollo Client, i create a Global Context (REACT)
    then i pass the client though all component

See this code

//gatsby-browser.js

import React from "react"
import GlobalContextProvider from "./src/context/GlobalContextProvider"

export const wrapRootElement = ({ element }) => {
  return <GlobalContextProvider>{element}</GlobalContextProvider>
}

//GlobalContextProvider.js

import React, { useState } from "react"
import  ApolloClient  from 'apollo-boost';
export const GlobalStateContext = React.createContext()
export const GlobalDispatchContext = React.createContext()

const token = 'df0ad05d2d05bb3f3790d060860499fd017c2b21';
const client = new ApolloClient({
  uri: 'https://api.github.com/graphql',
  request: (operation) => {
    operation.setContext({
      headers: {
        authorization: `Bearer ${token}`
      }
    })
  }
});


const initialState = {
  client
}

function reducer(state) {
  return state;
}

const GlobalContextProvider = ({ children }) => {
  const [state, dispatch] = React.useReducer(reducer, initialState)
  return (
    <GlobalStateContext.Provider value={state}>
      <GlobalDispatchContext.Provider value={dispatch}>
        {children}
      </GlobalDispatchContext.Provider>
    </GlobalStateContext.Provider>
  )
}

export default GlobalContextProvider

//review.js ( a component that use Client Apollo)

import React, { useState, useEffect, useContext } from "react"
import Layout from "../components/layout"
import Issues from "../components/issues"
import { gql } from "apollo-boost";

import {
  GlobalDispatchContext,
  GlobalStateContext,
} from "../context/GlobalContextProvider"

const Review = () => {
  
  const dispatch = useContext(GlobalDispatchContext)
  const state = useContext(GlobalStateContext)
 
  const [userName, setUserName] = useState(0)
  useEffect(() => {

    console.log(dispatch)
    state.client.query({
      query: gql`
        {
          viewer {
            name
          }
        }
      `
    })
    .then(result => {
      console.log(result)
      setUserName(result.data.viewer.name);
    });

    // get data from GitHub api
  }, [])
  const handleClick = () => {
    setUserName('test');
  }
  console.log(state);

  return (
    <Layout>
      {`test: ${userName}`}
      <button onClick={ handleClick }> change </button>
      <Issues git={userName} />
    </Layout>
  )
}

export default Review

Wrap and context. I didnt tried but I seems useful

https://alligator.io/gatsbyjs/state-management-in-gatsby/