Skip to content

Conversation

@blittle
Copy link
Contributor

@blittle blittle commented May 5, 2022

This comes up when you directly navigate from one product to another, and the product options are not the same. See this stackblitz. Notice the related products at the bottom of the details page that allow you to navigate directly to other products. As you do so, the product options get lost.

The bigger issue exposed here is that we don't lint our framework code. I updated this PR to now lint! Because of that, there are a lot of other changes. I commented throughout the PR on more significant things found by the linter.

@blittle blittle requested a review from frehner May 5, 2022 15:09
@blittle blittle force-pushed the bl-fix-product-options branch from ce43bf8 to b5c9499 Compare May 6, 2022 20:47
ReactApp: JSX.Element,
{log, nonce}: {log: Logger; nonce?: string}
): Promise<string> {
return new Promise<string>(async (resolve, reject) => {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is something caught by the linter that I think we should avoid. Having an async function as the resolver of a Promise. The issue is that uncaught errors within the async function won't bubble to any outer .catch statements

children,
}) => {
if (META_ENV_SSR) return <>{children}</>;
/* eslint-disable react-hooks/rules-of-hooks */
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This intentionally runs slightly different in SSR mode

Comment on lines +34 to +35
// eslint-disable-next-line react-hooks/rules-of-hooks
return useMemo(() => new URL(window.location.href), [location]); // eslint-disable-line react-hooks/exhaustive-deps
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This memoization is interesting. I assume it is correct. But at the same time I'm wondering if it maybe should be useMemo(() => new URL(location.href), [location]);?

});
});

it('computes selected variant based on options', async () => {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This test was essentially doing exactly what the other one was.

}, [initialVariantId, variants]);
const variant = getSelectedVariant(variants, selectedOptions);
setSelectedVariant(variant);
}, [selectedOptions, variants]);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I simplified the two effects in here into just one.

Copy link
Contributor

Choose a reason for hiding this comment

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

Nice

Copy link
Contributor

@frehner frehner left a comment

Choose a reason for hiding this comment

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

Looks so good!

clientState,
onClick,
location,
navigate,
Copy link
Contributor

Choose a reason for hiding this comment

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

Rules of hooks, yay

return (
<div className={className} tabIndex={1}>
/* eslint-disable jsx-a11y/no-noninteractive-tabindex */
<div className={className} tabIndex={0}>
Copy link
Contributor

Choose a reason for hiding this comment

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

Hm, this is a weird one. I feel like it would actually make more sense to have the tabindex on the custom element, but I don't know enough to know if that's correct or not.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, I don't know either. I think it should be looked at in a separate PR?

Copy link
Contributor

@cartogram cartogram May 9, 2022

Choose a reason for hiding this comment

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

I don't have a lot of context here, but from my observation... Pressing Enter when focused on this div here should have no effect so it shouldn't be tab-able IMO. In other words: the tabIndex should be removed (and the disable comment with it).

Adding tabIndex to the custom component would make sense to me too, but has no effect either when you hit Enter. I think this interaction/event-handling needs to be handled within the script that controls the component (the third-party shop-js/client script).

Copy link
Contributor

Choose a reason for hiding this comment

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

So I think the solution here is for the custom component to handle its own focus events internally, and we shouldn't have any tabIndex attribute overrides.

} else {
navigate(to);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
Copy link
Contributor

Choose a reason for hiding this comment

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

Any particular reason we want to ignore this one?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I was getting weird issues where it would execute twice, and the page wouldn't redirect. Because it's a redirect, it shouldn't matter though.

}, [initialVariantId, variants]);
const variant = getSelectedVariant(variants, selectedOptions);
setSelectedVariant(variant);
}, [selectedOptions, variants]);
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice

@blittle blittle requested a review from cartogram May 9, 2022 14:02
@Shopify Shopify deleted a comment from caution-tape-bot bot May 9, 2022
@blittle blittle force-pushed the bl-fix-product-options branch from 0340b93 to 9e82836 Compare May 9, 2022 14:13
@caution-tape-bot
Copy link

👋 It looks like you're updating JavaScript packages that are known
to cause problems when duplicated.

You can deduplicate them with the yarn-deduplicate utility:

npx yarn-deduplicate --packages graphql react react-dom webpack
npx yarn-deduplicate --scopes @shopify @apollo

If running these commands doesn't produce a change in your yarn.lock file,
you didn't have duplications in these packages and can carry on.

A duplicate React version may cause an invalid hook call warning.

React context providers usually use module-scoped globals as their
default context values. Multiple versions of such packages will yield
multiple global instances, resulting in oblique runtime errors.


const value = useMemo(
() => standardCurrencyFormatter.format(amount),
() => new Intl.NumberFormat(locale, options).format(amount),
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Might as well mov Intl.NumberFormat into the memo 🤘

Copy link
Contributor

@jplhomer jplhomer left a comment

Choose a reason for hiding this comment

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

Thanks for the diligent work!

@blittle blittle merged commit a844d26 into v1.x-2022-07 May 9, 2022
@blittle blittle deleted the bl-fix-product-options branch May 9, 2022 14:47
blittle added a commit that referenced this pull request May 9, 2022
* v1.x-2022-07:
  Fix stale product options (#1210)
  Upgrade body-parser in hydrogen package (#1232)
  Add new options to Money and useMoney (#1215)
  fix links (#1229)
  Update turbo and instructions for developing `dev` (#1225)
  Heck - deploy all branches to Oxygen
  add context for initialvariantid (#1217)
  Build chunks are inside assets folder (#1211)
  Upgraded to SFAPI 2022-07 (#1214)
  [ci] release v1.x-2022-07 (#1205)
  Make this a patch instead of minor
  add references to video in file_reference block (#1197)
  Laying the foundation for building components in isolation (#1188)
  Make metafields optional within the ProductProvider. Fixes #1127 (#1209)
  Add README to /templates directory (#1163)
  fix perf tracking and make it optional from developer's end (#1096)
  docs fixes (#1204)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants