Loading Data
Just like views are defined in page and layout variants, your applications queries
are defined in +page.gql and +layout.gql files. Queries must have a unique name:
query ShowList { shows { title }}Just like their equivalent view component, layout queries are designed to “wrap” child routes and are accessible by any child (or sibling) page or layout component.
To access the value of a query, your component just needs to accept a prop with the appropriate name. This could be one query or as many as you have defined. Keep in mind that since this works off of very simple static analysis, your component props must be spread out from the argument like so:
export default function ({ ShowList }) { return ( <> {ShowList.shows.map(show => ( <div> {show.title} </div> ))} </> )}export default function ({ ShowList }) { return (<> {ShowList.shows.map(show => (<div> {show.title} </div>))} </>)}An arrow function would have also worked as long as it had { ShowList } or { ShowList, AnotherQuery }
Query Variables
If your query contains variables with the same name as a route parameter, Houdini will wire the two up.
For example, all you need to do is define this query at src/routes/show/[id]/+page.gql and you can visit /show/123 or /show/abc:
query ShowInfo($id: ID!) { show(id: $id) { name }}Runtime Scalars
An unforunate reality is that not all query variables can be embeded as route paramters. A common example of this is information that’s embedded in your application’s session. To support this, we are working on an experimental API known as Runtime Scalars.
Runtime Scalars
To enable and configure this feature, you must provide an object to the runtimeScalars feature config:
export default { // ... features: { runtimeScalars: { OrganizationFromSession: { type: 'ID', resolve: ({session}) => session.organization } } }}With that defined, you can now use it as a scalar in a query and Houdini will call the configured
resolve function to generate the variable value:
query OrganizationInfo($id: OrganizationFromSession!) { organization(id: $id) { name }}Please keep in mind that this feature is still considered experimental and could change with any minor version.
Imperative Handles
Sometimes you need to perform some imperative task on a query (refetching, loading the next page, etc). For these
situations, you should use the $handle variant on the query prop. For example:
export default function ({ ShowList$handle }) { return ( <> <button onClick={ShowList$handle.loadNextPage}> Load Next </button> {ShowList.shows.map(show => ( <div> {show.title} </div> ))} </> )}export default function ({ ShowList$handle }) { return (<> <button onClick={ShowList$handle.loadNextPage}> Load Next </button> {ShowList.shows.map(show => (<div> {show.title} </div>))} </>)}Loading States
Loading states are one of Houdini’s most powerful features. Apart from one important difference, all of the information in the
guide on loading states applies to the react framework. Hopefully you didn’t just click that link because
it’s important to remember that you have to use isPending from the $houdini package when identifying a pending value. What you
see in that guide (checking if === PendingValue) won’t work with React 18.2.
Another thing to keep in mind is that for the React framework, the presence of @loading implies the existence of a suspense boundary
in your component hierarchy. I know that last sentence might not be totally clear but explaining it more thoroughly will take time so
please be patient.