Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 8 additions & 9 deletions src/react/Hydrate.tsx
Original file line number Diff line number Diff line change
@@ -1,35 +1,34 @@
import React from 'react'
import {createMemo} from 'solid-js'

import { hydrate, HydrateOptions } from '../core'
import { useQueryClient } from './QueryClientProvider'

export function useHydrate(state: unknown, options?: HydrateOptions) {
const queryClient = useQueryClient()

const optionsRef = React.useRef(options)
optionsRef.current = options
const optionsRef = options

// Running hydrate again with the same queries is safe,
// it wont overwrite or initialize existing queries,
// relying on useMemo here is only a performance optimization.
// hydrate can and should be run *during* render here for SSR to work properly
React.useMemo(() => {
createMemo(() => {
if (state) {
hydrate(queryClient, state, optionsRef.current)
hydrate(queryClient(), state(), optionsRef())
}
}, [queryClient, state])
})
}

export interface HydrateProps {
state?: unknown
options?: HydrateOptions
}

export const Hydrate: React.FC<HydrateProps> = ({
export const Hydrate = ({
children,
options,
state,
}) => {
}:HydrateProps) => {
useHydrate(state, options)
return children as React.ReactElement<any>
return children as JSX.Element
}
37 changes: 17 additions & 20 deletions src/react/QueryClientProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react'
import {createMutable, createEffect, createContext} from 'solid-js'

import { QueryClient } from '../core'

Expand All @@ -8,8 +8,8 @@ declare global {
}
}

const defaultContext = React.createContext<QueryClient | undefined>(undefined)
const QueryClientSharingContext = React.createContext<boolean>(false)
const defaultContext = createContext<QueryClient|undefined>(undefined)
const QueryClientSharingContext = createContext<boolean>(false)

// if contextSharing is on, we share the first and at least one
// instance of the context across the window
Expand All @@ -30,12 +30,12 @@ function getQueryClientContext(contextSharing: boolean) {
}

