Bug? Suspense with usePreloadedQuery doens't get triggered
- Dominant language
- Rust
- Stars
- 19k
- Forks
- 1.9k
- PR merge metrics
- No merged PRs in 30d
Description
## Problem
I have an app in which I show records in the form of cards. I have a browse page, a record detail page and a filter detail page.
The record detail page is a subpage of the browse page.
When I click on a card in the browse page, the Suspense isn't tiggered and I don't see anything untill the data is fetched.
When I click on a card in the filter detail page and I get redirected to the record detail page, the Suspense works and I see the skelleton while fetching the data.
I use the latest experimental versions of react and relay.
Index.jsx
```
import React, { Suspense } from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import { RelayEnvironmentProvider } from 'react-relay/hooks';
import App from './components/App/index';
import ErrorPage from './components/pages/Error';
import relayEnvironment from './relayEnvironment';
import Skelleton from './components/App/Skelleton';
ReactDOM.unstable_createRoot(
document.getElementById('root'),
).render(
}>
} />
} />
,
);
```
App.jsx
```
import React, { lazy } from 'react';
import { Routes, Route, useParams } from 'react-router-dom';
import { useLazyLoadQuery } from 'react-relay/hooks';
import PreloadRoute from '../common/PreloadRoute';
import { browsePageQuery, appQuery } from '../../graphql/queries';
import GeneralErrorBoundary from '../ErrorBoundaries/GeneralErrorBoundary';
const ErrorPage = lazy(() => import('../pages/Error'));
const Browse = lazy(() => import('../pages/Browse'));
const Search = lazy(() => import('../pages/Search'));
const SignUp = lazy(() => import('../pages/SignUp'));
const SignOut = lazy(() => import('../pages/SignOut'));
const SignIn = lazy(() => import('../pages/SignIn'));
const Skelleton = lazy(() => import('./Skelleton'));
export default function App() {
/* Params and data */
const { subdomain } = useParams();
const data = useLazyLoadQuery(appQuery, { subdomain });
return (
}
query={browsePageQuery}
variables={{ subdomain }}
loading={}
/>
} />
} />
} />
} />
} />
);
}
```
Browse.jsx
```
/* eslint-disable global-require */
import React, { lazy } from 'react';
import { Flex, Box } from 'rebass';
import { usePreloadedQuery } from 'react-relay/hooks';
import PropTypes from 'prop-types';
import { Routes, useParams } from 'react-router-dom';
import { useFeature } from '@optimizely/react-sdk';
import PreloadRoute from '../../common/PreloadRoute';
import { browsePageQuery, browseRecordPageQuery } from '../../../graphql/queries';
import Logo from '../../common/Logo';
import Tagline from './Tagline';
import Searchfield from '../../common/Searchfield';
import Filters from './Filters';
import RecordLoading from './RecordLoading';
import { PrivateNicheException } from '../../../exceptions';
const Record = lazy(() => import('./Record'));
export default function BrowsePage({ queryReference }) {
const data = usePreloadedQuery(browsePageQuery, queryReference);
const [isFilterEnabled] = useFeature('filters', { autoUpdate: true });
const { subdomain } = useParams();
const { niche } = data;
if (!niche.id) {
throw PrivateNicheException('This is a private niche');
}
return (
{isFilterEnabled && }
}
loading={}
query={browseRecordPageQuery}
variables={{
subdomain,
recordId: window.location.pathname.split('/').slice(-1)[0],
viewModus: 'detail',
}}
/>
);
}
BrowsePage.propTypes = {
queryReference: PropTypes.shape({}).isRequired,
};
```
Record.jsx
```
import React, { useEffect } from 'react';
import { usePreloadedQuery } from 'react-relay/hooks';
import PropTypes from 'prop-types';
import { Flex } from 'rebass';
import { browseRecordPageQuery } from '../../../../graphql/queries';
import Card from './Card';
export default function Record({ queryReference }) {
const data = usePreloadedQuery(browseRecordPageQuery, queryReference);
useEffect(() => {
console.log(queryReference);
console.log(data);
}, [data, queryReference]);
/** Make sure the scrolling of the background stops */
useEffect(() => {
const { body } = document;
body.style.height = '100vh';
body.style.overflowY = 'hidden';
return () => {
body.style.height = 'auto';
body.style.overflowY = 'auto';
};
}, []);
return (
boehoe
);
}
Record.propTypes = {
queryReference: PropTypes.shape({}),
};
Record.defaultProps = {
queryReference: null,
};
```
PreloadRoute.jsx
```
import React, { useEffect, Suspense, unstable_useTransition as useTransition } from 'react';
import PropTypes from 'prop-types';
import { Route } from 'react-router-dom';
import { useQueryLoader } from 'react-relay/hooks';
import { Loading } from 'front-component-library';
export default function PreloadRoute({
path, element, query, variables, loading,
}) {
const [queryRef, loadQuery] = useQueryLoader(query);
const [startTransition] = useTransition();
useEffect(() => {
startTransition(() => {
loadQuery(variables);
});
}, [loadQuery, variables]);
if (!element) {
return (
);
}
return (
{
queryRef != null && React.cloneElement(element, { queryReference: queryRef })
}
)}
/>
);
}
PreloadRoute.propTypes = {
path: PropTypes.string.isRequired,
element: PropTypes.node,
query: PropTypes.shape({}),
variables: PropTypes.shape({}),
loading: PropTypes.node,
};
PreloadRoute.defaultProps = {
element: null,
loading: ,
query: () => {},
variables: {},
};
```
Contributor guide
Assessment
This issue has not been assessed yet.