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

refactor: avoid wrapping components with injectIntl #1413

Merged
merged 2 commits into from
Aug 13, 2019

Conversation

emmenko
Copy link
Contributor

@emmenko emmenko commented Aug 12, 2019

Fixes #1412

TL;DR: I'm not aware of a way to "forward" the types to the wrapped components when using a HOC. To keep things simple, and avoid using the HOC in the first place, we can simply use the context consumer directly.

I also refactored a bit the tests to use console.error = jest.fn(), which is the easiest way to mock the log.

@@ -34,15 +34,15 @@
"module": "./lib/index.js",
"types": "./dist/index.d.ts",
"dependencies": {
"@formatjs/intl-relativetimeformat": "^2.6.2",
"@formatjs/intl-relativetimeformat": "^2.6.3",
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 included those deps updates as I saw they were freshly published. Let me know if it's ok, otherwise I can revert.

return <Component dangerouslySetInnerHTML={html} />;
return (
<Context.Consumer>
{intl => {
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 basically everything that we need from the injectIntl

import {formatMessage as baseFormatMessage} from '../format';
import {
invariantIntlContext,
DEFAULT_INTL_CONFIG,
createFormatters,
} from '../utils';
import {PrimitiveType, FormatXMLElementFn} from 'intl-messageformat';
const shallowEquals = require('shallow-equal/objects');
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Just reordering a bit the imports

} = this.props;
return (
<Context.Consumer>
{intl => {
Copy link
Contributor Author

@emmenko emmenko Aug 12, 2019

Choose a reason for hiding this comment

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

Same thing here

}
return (
<Context.Consumer>
{intl => {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Also for this one, no need to have a HOC here

expect(console.error).toHaveBeenCalledTimes(1);
expect(console.error).toHaveBeenCalledWith(
expect.stringContaining(
'Error formatting date.\nRangeError: Value invalid out of range for dateformat options property year'
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 added more expectations to check for the error message, as it gives a better understanding of the expected behavior.

@emmenko emmenko force-pushed the nm-refactor-no-hoc-wrappers branch from 1d31e4e to 38f9a34 Compare August 12, 2019 13:38
import withIntl, {Provider} from '../../../src/components/injectIntl';
import withIntl from '../../../src/components/injectIntl';

jest.mock('intl-locales-supported');
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 necessary otherwise the test fails because the intl polyfill (for the tests) returns false for some of the intl contructors as they don't support languages other than en.

@longlho
Copy link
Member

longlho commented Aug 12, 2019

overall LGTM! Ready to merge once build if fixed. Thanks a lot for your contributions!

@emmenko emmenko force-pushed the nm-refactor-no-hoc-wrappers branch from 38f9a34 to 2ba78f2 Compare August 12, 2019 14:04
@emmenko
Copy link
Contributor Author

emmenko commented Aug 12, 2019

Awesome, glad to help!

@emmenko
Copy link
Contributor Author

emmenko commented Aug 12, 2019

Hmm wait, if I run npm test locally I get this:

❯ npm test                                     

> react-intl@3.1.6 test /Users/emmenko/dev/src/react-intl
> cross-env NODE_ICU_DATA=./node_modules/full-icu jest --coverage --verbose

node: could not initialize ICU (check NODE_ICU_DATA or --icu-data-dir parameters)
npm ERR! Test failed.  See above for more details.

I've been using npm test:watch to work on the PR...did I miss some step? 🤔

@emmenko
Copy link
Contributor Author

emmenko commented Aug 12, 2019

I guess that might explain the problem I had with #1413 (comment)

@emmenko
Copy link
Contributor Author

emmenko commented Aug 12, 2019

Ah ok, I had to npm rebuild as I switched node versions after installing the deps the first time 😅

@emmenko emmenko force-pushed the nm-refactor-no-hoc-wrappers branch from 2ba78f2 to d48aff7 Compare August 12, 2019 14:18
@emmenko
Copy link
Contributor Author

emmenko commented Aug 12, 2019

Alright, I force pushed and removed the jest.mock('intl-locales-supported'); workaround.

@@ -112,7 +112,7 @@
"release": "standard-version",
"test:all": "npm run lint && npm run format && npm run test",
"test:perf": "cross-env NODE_ENV=production babel-node test/perf",
"test:watch": "jest --watch",
"test:watch": "cross-env NODE_ICU_DATA=./node_modules/full-icu jest --watch",
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 what tricked me. Now the polyfilled data is loaded also when running jest in watch mode.

Copy link
Member

@longlho longlho Aug 12, 2019

Choose a reason for hiding this comment

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

then u prob don't need to mock intl-locales-supported right? nvm u rm'ed it. Thanks!

@longlho
Copy link
Member

longlho commented Aug 12, 2019

Ah Node 12 fails bc it comes w/ native Intl.RelativeTimeFormat so u might just to adjust the err message expectation

@marcesengel
Copy link
Collaborator

The reason why injectIntl was still being used is because it allows for more flexibility in the SCU.
Just wanted to throw this out there before the merge.

@longlho
Copy link
Member

longlho commented Aug 12, 2019

@DragonRaider5 can u provide more details? I'd love to understand that use case more.

@emmenko
Copy link
Contributor Author

emmenko commented Aug 12, 2019

The reason why injectIntl was still being used is because it allows for more flexibility in the SCU.

The only place where we currently use sCU is the message component. I don't see a problem with not using injectIntl to be honest, because if intl changes, React will update the context, causing a new re-render anyway.

Unless I'm missing some other point...

@emmenko emmenko force-pushed the nm-refactor-no-hoc-wrappers branch from 64ef553 to 72e3af8 Compare August 12, 2019 15:20
@longlho longlho merged commit ce560e7 into formatjs:master Aug 13, 2019
@emmenko emmenko deleted the nm-refactor-no-hoc-wrappers branch August 13, 2019 04:57
longlho pushed a commit that referenced this pull request Aug 30, 2019
* refactor: avoid wrapping components with injectIntl

* test: adjust message matchers for node@12 native APIs
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.

[regression >3.1.1] Type generics annotation do not get forwarded to FormattedMessage
3 participants