-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathreact-messageformat.slide
177 lines (130 loc) · 5.04 KB
/
react-messageformat.slide
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
Why Oursky uses its own localization module in react
12 Dec 2018
Rick Mak
Oursky
@rickmak
CC81327D
* Existing solutions for React translation
- react-intl <- Oursky used this before
- react-i18next
- Others?
Let's do a quick poll
* We encountered following problems with react-intl
1. Can't embed react-component in translation string
2. ICU(International Components for Unicode) parser differ from the original implementation (icu4c)
.link https://github.com/yahoo/intl-messageformat
3. Not yet support new(16.3) Context
.link https://github.com/yahoo/react-intl/pull/1186
* How is our oursky/react-messageformat different from the others
- Use a more standard ICU parser
- Support embedding react-component in ICU messageformat
- Require the 'new' Context API
* What is ICU?
- ICU is International Components for Unicode
Example
"Please input the required text {COUNT, plural, one{field} other{fields}}."
<FormattedMessage
id="Error.PleaseInputRequiredField"
values={{
COUNT: numberOfEmptyFields,
}}
/>
.link http://userguide.icu-project.org/formatparse/messages
* What is ICU adoption?
- i18next also support ICU since 7.6.0, Apr 2018
- It depends to i18next-icu, which depends on yahoo/intl-messageformat
- Android provides `android.icu` package since 7.0 (API level 24)
- Steep learning curve in ICU compared with JSON format
.link https://github.com/i18next/react-i18next/issues/303#issuecomment-332419079
- In most cases, you just need simple interpolations
- In Oursky, we don't assume simple interpolations, we deliver a good translation from day one to avoid any switching cost.
* What is the difference of ICU parser we use
- We use github.com/messageformat/parser
.link https://github.com/oursky/react-messageformat#why
- We add react directive, add it to parser to make it a first class citizen
.link https://github.com/louischan-oursky/parser/commit/f9f8d499e2dd696ce9b890dc073950a48f749a09
* React directive of ICU we added
Please {Link, react, href{http://oursky.com} children{{Text, react, children{Click me}}}}
- `Link` is the name of react-component
- `react` is the newly added directive to support react-component
- Others are passed as props, `key{value}`
Please <Link href="http://oursky.com"><Text>Click me</Text></Link>
* Example before embed
en.json
{
"delta": "{greenArrow}"
}
cn.json
{
"delta": "{redArrow}"
}
import GreenArrow from "./GreenArrow";
import RedArrow from "./RedArrow";
<FormattedMessage id="delta" value={{
greenArrow: <GreenArrow deltaPercent=10 />,
redArrow: <RedArrow deltaPercent=10 />,
}} /
}>
* Example With embed
en.json
{"delta": "{GreenArrow, react, delta{deltaPercent}"}
cn.json
{"delta": "{RedArrow, react, delta{deltaPercent}"}
import GreenArrow from "./GreenArrow";
import RedArrow from "./RedArrow";
<FormattedMessage id="delta" value={{ deltaPercent: 10 /> }}
components={{GreenArrow, RedArrow}} />
* Example before embed
en.json
{"join": "Click {HERE} to Join!"}
{"here": "here"}
cn.json
{"join": "{HERE}加入!"}
{"here": "按此!"}
import BoldLink from "./BoldLink";
<FormattedMessage id="join" values={{
HERE: <BoldLink><FormattedMessage id="here" /></BoldLink>
}} />
* Example with embed
en.json
{"join": "Click {BoldLink, react, children{here}} to Join!"}
cn.json
{"join": "{BoldLink, react, children{按此}}加入!"}
import BoldLink from "./BoldLnk";
<FormattedMessage id="join" components={{ BoldLink }} />
* Require new Context API
Just use the following and the FormattedMessage will be using new Context API
to detect locale change.
import { Provider } from "@oursky/react-messageformat";
const messages = {
"Hello.World": "Hello World!",
};
<Provider locale="en" messages={messages}>
<MyApp />
</Provider>
* The new context API will save us from
- PureComponent will not refresh on locale change. The old Context will not propagate to it.
.link https://reactjs.org/docs/legacy-context.html#updating-context
- Work around one: refresh whole app - not ideal in UX.
.link https://github.com/yahoo/react-intl/issues/243
- Use Redux to work around the context
# https://github.com/oursky/polyupaths/blob/master/web/src/intl/SyncContextIntlToReduxStore.js
# https://github.com/oursky/polyupaths/blob/master/web/src/components/Text/Text.js
* Scope of react-messageformat
- It is not aimed to be a drop-in replacement for yahoo/react-intl
- We will not do all of
.link https://github.com/yahoo/react-intl/wiki#the-react-intl-module
- For example, FormattedPlural, FormattedHTMLMessage
- We rely on the standard Intl too
.link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl
* Future development
- Support react hook API
- Support Intl.NumberFormat, using standard Intl
- Current interpolate rule is strict, it will crash on production when there is missing translation string/value.
* PR welcome!
.link https://github.com/oursky/react-messageformat
* Credit
- Louis Chan, Senior Developer, Oursky
- Chiu Chun Yin, Senior Developer, Oursky
- Ken Chan, Developer, Oursky