@@ -911,6 +911,7 @@ export type UseInfiniteQueryState<
911911 arg : QueryArgFrom < D > | SkipToken ,
912912 options ?: UseInfiniteQueryStateOptions < D , R > ,
913913) => UseInfiniteQueryStateResult < D , R >
914+
914915export type TypedUseInfiniteQueryState <
915916 ResultType ,
916917 QueryArg ,
@@ -1556,6 +1557,89 @@ export function buildHooks<Definitions extends EndpointDefinitions>({
15561557 return [ promiseRef , dispatch , initiate , stableSubscriptionOptions ] as const
15571558 }
15581559
1560+ function buildUseQueryState (
1561+ endpointName : string ,
1562+ preSelector :
1563+ | typeof queryStatePreSelector
1564+ | typeof infiniteQueryStatePreSelector ,
1565+ ) {
1566+ const useQueryState = (
1567+ arg : any ,
1568+ {
1569+ skip = false ,
1570+ selectFromResult,
1571+ } :
1572+ | UseQueryStateOptions < any , any >
1573+ | UseInfiniteQueryStateOptions < any , any > = { } ,
1574+ ) => {
1575+ const { select } = api . endpoints [ endpointName ] as ApiEndpointQuery <
1576+ QueryDefinition < any , any , any , any , any > ,
1577+ Definitions
1578+ >
1579+ const stableArg = useStableQueryArgs (
1580+ skip ? skipToken : arg ,
1581+ serializeQueryArgs ,
1582+ context . endpointDefinitions [ endpointName ] ,
1583+ endpointName ,
1584+ )
1585+
1586+ type ApiRootState = Parameters < ReturnType < typeof select > > [ 0 ]
1587+
1588+ const lastValue = useRef < any > ( undefined )
1589+
1590+ const selectDefaultResult : Selector < ApiRootState , any , [ any ] > = useMemo (
1591+ ( ) =>
1592+ // Normally ts-ignores are bad and should be avoided, but we're
1593+ // already casting this selector to be `Selector<any>` anyway,
1594+ // so the inconsistencies don't matter here
1595+ // @ts -ignore
1596+ createSelector (
1597+ [
1598+ select ( stableArg ) ,
1599+ ( _ : ApiRootState , lastResult : any ) => lastResult ,
1600+ ( _ : ApiRootState ) => stableArg ,
1601+ ] ,
1602+ preSelector ,
1603+ {
1604+ memoizeOptions : {
1605+ resultEqualityCheck : shallowEqual ,
1606+ } ,
1607+ } ,
1608+ ) ,
1609+ [ select , stableArg ] ,
1610+ )
1611+
1612+ const querySelector : Selector < ApiRootState , any , [ any ] > = useMemo (
1613+ ( ) =>
1614+ selectFromResult
1615+ ? createSelector ( [ selectDefaultResult ] , selectFromResult , {
1616+ devModeChecks : { identityFunctionCheck : 'never' } ,
1617+ } )
1618+ : selectDefaultResult ,
1619+ [ selectDefaultResult , selectFromResult ] ,
1620+ )
1621+
1622+ const currentState = useSelector (
1623+ ( state : RootState < Definitions , any , any > ) =>
1624+ querySelector ( state , lastValue . current ) ,
1625+ shallowEqual ,
1626+ )
1627+
1628+ const store = useStore < RootState < Definitions , any , any > > ( )
1629+ const newLastValue = selectDefaultResult (
1630+ store . getState ( ) ,
1631+ lastValue . current ,
1632+ )
1633+ useIsomorphicLayoutEffect ( ( ) => {
1634+ lastValue . current = newLastValue
1635+ } , [ newLastValue ] )
1636+
1637+ return currentState
1638+ }
1639+
1640+ return useQueryState
1641+ }
1642+
15591643 function buildQueryHooks ( endpointName : string ) : QueryHooks < any > {
15601644 const useQuerySubscription : UseQuerySubscription < any > = (
15611645 arg : any ,
@@ -1685,70 +1769,10 @@ export function buildHooks<Definitions extends EndpointDefinitions>({
16851769 )
16861770 }
16871771
1688- const useQueryState : UseQueryState < any > = (
1689- arg : any ,
1690- { skip = false , selectFromResult } = { } ,
1691- ) => {
1692- const { select } = api . endpoints [ endpointName ] as ApiEndpointQuery <
1693- QueryDefinition < any , any , any , any , any > ,
1694- Definitions
1695- >
1696- const stableArg = useStableQueryArgs (
1697- skip ? skipToken : arg ,
1698- serializeQueryArgs ,
1699- context . endpointDefinitions [ endpointName ] ,
1700- endpointName ,
1701- )
1702-
1703- type ApiRootState = Parameters < ReturnType < typeof select > > [ 0 ]
1704-
1705- const lastValue = useRef < any > ( undefined )
1706-
1707- const selectDefaultResult : Selector < ApiRootState , any , [ any ] > = useMemo (
1708- ( ) =>
1709- createSelector (
1710- [
1711- select ( stableArg ) ,
1712- ( _ : ApiRootState , lastResult : any ) => lastResult ,
1713- ( _ : ApiRootState ) => stableArg ,
1714- ] ,
1715- queryStatePreSelector ,
1716- {
1717- memoizeOptions : {
1718- resultEqualityCheck : shallowEqual ,
1719- } ,
1720- } ,
1721- ) ,
1722- [ select , stableArg ] ,
1723- )
1724-
1725- const querySelector : Selector < ApiRootState , any , [ any ] > = useMemo (
1726- ( ) =>
1727- selectFromResult
1728- ? createSelector ( [ selectDefaultResult ] , selectFromResult , {
1729- devModeChecks : { identityFunctionCheck : 'never' } ,
1730- } )
1731- : selectDefaultResult ,
1732- [ selectDefaultResult , selectFromResult ] ,
1733- )
1734-
1735- const currentState = useSelector (
1736- ( state : RootState < Definitions , any , any > ) =>
1737- querySelector ( state , lastValue . current ) ,
1738- shallowEqual ,
1739- )
1740-
1741- const store = useStore < RootState < Definitions , any , any > > ( )
1742- const newLastValue = selectDefaultResult (
1743- store . getState ( ) ,
1744- lastValue . current ,
1745- )
1746- useIsomorphicLayoutEffect ( ( ) => {
1747- lastValue . current = newLastValue
1748- } , [ newLastValue ] )
1749-
1750- return currentState
1751- }
1772+ const useQueryState : UseQueryState < any > = buildUseQueryState (
1773+ endpointName ,
1774+ queryStatePreSelector ,
1775+ )
17521776
17531777 return {
17541778 useQueryState,
@@ -1794,15 +1818,6 @@ export function buildHooks<Definitions extends EndpointDefinitions>({
17941818 const useInfiniteQuerySubscription : UseInfiniteQuerySubscription < any > = (
17951819 arg : any ,
17961820 options = { } ,
1797- // {
1798- // refetchOnReconnect,
1799- // refetchOnFocus,
1800- // refetchOnMountOrArgChange,
1801- // skip = false,
1802- // pollingInterval = 0,
1803- // skipPollingIfUnfocused = false,
1804- // initialPageParam,
1805- // } = {},
18061821 ) => {
18071822 const [ promiseRef , dispatch , initiate , stableSubscriptionOptions ] =
18081823 useQuerySubscriptionCommonImpl < InfiniteQueryActionCreatorResult < any > > (
@@ -1811,128 +1826,6 @@ export function buildHooks<Definitions extends EndpointDefinitions>({
18111826 options ,
18121827 )
18131828
1814- // const { initiate } = api.endpoints[
1815- // endpointName
1816- // ] as unknown as ApiEndpointInfiniteQuery<
1817- // InfiniteQueryDefinition<any, any, any, any, any>,
1818- // Definitions
1819- // >
1820- // const dispatch = useDispatch<ThunkDispatch<any, any, UnknownAction>>()
1821- // const subscriptionSelectorsRef = useRef<
1822- // SubscriptionSelectors | undefined
1823- // >(undefined)
1824- // if (!subscriptionSelectorsRef.current) {
1825- // const returnedValue = dispatch(
1826- // api.internalActions.internal_getRTKQSubscriptions(),
1827- // )
1828-
1829- // if (process.env.NODE_ENV !== 'production') {
1830- // if (
1831- // typeof returnedValue !== 'object' ||
1832- // typeof returnedValue?.type === 'string'
1833- // ) {
1834- // throw new Error(
1835- // `Warning: Middleware for RTK-Query API at reducerPath "${api.reducerPath}" has not been added to the store.
1836- // You must add the middleware for RTK-Query to function correctly!`,
1837- // )
1838- // }
1839- // }
1840-
1841- // subscriptionSelectorsRef.current =
1842- // returnedValue as unknown as SubscriptionSelectors
1843- // }
1844- // const stableArg = useStableQueryArgs(
1845- // skip ? skipToken : arg,
1846- // // Even if the user provided a per-endpoint `serializeQueryArgs` with
1847- // // a consistent return value, _here_ we want to use the default behavior
1848- // // so we can tell if _anything_ actually changed. Otherwise, we can end up
1849- // // with a case where the query args did change but the serialization doesn't,
1850- // // and then we never try to initiate a refetch.
1851- // defaultSerializeQueryArgs,
1852- // context.endpointDefinitions[endpointName],
1853- // endpointName,
1854- // )
1855- // const stableSubscriptionOptions = useShallowStableValue({
1856- // refetchOnReconnect,
1857- // refetchOnFocus,
1858- // pollingInterval,
1859- // skipPollingIfUnfocused,
1860- // })
1861-
1862- // const lastRenderHadSubscription = useRef(false)
1863-
1864- // const promiseRef = useRef<
1865- // InfiniteQueryActionCreatorResult<any> | undefined
1866- // >(undefined)
1867-
1868- // let { queryCacheKey, requestId } = promiseRef.current || {}
1869-
1870- // // HACK We've saved the middleware subscription lookup callbacks into a ref,
1871- // // so we can directly check here if the subscription exists for this query.
1872- // let currentRenderHasSubscription = false
1873- // if (queryCacheKey && requestId) {
1874- // currentRenderHasSubscription =
1875- // subscriptionSelectorsRef.current.isRequestSubscribed(
1876- // queryCacheKey,
1877- // requestId,
1878- // )
1879- // }
1880-
1881- // const subscriptionRemoved =
1882- // !currentRenderHasSubscription && lastRenderHadSubscription.current
1883-
1884- // usePossiblyImmediateEffect(() => {
1885- // lastRenderHadSubscription.current = currentRenderHasSubscription
1886- // })
1887-
1888- // usePossiblyImmediateEffect((): void | undefined => {
1889- // if (subscriptionRemoved) {
1890- // promiseRef.current = undefined
1891- // }
1892- // }, [subscriptionRemoved])
1893-
1894- // usePossiblyImmediateEffect((): void | undefined => {
1895- // const lastPromise = promiseRef.current
1896- // if (
1897- // typeof process !== 'undefined' &&
1898- // process.env.NODE_ENV === 'removeMeOnCompilation'
1899- // ) {
1900- // // this is only present to enforce the rule of hooks to keep `isSubscribed` in the dependency array
1901- // console.log(subscriptionRemoved)
1902- // }
1903-
1904- // if (stableArg === skipToken) {
1905- // lastPromise?.unsubscribe()
1906- // promiseRef.current = undefined
1907- // return
1908- // }
1909-
1910- // const lastSubscriptionOptions = promiseRef.current?.subscriptionOptions
1911-
1912- // if (!lastPromise || lastPromise.arg !== stableArg) {
1913- // lastPromise?.unsubscribe()
1914- // const promise = dispatch(
1915- // initiate(stableArg, {
1916- // initialPageParam,
1917- // subscriptionOptions: stableSubscriptionOptions,
1918- // forceRefetch: refetchOnMountOrArgChange,
1919- // }),
1920- // )
1921-
1922- // promiseRef.current = promise
1923- // } else if (stableSubscriptionOptions !== lastSubscriptionOptions) {
1924- // lastPromise.updateSubscriptionOptions(stableSubscriptionOptions)
1925- // }
1926- // }, [
1927- // dispatch,
1928- // initiate,
1929- // refetchOnMountOrArgChange,
1930- // stableArg,
1931- // stableSubscriptionOptions,
1932- // subscriptionRemoved,
1933- // initialPageParam,
1934- // ])
1935-
19361829 const subscriptionOptionsRef = useRef ( stableSubscriptionOptions )
19371830 usePossiblyImmediateEffect ( ( ) => {
19381831 subscriptionOptionsRef . current = stableSubscriptionOptions
@@ -1995,72 +1888,8 @@ export function buildHooks<Definitions extends EndpointDefinitions>({
19951888 } , [ promiseRef , trigger , arg ] )
19961889 }
19971890
1998- const useInfiniteQueryState : UseInfiniteQueryState < any > = (
1999- arg : any ,
2000- { skip = false , selectFromResult } = { } ,
2001- ) => {
2002- const { select } = api . endpoints [
2003- endpointName
2004- ] as unknown as ApiEndpointInfiniteQuery <
2005- InfiniteQueryDefinition < any , any , any , any , any > ,
2006- Definitions
2007- >
2008- const stableArg = useStableQueryArgs (
2009- skip ? skipToken : arg ,
2010- serializeQueryArgs ,
2011- context . endpointDefinitions [ endpointName ] ,
2012- endpointName ,
2013- )
2014-
2015- type ApiRootState = Parameters < ReturnType < typeof select > > [ 0 ]
2016-
2017- const lastValue = useRef < any > ( undefined )
2018-
2019- const selectDefaultResult : Selector < ApiRootState , any , [ any ] > = useMemo (
2020- ( ) =>
2021- createSelector (
2022- [
2023- select ( stableArg ) ,
2024- ( _ : ApiRootState , lastResult : any ) => lastResult ,
2025- ( _ : ApiRootState ) => stableArg ,
2026- ] ,
2027- infiniteQueryStatePreSelector ,
2028- {
2029- memoizeOptions : {
2030- resultEqualityCheck : shallowEqual ,
2031- } ,
2032- } ,
2033- ) ,
2034- [ select , stableArg ] ,
2035- )
2036-
2037- const querySelector : Selector < ApiRootState , any , [ any ] > = useMemo (
2038- ( ) =>
2039- selectFromResult
2040- ? createSelector ( [ selectDefaultResult ] , selectFromResult , {
2041- devModeChecks : { identityFunctionCheck : 'never' } ,
2042- } )
2043- : selectDefaultResult ,
2044- [ selectDefaultResult , selectFromResult ] ,
2045- )
2046-
2047- const currentState = useSelector (
2048- ( state : RootState < Definitions , any , any > ) =>
2049- querySelector ( state , lastValue . current ) ,
2050- shallowEqual ,
2051- )
2052-
2053- const store = useStore < RootState < Definitions , any , any > > ( )
2054- const newLastValue = selectDefaultResult (
2055- store . getState ( ) ,
2056- lastValue . current ,
2057- )
2058- useIsomorphicLayoutEffect ( ( ) => {
2059- lastValue . current = newLastValue
2060- } , [ newLastValue ] )
2061-
2062- return currentState
2063- }
1891+ const useInfiniteQueryState : UseInfiniteQueryState < any > =
1892+ buildUseQueryState ( endpointName , infiniteQueryStatePreSelector )
20641893
20651894 return {
20661895 useInfiniteQueryState,
0 commit comments