-
Notifications
You must be signed in to change notification settings - Fork 2
Description
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 }} />
}