Skip to content

Commit

Permalink
More random fixes for React bindings (#1297)
Browse files Browse the repository at this point in the history
  • Loading branch information
AlecAivazis committed Apr 25, 2024
1 parent e636868 commit d1686d0
Show file tree
Hide file tree
Showing 9 changed files with 83 additions and 22 deletions.
5 changes: 5 additions & 0 deletions .changeset/witty-cherries-visit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'houdini-react': patch
---

fix bug with useRoute pulling route params
1 change: 1 addition & 0 deletions packages/houdini-react/src/plugin/vite.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@ export default {
observer.send({
setup: true,
variables,
session: window.__houdini__initial__session__,
})
// save it in the cache
Expand Down
2 changes: 1 addition & 1 deletion packages/houdini-react/src/runtime/clientPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { ClientPlugin } from 'houdini'

const plugin: () => ClientPlugin = () => () => {
return {
beforeNetwork(ctx, { next }) {
start(ctx, { next }) {
next({
...ctx,
cacheParams: {
Expand Down
21 changes: 18 additions & 3 deletions packages/houdini-react/src/runtime/hooks/useDocumentHandle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import type {
} from '$houdini/runtime/lib/types'
import React from 'react'

import { useClient, useSession } from '../routing/Router'
import { useClient, useLocation, useSession } from '../routing/Router'

export function useDocumentHandle<
_Artifact extends QueryArtifact,
Expand All @@ -32,6 +32,7 @@ export function useDocumentHandle<
}): DocumentHandle<_Artifact, _Data, _Input> & { fetch: FetchFn<_Data, _Input> } {
const [forwardPending, setForwardPending] = React.useState(false)
const [backwardPending, setBackwardPending] = React.useState(false)
const location = useLocation()

// grab the current session value
const [session] = useSession()
Expand Down Expand Up @@ -62,11 +63,25 @@ export function useDocumentHandle<
}

// add the session value to the
const fetchQuery: FetchFn<_Data, _Input> = (args) =>
observer.send({
const fetchQuery: FetchFn<_Data, _Input> = (args) => {
// before we send the query, we need to figure out which variables are
// actually useful for this document
const usedVariables = Object.fromEntries(
Object.keys(observer.artifact.input?.fields ?? {}).map((fieldName) => [
fieldName,
location.params[fieldName],
])
)

return observer.send({
...args,
variables: {
...usedVariables,
...args?.variables,
},
session,
})
}

// only consider paginated queries
if (artifact.kind !== ArtifactKind.Query || !artifact.refetch?.paginated) {
Expand Down
66 changes: 52 additions & 14 deletions packages/houdini-react/src/runtime/routing/Router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export function Router({
injectToStream,
})
// if we get this far, it's safe to load the component
const { component_cache } = useRouterContext()
const { component_cache, data_cache } = useRouterContext()
const PageComponent = component_cache.get(page.id)!

// if we got this far then we're past the suspense
Expand Down Expand Up @@ -100,24 +100,33 @@ export function Router({
}
}, [])

const goto = (url: string) => {
// clear the data cache so that we refetch queries with the new session (will force a cache-lookup)
data_cache.clear()

// perform the navigation
setCurrentURL(url)
}

// links are powered using anchor tags that we intercept and handle ourselves
useLinkBehavior({
goto: (val: string) => {
setCurrentURL(val)
},
goto,
preload(url: string, which: PreloadWhichValue) {
// there are 2 things that we could preload: the page component and the data

// look for the matching route information
const [page, variables] = find_match(configFile, manifest, url)
if (!page) {
return
}

// load the page component if necessary
if (['both', 'component'].includes(which)) {
if (['page', 'component'].includes(which)) {
loadComponent(page)
}

// load the page component if necessary
if (['both', 'data'].includes(which)) {
if (['page', 'data'].includes(which)) {
loadData(page, variables)
}
},
Expand All @@ -128,7 +137,13 @@ export function Router({
// its needs
return (
<VariableContext.Provider value={variables}>
<LocationContext.Provider value={{ pathname: currentURL, params: variables ?? {} }}>
<LocationContext.Provider
value={{
pathname: currentURL,
goto,
params: variables ?? {},
}}
>
<PageComponent url={currentURL} key={page.id} />
</LocationContext.Provider>
</VariableContext.Provider>
Expand Down Expand Up @@ -173,7 +188,15 @@ function usePageData({
const [session] = useSession()

// the function to load a query using the cache references
function load_query({ id, artifact }: { id: string; artifact: QueryArtifact }): Promise<void> {
function load_query({
id,
artifact,
variables,
}: {
id: string
artifact: QueryArtifact
variables: GraphQLVariables
}): Promise<void> {
// TODO: better tracking - only register the variables that were used
// track the new variables
for (const artifact of Object.keys(page.documents)) {
Expand Down Expand Up @@ -320,6 +343,10 @@ function usePageData({
targetPage: RouterPageManifest<ComponentType>,
variables: GraphQLVariables | null
) {
if (!targetPage) {
return
}

// if any of the artifacts that this page on have new variables, we need to clear the data cache
for (const [artifact, { variables: pageVariables }] of Object.entries(
targetPage.documents
Expand Down Expand Up @@ -376,7 +403,7 @@ function usePageData({
`)

// now that we have the artifact, we can load the query too
load_query({ id: artifact.name, artifact })
load_query({ id: artifact.name, artifact, variables })
})
.catch((err) => {
// TODO: handle error
Expand All @@ -389,7 +416,7 @@ function usePageData({
for (const artifact of Object.values(found_artifacts)) {
// if we don't have the query, load it
if (!data_cache.has(artifact.name)) {
load_query({ id: artifact.name, artifact })
load_query({ id: artifact.name, artifact, variables })
}
}
}
Expand Down Expand Up @@ -583,9 +610,15 @@ export function useCurrentVariables(): GraphQLVariables {

const VariableContext = React.createContext<GraphQLVariables>(null)

const LocationContext = React.createContext<{ pathname: string; params: Record<string, any> }>({
const LocationContext = React.createContext<{
pathname: string
params: Record<string, any>
// a function to imperatively navigate to a url
goto: (url: string) => void
}>({
pathname: '',
params: {},
goto: () => {},
})

export function useQueryResult<_Data extends GraphQLObject, _Input extends GraphQLVariables>(
Expand Down Expand Up @@ -707,12 +740,17 @@ function usePreload({ preload }: { preload: (url: string, which: PreloadWhichVal
React.useEffect(() => {
const mouseMove: HTMLAnchorElement['onmousemove'] = (e) => {
const target = e.target
if (!(target instanceof HTMLAnchorElement)) {
if (!(target instanceof HTMLElement)) {
return
}

const anchor = target.closest('a')
if (!anchor) {
return
}

// if the anchor doesn't allow for preloading, don't do anything
let preloadWhichRaw = target.attributes.getNamedItem('data-houdini-preload')?.value
let preloadWhichRaw = anchor.attributes.getNamedItem('data-houdini-preload')?.value
let preloadWhich: PreloadWhichValue =
!preloadWhichRaw || preloadWhichRaw === 'true'
? 'page'
Expand All @@ -733,7 +771,7 @@ function usePreload({ preload }: { preload: (url: string, which: PreloadWhichVal

// set the new timeout to track _this_ anchor
timeoutRef.current = setTimeout(() => {
const url = target.attributes.getNamedItem('href')?.value
const url = anchor.attributes.getNamedItem('href')?.value
if (!url) {
return
}
Expand Down
2 changes: 1 addition & 1 deletion packages/houdini/src/runtime/client/documentStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ export class DocumentStore<
this.#configFile = getCurrentConfig()

this.#plugins = pipeline ?? [
// cache policy needs to always come first so that it can be the first fetch_enter to fire
// cache policy needs to always come first so that it can be the first network to fire
cachePolicy({
cache,
enabled: enableCache,
Expand Down
2 changes: 1 addition & 1 deletion packages/houdini/src/runtime/client/plugins/cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export const cachePolicy =
}): ClientPlugin =>
() => {
return {
network(ctx, { initialValue, next, resolve, marshalVariables }) {
beforeNetwork(ctx, { initialValue, next, resolve, marshalVariables }) {
const { policy, artifact } = ctx
let useCache = false
// enforce cache policies for queries
Expand Down
2 changes: 1 addition & 1 deletion packages/houdini/src/runtime/client/plugins/fetchParams.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export type FetchParamFn = (ctx: FetchParamsInput) => Required<ClientPluginConte
export const fetchParams: (fn?: FetchParamFn) => ClientPlugin =
(fn = () => ({})) =>
() => ({
beforeNetwork(ctx, { next, marshalVariables }) {
start(ctx, { next, marshalVariables }) {
next({
...ctx,
fetchParams: fn({
Expand Down
4 changes: 3 additions & 1 deletion packages/houdini/src/runtime/router/match.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,9 @@ export function find_match<_ComponentType>(
}

// we might have to marshal the variables
let variables: GraphQLVariables = {}
let variables: GraphQLVariables = {
...matchVariables,
}
// each of the matched documents might tell us how to handle a subset of the
// matchVariables. look at every document's input specification and marshal
// any values that are in matchVariables
Expand Down

0 comments on commit d1686d0

Please sign in to comment.