Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Entry points docs #1

Open
edvinerikson opened this issue Oct 13, 2020 · 10 comments
Open

Entry points docs #1

edvinerikson opened this issue Oct 13, 2020 · 10 comments

Comments

@edvinerikson
Copy link
Member

Entry points

entry points is a pattern in Relay that enables the render-as-you-fetch pattern to be used in a simple way. In practice, it encapsulates a react component and its data requirements (queries) together in a way that allows for parallel data fetching.

Using entry points

The entry point

The entry point is responsible for defining what component and what queries to load.
In order to define an entry point, we would need two things, the JSResourceReference instance, and the getPreloadProps method. Further, in order to use the entry point, we will need a PreloadedEntryPoint and the EntryPointContainer React component.

EntryPointComponent

The EntryPointComponent is the component that you define and that the EntryPointContainer component will render once it's loaded.

The props you specify on your EntryPointComponent will dictate what props you need to define in your getPreloadProps method.

const MyEntryPointComponent: EntryPointComponent<{myQuery: MyQuery}, {}> = ({ queries }) => {
  const data = usePreloadedQuery(graphql`
    query MyQuery {
      hello
    }
  `, queries.myQuery);

  return <h1>{data.hello}</h1>
}

JSResourceReference

Conceptually the JSResourceReference is a way to dynamically fetch a module (like dynamic import), but after it's been imported it will be available synchronously. This is needed for Suspense to work properly, as we will suspend while loading the component, but as soon as it's been loaded once we want to get it synchronously in order to render it.

Within an EntryPoint, this JSResourceReference must return a React component that matches the EntryPointComponent type that Relay provides.

The JSResourceReference type signature is this

type JSResourceReference<T> = {
  getModuleId(): string;
  getModuleIfRequired(): T | null;
  load(): Promise<T>
}

getPreloadProps

The getPreloadProps method is responsible for providing the query id/text and its variables for the queries the component requires. In more advanced use cases it also allows you to define further nested entry points that you want to be preloaded when the parent entry point is loading.

// when acquiring the entry point reference we can pass in parameters, those will be provided to this function.
function getPreloadProps(params) {
  return {
    // we may want to pass some extra props to the react component.
    extraProps: {},
   // nested entrypoints will be defined here
    entryPoints: {},
   // queries will be defined here. 
    queries: {
       myQuery: {
          // the AST generated by relay-compiler
          parameters: MyQueryConcreteRequest,
          // the variables the query may need.
          variables: { name: params.name }
       }
    }
  };
}

EntryPoint

The entry point combines the JSResourceReference and the getPreloadProps method into an object that can be passed to loadEntryPoint and useEntryPointLoader.

const myEntryPoint: EntryPoint<typeof MyEntryPointComponent> = {
  root: makeResource("./MyEntryPointComponent"),
  getPreloadProps(params) {
    return {
      // we may want to pass some extra props to the react component.
      extraProps: {},
      // nested entrypoints will be defined here
      entryPoints: {},
      // queries will be defined here. 
      queries: {
         myQuery: {
            // the AST generated by relay-compiler
            parameters: MyQueryConcreteRequest,
            // the variables the query may need.
            variables: { name: params.name }
         }
      }
    };
  }
}

The container

EntryPointContainer is the React component responsible for rendering the EntryPointComponent. It will suspend if the component is still loading.

It will take an entry point reference and pass the data returned from the getPreloadProps method as props to the EntryPointComponent defined in the root field of the entry point.

The reference

The PreloadedEntryPoint is what you will be passing to the EntryPointContainer component. The PreloadedEntryPoint is a reference to an object holding the in-flight or fetched queries and components. It's the result of loading an entry point.

There are two ways of acquiring a preloaded entry point, through loadEntryPoint and useEntryPointLoader.

You will probably use the useEntryPointLoader hook more often in your code as loadEntryPoint is more suited to be used outside of React, in a router for example. However, it's still useful in case you want to start preloading an entry point before rendering it.

loadEntryPoint

You would want to use this if you are preloading entry points or wanting to use entry points outside of React.

const environmentProvider = {getEnvironment: () => RelayEnvironment};
// pass reference to EntryPointContainer
const reference = loadEntryPoint(environmentProvider, myEntryPoint, {name: "Edvin"})

useEntryPointLoader

useEntryPointLoader provides a React tailored API that can be useful if you want to use entry points within React. For example, tooltips and modals can make use of this.

function MyComponent() {
  const [entryPointReference, loadEntryPoint, disposeEntryPoint] = useEntryPointLoader(myEntryPoint);
  

  return entryPointReference == null ? <button onClick={() => loadEntryPoint({name: "Edvin"})}>Click me</button> : <EntryPointContainer entryPointReference={entryPointReference} props={{ disposeEntryPoint }} />
}
@edvinerikson
Copy link
Member Author

Entry points roadmap

@mickdelaney
Copy link

Is there any update on how to proceed from here ?
is there a package(s), branch or tag to use etc.

@edvinerikson
Copy link
Member Author

There are some docs here: https://relay.dev/docs/api-reference/use-entrypoint-loader/

@fdutey
Copy link

fdutey commented Sep 10, 2021

The docs at https://relay.dev/docs/api-reference/use-entrypoint-loader/ are clearly not complete enough to start using it. A concrete example would be more than welcome.

@tmitchel2
Copy link

It would be good to understand what issue(s) this is meant to solve. Im already heavily invested into relay hooks and it's really not apparent how and when to apply this given I can already render-as-I-fetch...

@mickdelaney
Copy link

It would be good to understand what issue(s) this is meant to solve. Im already heavily invested into relay hooks and it's really not apparent how and when to apply this given I can already render-as-I-fetch...

There’s a YouTube video from the react team on entrypoints that explains it very well.

https://youtu.be/Tl0S7QkxFE4

Around the 19 mins mark

@tmitchel2
Copy link

Thanks... to me it looks like loadQuery() + loadingCode, in my use case in ReactNative the code is all local so perhaps this is not a useful.... I will study it further.

@Albert-Gao
Copy link

Albert-Gao commented Aug 5, 2022

How to use it with react navigation in React native plz?😊

@nibblesnbits
Copy link

The docs at https://relay.dev/docs/api-reference/use-entrypoint-loader/ are clearly not complete enough to start using it. A concrete example would be more than welcome.

Any movement on this in the past 3 years?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants