11import 'regenerator-runtime/runtime.js' ;
2- import * as React from 'react' ;
2+ import React , { useState , useEffect , useMemo } from 'react' ;
33import { createRoot } from 'react-dom/client' ;
44import { GraphiQL } from 'graphiql' ;
55import { explorerPlugin } from '@graphiql/plugin-explorer' ;
66import { getSnippets } from './snippets' ;
77import { codeExporterPlugin } from '@graphiql/plugin-code-exporter' ;
8- import 'graphiql/style.css' ;
9- import '@graphiql/plugin-explorer/style.css' ;
10- import '@graphiql/plugin-code-exporter/style.css' ;
118import { createGraphiQLFetcher } from '@graphiql/toolkit' ;
129import { useStorage } from '@graphiql/react' ;
13-
14- export const STARTING_URL =
15- 'https://swapi-graphql.netlify.app/.netlify/functions/index' ;
16-
17- import './index.css' ;
1810import { serverSelectPlugin , LAST_URL_KEY } from './select-server-plugin' ;
11+ import './index.css' ;
12+
13+ export const STARTING_URL = 'https://countries.trevorblades.com' ;
1914
2015if ( 'serviceWorker' in navigator ) {
2116 window . addEventListener ( 'load' , ( ) => {
2217 navigator . serviceWorker
2318 . register ( '/service-worker.js' )
2419 . then ( registration => {
25- console . log ( 'SW registered: ' , registration ) ;
20+ console . log ( 'SW registered:' , registration ) ;
2621 } )
2722 . catch ( registrationError => {
28- console . log ( 'SW registration failed: ' , registrationError ) ;
23+ console . error ( 'SW registration failed:' , registrationError ) ;
2924 } ) ;
3025 } ) ;
3126}
@@ -59,24 +54,21 @@ const style = { height: '100vh' };
5954 */
6055const explorer = explorerPlugin ( ) ;
6156
62- const App = ( ) => {
63- // TODO: `storage` will be always `null`, fix it to have access outside `StorageContextProvider` after zustand migration
64- const storage = useStorage ( ) ;
65- const lastUrl = storage ?. get ( LAST_URL_KEY ) ;
66- const [ currentUrl , setUrl ] = React . useState ( lastUrl ?? STARTING_URL ) ;
57+ function App ( ) {
58+ const [ currentUrl , setUrl ] = useState ( '' ) ;
6759 // TODO: a breaking change where we make URL an internal state concern, and then expose hooks
6860 // so that you can handle/set URL state internally from a plugin
6961 // fetcher could then pass a dynamic URL config object to the fetcher internally
70- const exporter = React . useMemo (
62+ const exporter = useMemo (
7163 ( ) =>
7264 codeExporterPlugin ( { snippets : getSnippets ( { serverUrl : currentUrl } ) } ) ,
7365 [ currentUrl ] ,
7466 ) ;
75- const fetcher = React . useMemo (
67+ const fetcher = useMemo (
7668 ( ) => createGraphiQLFetcher ( { url : currentUrl } ) ,
7769 [ currentUrl ] ,
7870 ) ;
79- const serverSelect = React . useMemo (
71+ const serverSelect = useMemo (
8072 ( ) => serverSelectPlugin ( { url : currentUrl , setUrl } ) ,
8173 [ currentUrl ] ,
8274 ) ;
@@ -87,9 +79,26 @@ const App = () => {
8779 plugins = { [ serverSelect , explorer , exporter ] }
8880 fetcher = { fetcher }
8981 shouldPersistHeaders
90- />
82+ >
83+ < GraphiQLStorageBound setUrl = { setUrl } />
84+ </ GraphiQL >
9185 ) ;
92- } ;
86+ }
87+
88+ /**
89+ * `useStorage` is a context hook that's only available within the `<GraphiQL>`
90+ * provider tree. `<GraphiQLStorageBound>` must be rendered as a child of `<GraphiQL>`.
91+ */
92+ function GraphiQLStorageBound ( { setUrl } ) {
93+ const storage = useStorage ( ) ;
94+ const lastUrl = storage . get ( LAST_URL_KEY ) ?? STARTING_URL ;
95+
96+ useEffect ( ( ) => {
97+ setUrl ( lastUrl ) ;
98+ } , [ lastUrl , setUrl ] ) ;
99+
100+ return null ;
101+ }
93102
94103const root = createRoot ( document . getElementById ( 'root' ) ) ;
95104root . render ( < App /> ) ;
0 commit comments