Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[V3][Hooks Integration 🪝] Replace last of the getProps #1149

Merged
merged 4 commits into from
Apr 25, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,12 @@ const withErrorHandling = (Wrapped) => {
*/
export const routeComponent = (Wrapped, isPage, locals) => {
const AppConfig = getAppConfig()
const extraArgs = AppConfig.extraGetPropsArgs(locals)

const hocs = AppConfig.getHOCsInUse()
const getPropsEnabled = hocs.indexOf(withLegacyGetProps) >= 0

const extraArgs = getPropsEnabled ? AppConfig.extraGetPropsArgs(locals) : {}
Copy link
Collaborator

@kevinxh kevinxh Apr 25, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what happens if getPropsEnabled is true but extraGetPropsArgs is not defined? Is there a default noop implementation for AppConfig.extraGetPropsArgs ? If not, maybe we should guard undefined extraGetPropsArgs?


/* istanbul ignore next */
const wrappedComponentName = Wrapped.displayName || Wrapped.name

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import {getConfig} from 'pwa-kit-runtime/utils/ssr-config'
import {createUrlTemplate} from '../../utils/url'

import {CommerceApiProvider} from 'commerce-sdk-react-preview'
import {withLegacyGetProps} from 'pwa-kit-react-sdk/ssr/universal/components/with-legacy-get-props'
import {withReactQuery} from 'pwa-kit-react-sdk/ssr/universal/components/with-react-query'
import {useCorrelationId} from 'pwa-kit-react-sdk/ssr/universal/hooks'
import {getAppOrigin} from 'pwa-kit-react-sdk/utils/url'
Expand Down Expand Up @@ -86,14 +85,6 @@ AppConfig.restore = (locals = {}) => {

AppConfig.freeze = () => undefined

AppConfig.extraGetPropsArgs = (locals = {}) => {
return {
buildUrl: locals.buildUrl,
site: locals.site,
locale: locals.locale
}
}

AppConfig.propTypes = {
children: PropTypes.node,
locals: PropTypes.object
Expand All @@ -119,4 +110,4 @@ const options = {
}
}

export default withReactQuery(withLegacyGetProps(AppConfig), options)
export default withReactQuery(AppConfig, options)
73 changes: 33 additions & 40 deletions packages/template-retail-react-app/app/components/_app/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {useHistory, useLocation} from 'react-router-dom'
import {getAssetUrl} from 'pwa-kit-react-sdk/ssr/universal/utils'
import {getAppOrigin} from 'pwa-kit-react-sdk/utils/url'
import {getConfig} from 'pwa-kit-runtime/utils/ssr-config'
import {useQueries} from '@tanstack/react-query'
import {useQuery, useQueries} from '@tanstack/react-query'
import {
useAccessToken,
useCategory,
Expand Down Expand Up @@ -62,7 +62,6 @@ import {
} from '../../constants'

import Seo from '../seo'
import {resolveLocaleFromUrl, resolveSiteFromUrl} from '../../utils/site-utils'

const onClient = typeof window !== 'undefined'

Expand Down Expand Up @@ -99,7 +98,7 @@ const useLazyLoadCategories = () => {
}

const App = (props) => {
const {children, targetLocale = DEFAULT_LOCALE, messages = {}} = props
const {children} = props
const {data: categoriesTree} = useLazyLoadCategories()
const categories = flatten(categoriesTree || {}, 'categories')

Expand All @@ -116,6 +115,31 @@ const App = (props) => {

const {isOpen, onOpen, onClose} = useDisclosure()

const targetLocale = getTargetLocale({
getUserPreferredLocales: () => {
// CONFIG: This function should return an array of preferred locales. They can be
// derived from various sources. Below are some examples of those:
//
// - client side: window.navigator.languages
// - the page URL they're on (example.com/en-GB/home)
// - cookie (if their previous preference is saved there)
//
// If this function returns an empty array (e.g. there isn't locale in the page url),
// then the app would use the default locale as the fallback.

// NOTE: Your implementation may differ, this is just what we did.
return [locale?.id || DEFAULT_LOCALE]
},
l10nConfig: site.l10n
})

// Fetch the translation message data using the target locale.
const {data: messages} = useQuery({
queryKey: ['app', 'translationas', 'messages', targetLocale],
queryFn: () => fetchTranslations(targetLocale),
enabled: typeof window === 'undefined'
})

// Used to conditionally render header/footer for checkout page
const isCheckout = /\/checkout$/.test(location?.pathname)

Expand Down Expand Up @@ -201,6 +225,11 @@ const App = (props) => {
<Box className="sf-app" {...styles.container}>
<IntlProvider
onError={(err) => {
if (!messages) {
// During the ssr prepass phase the messages object has not loaded, so we can suppress
// errors during this time.
return
}
if (err.code === 'MISSING_TRANSLATION') {
// NOTE: Remove the console error for missing translations during development,
// as we knew translations would be added later.
Expand Down Expand Up @@ -314,44 +343,8 @@ const App = (props) => {
)
}

App.shouldGetProps = () => {
// In this case, we only want to fetch data for the app once, on the server.
return typeof window === 'undefined'
}

App.getProps = async ({res}) => {
const site = resolveSiteFromUrl(res.locals.originalUrl)
const locale = resolveLocaleFromUrl(res.locals.originalUrl)
const l10nConfig = site.l10n
const targetLocale = getTargetLocale({
getUserPreferredLocales: () => {
// CONFIG: This function should return an array of preferred locales. They can be
// derived from various sources. Below are some examples of those:
//
// - client side: window.navigator.languages
// - the page URL they're on (example.com/en-GB/home)
// - cookie (if their previous preference is saved there)
//
// If this function returns an empty array (e.g. there isn't locale in the page url),
// then the app would use the default locale as the fallback.

// NOTE: Your implementation may differ, this is just what we did.
return [locale?.id]
},
l10nConfig
})
const messages = await fetchTranslations(targetLocale)

return {
targetLocale,
messages
}
}

App.propTypes = {
children: PropTypes.node,
targetLocale: PropTypes.string,
messages: PropTypes.object
children: PropTypes.node
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,19 +65,6 @@ describe('App', () => {
expect(screen.getByText('Any children here')).toBeInTheDocument()
})

test('shouldGetProps returns true only server-side', () => {
windowSpy.mockImplementation(() => undefined)

expect(App.shouldGetProps()).toBe(true)

windowSpy.mockImplementation(() => ({
location: {
origin: 'http://localhost:3000/'
}
}))
expect(App.shouldGetProps()).toBe(false)
})

test('The localized hreflang links exist in the html head', () => {
useMultiSite.mockImplementation(() => resultUseMultiSite)
renderWithProviders(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,20 @@ import React from 'react'
import {Box, Heading, Flex, Button, Stack, Text} from '@chakra-ui/react'
import {Helmet} from 'react-helmet'
import {useIntl} from 'react-intl'
import {useServerContext} from 'pwa-kit-react-sdk/ssr/universal/hooks'
import {SearchIcon} from '../../components/icons'
import {useHistory} from 'react-router-dom'
import Link from '../../components/link'

const PageNotFound = () => {
const intl = useIntl()
const history = useHistory()
const {res} = useServerContext()

if (res) {
res.status(404)
}

return (
<Box
layerStyle="page"
Expand Down Expand Up @@ -80,10 +87,4 @@ const PageNotFound = () => {
)
}

PageNotFound.getProps = async ({res}) => {
if (res) {
res.status(404)
}
}

export default PageNotFound
3 changes: 1 addition & 2 deletions packages/template-retail-react-app/app/utils/test-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import {AddToCartModalProvider} from '../hooks/use-add-to-cart-modal'
import {ServerContext} from 'pwa-kit-react-sdk/ssr/universal/contexts'
import {IntlProvider} from 'react-intl'
import {CommerceApiProvider} from 'commerce-sdk-react-preview'
import {withLegacyGetProps} from 'pwa-kit-react-sdk/ssr/universal/components/with-legacy-get-props'
import {withReactQuery} from 'pwa-kit-react-sdk/ssr/universal/components/with-react-query'
import fallbackMessages from '../translations/compiled/en-GB.json'
import mockConfig from '../../config/mocks/default'
Expand Down Expand Up @@ -170,7 +169,7 @@ TestProviders.propTypes = {
* @param {object} options
*/
export const renderWithProviders = (children, options) => {
const TestProvidersWithDataAPI = withReactQuery(withLegacyGetProps(TestProviders), {
const TestProvidersWithDataAPI = withReactQuery(TestProviders, {
queryClientConfig: {
defaultOptions: {
queries: {
Expand Down