export const useQueryClient = () => {
const queryClient = React.useContext(
getQueryClientContext(React.useContext(QueryClientSharingContext))
const queryClient = useContext(
getQueryClientContext(QueryClientSharingContext)
)

if (!queryClient) {
throw new Error('No QueryClient set, use QueryClientProvider to set one')
throw new Error('No QueryClient set')
}

return queryClient
Expand All @@ -46,23 +46,20 @@ export interface QueryClientProviderProps {
contextSharing?: boolean
}

export const QueryClientProvider: React.FC<QueryClientProviderProps> = ({
client,
contextSharing = false,
children,
}) => {
React.useEffect(() => {
client.mount()
return () => {
client.unmount()
}
}, [client])
export const QueryClientProvider = ({props}:QueryClientProviderProps) => {
createEffect(() => {
props.client.mount()
})

onCleanup(() => {
props.clien.unmount()
})

const Context = getQueryClientContext(contextSharing)
const Context = getQueryClientContext(props.contextSharing())

return (
<QueryClientSharingContext.Provider value={contextSharing}>
<Context.Provider value={client}>{children}</Context.Provider>
<QueryClientSharingContext.Provider value={contextSharing()}>
<Context.Provider value={props.client()}>{props.children()}</Context.Provider>
</QueryClientSharingContext.Provider>
)
}
20 changes: 10 additions & 10 deletions src/react/QueryErrorResetBoundary.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react'
import {createContext, useContext, createMemo} from "solid-js"

// CONTEXT

Expand All @@ -23,29 +23,29 @@ function createValue(): QueryErrorResetBoundaryValue {
}
}

const QueryErrorResetBoundaryContext = React.createContext(createValue())
const QueryErrorResetBoundaryContext = createContext(createValue())

// HOOK

export const useQueryErrorResetBoundary = () =>
React.useContext(QueryErrorResetBoundaryContext)
useContext(QueryErrorResetBoundaryContext)

// COMPONENT

export interface QueryErrorResetBoundaryProps {
children:
| ((value: QueryErrorResetBoundaryValue) => React.ReactNode)
| React.ReactNode
| ((value: QueryErrorResetBoundaryValue) => JSX.Element)
| JSX.Element
}

export const QueryErrorResetBoundary: React.FC<QueryErrorResetBoundaryProps> = ({
export const QueryErrorResetBoundary = ({
children,
}) => {
const value = React.useMemo(() => createValue(), [])
}:QueryErrorResetBoundaryProps) => {
const value = createMemo(() => createValue())
return (
<QueryErrorResetBoundaryContext.Provider value={value}>
<QueryErrorResetBoundaryContext.Provider value={value()}>
{typeof children === 'function'
? (children as Function)(value)
? (children as Function)(value())
: children}
</QueryErrorResetBoundaryContext.Provider>
)
Expand Down
4 changes: 2 additions & 2 deletions src/react/setBatchUpdatesFn.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { notifyManager } from '../core'
import { unstable_batchedUpdates } from './reactBatchedUpdates'
import {batch} from 'solid-js'

notifyManager.setBatchNotifyFunction(unstable_batchedUpdates)
notifyManager.setBatchNotifyFunction(batch)
28 changes: 14 additions & 14 deletions src/react/useBaseQuery.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import React from 'react'

import { QueryKey } from '../core'
import { notifyManager } from '../core/notifyManager'
import { QueryObserver } from '../core/queryObserver'
import { useQueryErrorResetBoundary } from './QueryErrorResetBoundary'
import { useQueryClient } from './QueryClientProvider'
import { UseBaseQueryOptions } from './types'
import { shouldThrowError } from './utils'
import {createSignal, createMemo, createEffect, onCleanup} from 'solid-js'

export function useBaseQuery<
TQueryFnData,
Expand All @@ -24,12 +23,12 @@ export function useBaseQuery<
>,
Observer: typeof QueryObserver
) {
const mountedRef = React.useRef(false)
const [, forceUpdate] = React.useState(0)
const [mountedRef] = createSignal(false)
const [, forceUpdate] = createSignal(0)

const queryClient = useQueryClient()
const errorResetBoundary = useQueryErrorResetBoundary()
const defaultedOptions = queryClient.defaultQueryObserverOptions(options)
const [defaultedOptions] = createSignal(queryClient.defaultQueryObserverOptions(options))

// Make sure results are optimistically set in fetching state before subscribing or updating options
defaultedOptions.optimisticResults = true
Expand Down Expand Up @@ -74,7 +73,7 @@ export function useBaseQuery<
}
}

const [observer] = React.useState(
const [observer] = createSignal(
() =>
new Observer<TQueryFnData, TError, TData, TQueryData, TQueryKey>(
queryClient,
Expand All @@ -84,7 +83,7 @@ export function useBaseQuery<

let result = observer.getOptimisticResult(defaultedOptions)

React.useEffect(() => {
createEffect(() => {
mountedRef.current = true

errorResetBoundary.clearReset()
Expand All @@ -100,18 +99,19 @@ export function useBaseQuery<
// Update result to make sure we did not miss any query updates
// between creating the observer and subscribing to it.
observer.updateResult()

return () => {
onCleanup(() => {
mountedRef.current = false
unsubscribe()
}
}, [errorResetBoundary, observer])
})
})



React.useEffect(() => {
createEffect(() => {
// Do not notify on updates because of changes in the options because
// these changes should already be reflected in the optimistic result.
observer.setOptions(defaultedOptions, { listeners: false })
}, [defaultedOptions, observer])
observer.setOptions(defaultedOptions(), { listeners: false })
})

// Handle suspense
if (defaultedOptions.suspense && result.isLoading) {
Expand Down
2 changes: 2 additions & 0 deletions src/react/useInfiniteQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { QueryFunction, QueryKey } from '../core/types'
import { parseQueryArgs } from '../core/utils'
import { UseInfiniteQueryOptions, UseInfiniteQueryResult } from './types'
import { useBaseQuery } from './useBaseQuery'
import {createSignal, createMemo, createEffect, onCleanup} from 'solid-js'


// HOOK

Expand Down
20 changes: 11 additions & 9 deletions src/react/useIsFetching.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React from 'react'

import {createSignal, createMemo, createEffect, onCleanup} from 'solid-js'

import { notifyManager } from '../core/notifyManager'
import { QueryKey } from '../core/types'
Expand All @@ -14,21 +15,21 @@ export function useIsFetching(
arg1?: QueryKey | QueryFilters,
arg2?: QueryFilters
): number {
const mountedRef = React.useRef(false)
const mountedRef = false

const queryClient = useQueryClient()

const [filters] = parseFilterArgs(arg1, arg2)
const [isFetching, setIsFetching] = React.useState(
const [isFetching, setIsFetching] = createSignal(
queryClient.isFetching(filters)
)

const filtersRef = React.useRef(filters)
const filtersRef = filters
filtersRef.current = filters
const isFetchingRef = React.useRef(isFetching)
const isFetchingRef = isFetching
isFetchingRef.current = isFetching

React.useEffect(() => {
createEffect(() => {
mountedRef.current = true

const unsubscribe = queryClient.getQueryCache().subscribe(
Expand All @@ -42,11 +43,12 @@ export function useIsFetching(
})
)

return () => {
onCleanup(()=>{
mountedRef.current = false
unsubscribe()
}
}, [queryClient])
})

})

return isFetching
}
16 changes: 9 additions & 7 deletions src/react/useIsMutating.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React from 'react'

import {createSignal, createMemo, createEffect, onCleanup} from 'solid-js'

import { notifyManager } from '../core/notifyManager'
import { QueryKey } from '../core/types'
Expand All @@ -14,12 +15,12 @@ export function useIsMutating(
arg1?: QueryKey | MutationFilters,
arg2?: MutationFilters
): number {
const mountedRef = React.useRef(false)
const mountedRef = false
const filters = parseMutationFilterArgs(arg1, arg2)

const queryClient = useQueryClient()

const [isMutating, setIsMutating] = React.useState(
const [isMutating, setIsMutating] = createSignal(
queryClient.isMutating(filters)
)

Expand All @@ -28,7 +29,7 @@ export function useIsMutating(
const isMutatingRef = React.useRef(isMutating)
isMutatingRef.current = isMutating

React.useEffect(() => {
createEffect(() => {
mountedRef.current = true

const unsubscribe = queryClient.getMutationCache().subscribe(
Expand All @@ -42,11 +43,12 @@ export function useIsMutating(
})
)

return () => {
onCleanup(()=>{
mountedRef.current = false
unsubscribe()
}
}, [queryClient])
})

})

return isMutating
}
Loading