Compare commits
602 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1c1f68e8dc | ||
|
|
443683525f | ||
|
|
88296d994d | ||
|
|
eee3bce748 | ||
|
|
6466714e4c | ||
|
|
7df71a2525 | ||
|
|
28e51005dc | ||
|
|
fbe19e90b9 | ||
|
|
db0ec1ab0f | ||
|
|
ac0c3e60fb | ||
|
|
9d8f7aed0e | ||
|
|
3fe1664601 | ||
|
|
cc3b821f66 | ||
|
|
2692cf4f03 | ||
|
|
b691f7448f | ||
|
|
dec8b62796 | ||
|
|
44550c374f | ||
|
|
d7d9b81a85 | ||
|
|
d128b45c6f | ||
|
|
e2a70ac0ea | ||
|
|
b062596fd4 | ||
|
|
5014781d21 | ||
|
|
923aee7cf5 | ||
|
|
04ebe6d8c1 | ||
|
|
445ded0e3b | ||
|
|
de4c0127ad | ||
|
|
48949f35c5 | ||
|
|
a8fc7d80e2 | ||
|
|
ceb282a46d | ||
|
|
1668ccb2b0 | ||
|
|
95cf873e53 | ||
|
|
7d5498de1b | ||
|
|
e2c648e93c | ||
|
|
ca8ddfda02 | ||
|
|
a53e45ada0 | ||
|
|
c07ed1a498 | ||
|
|
f87407034d | ||
|
|
6f26178a3a | ||
|
|
7480eb2317 | ||
|
|
933898b457 | ||
|
|
5d08b299a7 | ||
|
|
6165c49f1d | ||
|
|
20587a4733 | ||
|
|
6a89bc9be0 | ||
|
|
ba488ce64f | ||
|
|
b06fd4b36d | ||
|
|
2d37da10db | ||
|
|
b46d90e09d | ||
|
|
4b11e25746 | ||
|
|
1d74e43b2c | ||
|
|
27ce7a9151 | ||
|
|
a9578c9d5b | ||
|
|
b82f13546f | ||
|
|
3979c734a2 | ||
|
|
24f27f81a5 | ||
|
|
9c7d8a941d | ||
|
|
f05fe34a85 | ||
|
|
ea6c7f4edb | ||
|
|
a7cb3ace36 | ||
|
|
89defaa712 | ||
|
|
24dd09fea7 | ||
|
|
1d108d8f6a | ||
|
|
60ec3c6b37 | ||
|
|
55a788e756 | ||
|
|
1cf81c1aa9 | ||
|
|
457730dded | ||
|
|
d81d9e260f | ||
|
|
c577b82875 | ||
|
|
2d049e8df6 | ||
|
|
cd65b60960 | ||
|
|
b52288cbcf | ||
|
|
4327cde28b | ||
|
|
08c320d047 | ||
|
|
2b5c43029e | ||
|
|
c8c879f1c5 | ||
|
|
a107f6d12e | ||
|
|
4717d2480c | ||
|
|
91dc94cec6 | ||
|
|
1f605930cc | ||
|
|
c7020c017d | ||
|
|
9b025df36b | ||
|
|
b0b1303207 | ||
|
|
4f20847f8b | ||
|
|
3e95d99fe2 | ||
|
|
1dce444f70 | ||
|
|
4dfe234950 | ||
|
|
8ecaaddd23 | ||
|
|
a793486541 | ||
|
|
6b85431df6 | ||
|
|
32edcfc9cd | ||
|
|
a28dc34918 | ||
|
|
3135f888f0 | ||
|
|
84fc62f30f | ||
|
|
c4c7e0a966 | ||
|
|
918037bd30 | ||
|
|
5fe354bc1e | ||
|
|
9a9a6cf10b | ||
|
|
6ac0bbfd17 | ||
|
|
75e9127216 | ||
|
|
1d099c001f | ||
|
|
ffa70704ca | ||
|
|
71f0c6fef9 | ||
|
|
a6bdb0022f | ||
|
|
1d93d28494 | ||
|
|
c3d43193c9 | ||
|
|
da9a658e35 | ||
|
|
3bc9d9caa7 | ||
|
|
d5059c91f5 | ||
|
|
ec4c0f1dd6 | ||
|
|
4d99f2bdd4 | ||
|
|
ce1f57e940 | ||
|
|
2fbe0cd333 | ||
|
|
747d65133a | ||
|
|
195b03e196 | ||
|
|
c023d53f02 | ||
|
|
c1f0b4e9da | ||
|
|
26d060797c | ||
|
|
118b93c591 | ||
|
|
654829da66 | ||
|
|
88e29060cd | ||
|
|
a7b81a60c0 | ||
|
|
db985af3c3 | ||
|
|
2c16a6bb9d | ||
|
|
b4949fd8c6 | ||
|
|
206bc2a330 | ||
|
|
2c00d750c2 | ||
|
|
ae79e023d5 | ||
|
|
bef7ae4800 | ||
|
|
b7d7f47a5e | ||
|
|
85de53c450 | ||
|
|
96d39380fa | ||
|
|
d5a769ec89 | ||
|
|
869d26c3b4 | ||
|
|
c3f2c6b19d | ||
|
|
465d35a78a | ||
|
|
bf3f9cffc2 | ||
|
|
4b7f7b371b | ||
|
|
0dd4ff1bc8 | ||
|
|
577818e419 | ||
|
|
2589ed586d | ||
|
|
b9ce809aaf | ||
|
|
dd01e016a6 | ||
|
|
329b107606 | ||
|
|
fb7b8f201f | ||
|
|
74da40520c | ||
|
|
f5f0256d82 | ||
|
|
25bdc55fb8 | ||
|
|
f5f1c749b6 | ||
|
|
951b243d17 | ||
|
|
a9b2d841f7 | ||
|
|
58d6f4fac6 | ||
|
|
03846d6916 | ||
|
|
774a94b6c2 | ||
|
|
283dbc30ee | ||
|
|
f4374bd168 | ||
|
|
87958ea037 | ||
|
|
52235eadfd | ||
|
|
cb963b09ab | ||
|
|
1fb75eaa9e | ||
|
|
a71a787038 | ||
|
|
cbc450860e | ||
|
|
ecdc185deb | ||
|
|
cc2e5cc3d7 | ||
|
|
5c2a88a9a1 | ||
|
|
5bc9daa125 | ||
|
|
21a4e7a826 | ||
|
|
556bd43a26 | ||
|
|
8426fafe90 | ||
|
|
7ae3bbee25 | ||
|
|
bada298857 | ||
|
|
5a540f778a | ||
|
|
bed4c0595c | ||
|
|
0c89348be4 | ||
|
|
53d16f86fd | ||
|
|
ecd66274a7 | ||
|
|
586f487ea9 | ||
|
|
03e7900edb | ||
|
|
345329e079 | ||
|
|
f5798f729d | ||
|
|
dcd34ab6c1 | ||
|
|
8a78b2497a | ||
|
|
58d66ad47f | ||
|
|
f6448ff595 | ||
|
|
4421c71120 | ||
|
|
9a6ef44a06 | ||
|
|
ae5ebe3d92 | ||
|
|
0c59b3c71f | ||
|
|
6e58219117 | ||
|
|
6259f15e33 | ||
|
|
e48635bd59 | ||
|
|
cf592f29bc | ||
|
|
00e9080314 | ||
|
|
17336bc8ee | ||
|
|
1df0e8a012 | ||
|
|
66a279df53 | ||
|
|
5eb67ed4e2 | ||
|
|
fcd42c1e28 | ||
|
|
c99abadafb | ||
|
|
8753a838cf | ||
|
|
749e809478 | ||
|
|
fb37b44e79 | ||
|
|
8f8a26c091 | ||
|
|
c2e9167e45 | ||
|
|
13ef94ad46 | ||
|
|
c2388bf09b | ||
|
|
b52ea6bd8f | ||
|
|
bdf263625d | ||
|
|
8c7bbbfc21 | ||
|
|
15631e02a2 | ||
|
|
1907f72934 | ||
|
|
ba62748217 | ||
|
|
224ace32be | ||
|
|
3ef748abb3 | ||
|
|
3f8b8d754c | ||
|
|
7a18e4e00b | ||
|
|
60ed71459c | ||
|
|
7b39bbaa91 | ||
|
|
2927c4ce76 | ||
|
|
3e47b3002b | ||
|
|
1bac6d567f | ||
|
|
92cfbf16c2 | ||
|
|
b445b26164 | ||
|
|
832c503c92 | ||
|
|
076d7fd63a | ||
|
|
3ed71070a3 | ||
|
|
08dbefedc7 | ||
|
|
4be377650e | ||
|
|
8898803b4a | ||
|
|
21f71d72f0 | ||
|
|
d79061e0c6 | ||
|
|
d951c560e4 | ||
|
|
6cf782b75c | ||
|
|
dca0f7315c | ||
|
|
0983d2dbcf | ||
|
|
d90cbec236 | ||
|
|
6e20d410bb | ||
|
|
b4f6460bff | ||
|
|
199056cf1b | ||
|
|
681c68c62a | ||
|
|
cc41ec258f | ||
|
|
3c0906ca24 | ||
|
|
60a3655469 | ||
|
|
15df676d2e | ||
|
|
e5276bbbe7 | ||
|
|
12ab5baff4 | ||
|
|
f120c1b78e | ||
|
|
421bb8c53a | ||
|
|
9fea8ec6c8 | ||
|
|
536f826b56 | ||
|
|
307b4ebcc9 | ||
|
|
e1a9eb13b1 | ||
|
|
51fe7e466e | ||
|
|
8403a28adc | ||
|
|
c4f8466d5d | ||
|
|
cc5889c543 | ||
|
|
9e88467485 | ||
|
|
bfb3852942 | ||
|
|
df4356133d | ||
|
|
814be45aa8 | ||
|
|
bab9227e9d | ||
|
|
2f1ce9169d | ||
|
|
b19f202542 | ||
|
|
71f12283d9 | ||
|
|
4c5882258c | ||
|
|
ce24114a01 | ||
|
|
8e79c9fd30 | ||
|
|
5372e66c0c | ||
|
|
94dbf619d3 | ||
|
|
9d7ceac1f3 | ||
|
|
6a992382a4 | ||
|
|
c93d0c4f30 | ||
|
|
f2010e5532 | ||
|
|
5dce7c21e3 | ||
|
|
382f1519b2 | ||
|
|
38914dfe6a | ||
|
|
f65d629541 | ||
|
|
7608eda1ff | ||
|
|
21d9b85d66 | ||
|
|
44fa2c83d1 | ||
|
|
bad1080586 | ||
|
|
992e11b852 | ||
|
|
043c249458 | ||
|
|
d551e19b18 | ||
|
|
58720d608e | ||
|
|
3c7f275f4f | ||
|
|
77d6143485 | ||
|
|
d0fc12db61 | ||
|
|
ae17ce5b03 | ||
|
|
8794c51389 | ||
|
|
8a1c16bf09 | ||
|
|
1f65b2901b | ||
|
|
9be069fb98 | ||
|
|
b194f66fbc | ||
|
|
1d4e8c958d | ||
|
|
b071f10dd7 | ||
|
|
44f63165cb | ||
|
|
cc01d1be33 | ||
|
|
66cee497e7 | ||
|
|
7251f6a6e9 | ||
|
|
f7837682b4 | ||
|
|
41f21520d1 | ||
|
|
e5efe5f568 | ||
|
|
396ab3eba1 | ||
|
|
01ad9af590 | ||
|
|
5d2f6c07c3 | ||
|
|
6cab7064a0 | ||
|
|
6f80ed8615 | ||
|
|
88d49edda5 | ||
|
|
5f705664fa | ||
|
|
6fba1f1fad | ||
|
|
127af0ffc7 | ||
|
|
86f72d0830 | ||
|
|
9423829db2 | ||
|
|
f8a698e9af | ||
|
|
807244badd | ||
|
|
2106bf5085 | ||
|
|
2debcef8f6 | ||
|
|
7cdcb4f696 | ||
|
|
8f8e215df1 | ||
|
|
0c56ee7a89 | ||
|
|
dfebed11c2 | ||
|
|
0394bae0e3 | ||
|
|
1e4828d9fc | ||
|
|
108f25350d | ||
|
|
f40b5b5c47 | ||
|
|
b38bbde2fe | ||
|
|
939071d737 | ||
|
|
42d7d0adad | ||
|
|
14e6a69a46 | ||
|
|
b1e1ccf632 | ||
|
|
7b78757c6f | ||
|
|
7d3cf9565e | ||
|
|
86cc1d4e67 | ||
|
|
80d09bfbb3 | ||
|
|
615ae2f497 | ||
|
|
1c3b4af564 | ||
|
|
40cc8fa45f | ||
|
|
ea61ddb0d0 | ||
|
|
9f975293e1 | ||
|
|
d40393fde7 | ||
|
|
8517e99816 | ||
|
|
cf07f0cab1 | ||
|
|
ddb58dd9f3 | ||
|
|
7d9ded56a2 | ||
|
|
e75e8dcbeb | ||
|
|
4a0a534357 | ||
|
|
d441128bf6 | ||
|
|
891e087926 | ||
|
|
9d385ef326 | ||
|
|
3b80d4dcd7 | ||
|
|
343033bf06 | ||
|
|
b688bb301c | ||
|
|
9138b45e82 | ||
|
|
1b7f871819 | ||
|
|
52e45997db | ||
|
|
45547d1c3b | ||
|
|
0f520b8cc0 | ||
|
|
5478d76271 | ||
|
|
57a1ebb809 | ||
|
|
dfb5cc306f | ||
|
|
ea880f2e2c | ||
|
|
68faf9d1b9 | ||
|
|
5597ca70be | ||
|
|
4b9d48a150 | ||
|
|
6b19617333 | ||
|
|
86d696d933 | ||
|
|
e685ca9126 | ||
|
|
abaa9a8760 | ||
|
|
ebabd2f8cd | ||
|
|
c51e8a1523 | ||
|
|
9fb898943a | ||
|
|
ccd781d97e | ||
|
|
9db68fcf5d | ||
|
|
219e838070 | ||
|
|
720ce5aa70 | ||
|
|
a0a8f2a451 | ||
|
|
67cc922747 | ||
|
|
75e6399261 | ||
|
|
25528eacbc | ||
|
|
f6b619aab1 | ||
|
|
7547d0d8e5 | ||
|
|
d7a6c95464 | ||
|
|
9687b35d83 | ||
|
|
173d065a9e | ||
|
|
67cbe6d471 | ||
|
|
c625bc88aa | ||
|
|
f1f599d775 | ||
|
|
c4b719d4dc | ||
|
|
e23690a0dc | ||
|
|
20d2398ab6 | ||
|
|
32cadeacdb | ||
|
|
a3c0d68af9 | ||
|
|
24cf5c7a5e | ||
|
|
8ea1ee14d5 | ||
|
|
ec029f66cc | ||
|
|
ba6ca7ff71 | ||
|
|
eb9f4efde7 | ||
|
|
8ee93720ce | ||
|
|
cea00b4b21 | ||
|
|
f3c9508e95 | ||
|
|
23de673537 | ||
|
|
26870ad27b | ||
|
|
54ee110436 | ||
|
|
a011a23090 | ||
|
|
0d4c994471 | ||
|
|
bc1d59ee19 | ||
|
|
3a6584b2ee | ||
|
|
c650249339 | ||
|
|
516aa96419 | ||
|
|
1808ecb348 | ||
|
|
74c29b391a | ||
|
|
33f54bfaa1 | ||
|
|
5131a43f96 | ||
|
|
62135da3ba | ||
|
|
7fbbb535ff | ||
|
|
bda788e932 | ||
|
|
ec44f2af6d | ||
|
|
6059444c84 | ||
|
|
814bf1ca0c | ||
|
|
aaa496213e | ||
|
|
c66f40f749 | ||
|
|
e921abf260 | ||
|
|
d893ab6428 | ||
|
|
dbb67824a4 | ||
|
|
592abf8ee7 | ||
|
|
2a411dd248 | ||
|
|
909d647801 | ||
|
|
243be87c6d | ||
|
|
eab4ffa721 | ||
|
|
1e0f0a35cf | ||
|
|
d4aebaa671 | ||
|
|
cd5189a63c | ||
|
|
cf50a83b8d | ||
|
|
89746fa70f | ||
|
|
e1c2c42c24 | ||
|
|
05c133a9c3 | ||
|
|
92bda144d9 | ||
|
|
6eeb2898f7 | ||
|
|
e974383cba | ||
|
|
7912baea69 | ||
|
|
07389fd9fc | ||
|
|
7a4aef0d0d | ||
|
|
85fd90d4c2 | ||
|
|
6080ab547d | ||
|
|
6562466c9e | ||
|
|
904c6e767b | ||
|
|
58634bda69 | ||
|
|
cb10a45ded | ||
|
|
90007f7087 | ||
|
|
39ddfdd9a2 | ||
|
|
ab4ea744f9 | ||
|
|
60cc2fe911 | ||
|
|
74ea71b324 | ||
|
|
3d748e93f1 | ||
|
|
a5d7fc84ee | ||
|
|
e8a8d005f0 | ||
|
|
2f4c61d1be | ||
|
|
677dd27912 | ||
|
|
689f5cc187 | ||
|
|
8f8d9a9dde | ||
|
|
634b107491 | ||
|
|
31ba751d2e | ||
|
|
c8b2a3dc13 | ||
|
|
58313419e2 | ||
|
|
8e598ea5c6 | ||
|
|
58f0298c62 | ||
|
|
f98e6c1955 | ||
|
|
a2f7b34f38 | ||
|
|
fad173a0f9 | ||
|
|
c1a9d1c0e0 | ||
|
|
3cf363384e | ||
|
|
bff0662ba3 | ||
|
|
8b6749dedd | ||
|
|
00095e3cbd | ||
|
|
6890805b16 | ||
|
|
c654fdf709 | ||
|
|
c060f4ac3d | ||
|
|
23d3e70b4e | ||
|
|
d945077f42 | ||
|
|
6607ffb9ec | ||
|
|
ad5902bc39 | ||
|
|
5247dc3cd2 | ||
|
|
b340601ef6 | ||
|
|
0f6081ee26 | ||
|
|
c17797f979 | ||
|
|
6638d49ad9 | ||
|
|
659ff22ea4 | ||
|
|
442d78a556 | ||
|
|
a599587fce | ||
|
|
9483255583 | ||
|
|
b3d37a908c | ||
|
|
e039795971 | ||
|
|
47d0f21c60 | ||
|
|
a88d821d9f | ||
|
|
460c4c2b9a | ||
|
|
3bf315d70e | ||
|
|
5d3920f5ab | ||
|
|
69208fc62a | ||
|
|
484a5b38af | ||
|
|
f112083c7a | ||
|
|
2ef148d1ee | ||
|
|
818ef42d22 | ||
|
|
d77b28e90b | ||
|
|
2183e55c12 | ||
|
|
b3d3ae42ed | ||
|
|
61924171bf | ||
|
|
20a081eb37 | ||
|
|
7dbf29a10d | ||
|
|
440543aa88 | ||
|
|
4725941c74 | ||
|
|
f14d0ef339 | ||
|
|
c595c27357 | ||
|
|
6d378bf78e | ||
|
|
23c4d31291 | ||
|
|
6af9f59010 | ||
|
|
571d1f7314 | ||
|
|
dd29092472 | ||
|
|
3a48eef3c8 | ||
|
|
f80da18f2e | ||
|
|
c4c800416f | ||
|
|
a6e4c9210d | ||
|
|
764519245b | ||
|
|
902a15d149 | ||
|
|
3e61ccc2d4 | ||
|
|
3aaf9abb73 | ||
|
|
e348891410 | ||
|
|
45469fbde9 | ||
|
|
0bc349c450 | ||
|
|
6aacfdb9ba | ||
|
|
5aa1c3547e | ||
|
|
c1c31f2cba | ||
|
|
79707ca3ee | ||
|
|
5fcb784294 | ||
|
|
0a1e5eb93b | ||
|
|
826d2ac716 | ||
|
|
878644b358 | ||
|
|
ef4efcced1 | ||
|
|
9e1a44e6bb | ||
|
|
7819816cc9 | ||
|
|
087c4c8b3c | ||
|
|
b370918e0c | ||
|
|
e6ad21933b | ||
|
|
22b96dd414 | ||
|
|
aa2edb427a | ||
|
|
39d6f49896 | ||
|
|
e0a82f4921 | ||
|
|
b95a23ce78 | ||
|
|
7842c19934 | ||
|
|
fef495942a | ||
|
|
b7d480986a | ||
|
|
da6a30b022 | ||
|
|
bca912f91e | ||
|
|
5b77fff586 | ||
|
|
95db5bab42 | ||
|
|
b4c1356d18 | ||
|
|
668dd47700 | ||
|
|
d9bcda01db | ||
|
|
8c50a04455 | ||
|
|
80b849e2a0 | ||
|
|
e15a7d1f7e | ||
|
|
7da8884581 | ||
|
|
871523c8f4 | ||
|
|
09172b112f | ||
|
|
3adc4a6e0e | ||
|
|
b29bf7515b | ||
|
|
cba62feeec | ||
|
|
09c6d53e64 | ||
|
|
78aa706491 | ||
|
|
f50d542ff7 | ||
|
|
583d7205c6 | ||
|
|
1f1dba92a8 | ||
|
|
258e591e45 | ||
|
|
42d27cd152 | ||
|
|
d8d6c7a07b | ||
|
|
4f0163fd38 | ||
|
|
0244879c8f | ||
|
|
743e4c6231 | ||
|
|
c3d99b5292 | ||
|
|
d1f519e0cd | ||
|
|
ff3cec5beb | ||
|
|
b0deadc05d | ||
|
|
ced4ef9ad6 | ||
|
|
ca19ae5ad0 | ||
|
|
9460263e41 | ||
|
|
197ecabb9a | ||
|
|
ee459684f1 | ||
|
|
6516c72ef1 | ||
|
|
9d022818e1 | ||
|
|
b9ae9f5f38 | ||
|
|
b8ac9e1597 | ||
|
|
9537b240de | ||
|
|
9c6de78844 | ||
|
|
6bb4fea31d | ||
|
|
97849a08cd | ||
|
|
2f435912d8 | ||
|
|
d737dc6dd2 | ||
|
|
1b22f12acd | ||
|
|
69bb9e3c8c | ||
|
|
772b5f9a5a | ||
|
|
64acaca8ee | ||
|
|
0008beb1fb | ||
|
|
846b5ea252 |
7
.babelrc
7
.babelrc
@@ -2,9 +2,9 @@
|
||||
"presets": ["react"],
|
||||
"ignore": ["third_party"],
|
||||
"plugins": [
|
||||
"fbjs-scripts/babel-6/dev-expression",
|
||||
"transform-class-properties",
|
||||
"syntax-trailing-function-commas",
|
||||
"babel-plugin-transform-object-rest-spread",
|
||||
"transform-object-rest-spread",
|
||||
"transform-es2015-template-literals",
|
||||
"transform-es2015-literals",
|
||||
"transform-es2015-arrow-functions",
|
||||
@@ -22,6 +22,7 @@
|
||||
"transform-es2015-modules-commonjs",
|
||||
"transform-es3-member-expression-literals",
|
||||
"transform-es3-property-literals",
|
||||
"./scripts/babel/transform-object-assign-require"
|
||||
"./scripts/babel/transform-object-assign-require",
|
||||
"transform-react-jsx-source"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# We can probably lint these later but not important at this point
|
||||
src/renderers/art
|
||||
src/shared/vendor
|
||||
# But not in docs/_js/examples/*
|
||||
docs/_js/*.js
|
||||
|
||||
@@ -30,6 +30,7 @@ module.exports = {
|
||||
'indent': [ERROR, 2, {SwitchCase: 1}],
|
||||
'jsx-quotes': [ERROR, 'prefer-double'],
|
||||
'no-bitwise': OFF,
|
||||
'no-inner-declarations': [ERROR, 'functions'],
|
||||
'no-multi-spaces': ERROR,
|
||||
'no-restricted-syntax': [ERROR, 'WithStatement'],
|
||||
'no-shadow': ERROR,
|
||||
|
||||
37
.flowconfig
Normal file
37
.flowconfig
Normal file
@@ -0,0 +1,37 @@
|
||||
[ignore]
|
||||
|
||||
<PROJECT_ROOT>/examples/.*
|
||||
<PROJECT_ROOT>/build/.*
|
||||
<PROJECT_ROOT>/.*/node_modules/y18n/.*
|
||||
<PROJECT_ROOT>/.*/__mocks__/.*
|
||||
<PROJECT_ROOT>/.*/__tests__/.*
|
||||
|
||||
# Ignore Docs
|
||||
<PROJECT_ROOT>/.*/docs/.*
|
||||
|
||||
[include]
|
||||
|
||||
[libs]
|
||||
./node_modules/fbjs/flow/lib
|
||||
./flow
|
||||
|
||||
[options]
|
||||
module.system=haste
|
||||
|
||||
esproposal.class_static_fields=enable
|
||||
esproposal.class_instance_fields=enable
|
||||
|
||||
munge_underscores=false
|
||||
|
||||
suppress_type=$FlowIssue
|
||||
suppress_type=$FlowFixMe
|
||||
suppress_type=$FixMe
|
||||
suppress_type=$FlowExpectedError
|
||||
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(3[0-1]\\|[1-2][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*www[a-z,_]*\\)?)\\)
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(3[0-1]\\|[1-2][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*www[a-z,_]*\\)?)\\)?:? #[0-9]+
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError
|
||||
|
||||
[version]
|
||||
^0.31.0
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -15,9 +15,10 @@ docs/code
|
||||
docs/_site
|
||||
docs/.sass-cache
|
||||
docs/js/*
|
||||
docs/downloads
|
||||
docs/downloads/*.zip
|
||||
docs/vendor/bundle
|
||||
examples/shared/*.js
|
||||
examples/**/bundle.js
|
||||
test/the-files-to-test.generated.js
|
||||
*.log*
|
||||
chrome-user-data
|
||||
|
||||
42
.travis.yml
42
.travis.yml
@@ -1,8 +1,11 @@
|
||||
---
|
||||
sudo: required
|
||||
dist: trusty
|
||||
language: node_js
|
||||
node_js:
|
||||
- 4
|
||||
sudo: false
|
||||
rvm:
|
||||
- 2.2.3
|
||||
cache:
|
||||
directories:
|
||||
- docs/vendor/bundle
|
||||
@@ -25,8 +28,8 @@ script:
|
||||
|
||||
GH_PAGES_DIR="$TRAVIS_BUILD_DIR"/../react-gh-pages
|
||||
echo "machine github.com login reactjs-bot password $GITHUB_TOKEN" >~/.netrc
|
||||
git config --global user.name "Travis CI"
|
||||
git config --global user.email "travis@reactjs.org"
|
||||
git config --global user.name "$GITHUB_USER_NAME"
|
||||
git config --global user.email "$GITHUB_USER_EMAIL"
|
||||
|
||||
git clone --branch gh-pages --depth=50 \
|
||||
https://reactjs-bot@github.com/facebook/react.git \
|
||||
@@ -36,7 +39,7 @@ script:
|
||||
bundle exec rake release
|
||||
cd $GH_PAGES_DIR
|
||||
git status
|
||||
if ! git diff-index --quiet HEAD --; then
|
||||
if test -n "$(git status --porcelain)"; then
|
||||
git add -A .
|
||||
git commit -m "Rebuild website"
|
||||
git push origin gh-pages
|
||||
@@ -68,12 +71,40 @@ script:
|
||||
fi
|
||||
elif [ "$TEST_TYPE" = test ]; then
|
||||
set -e
|
||||
./node_modules/.bin/grunt jest:normal
|
||||
./node_modules/.bin/grunt jest:coverage
|
||||
cat ./coverage/lcov.info | ./node_modules/.bin/coveralls
|
||||
|
||||
echo 'Testing in server-render (HTML generation) mode...'
|
||||
printf '\nmodule.exports.useCreateElement = false;\n' \
|
||||
>> src/renderers/dom/shared/ReactDOMFeatureFlags.js
|
||||
./node_modules/.bin/grunt jest:normal
|
||||
git checkout -- src/renderers/dom/shared/ReactDOMFeatureFlags.js
|
||||
|
||||
echo 'Testing in fiber mode...'
|
||||
printf '\nmodule.exports.useFiber = true;\n' \
|
||||
>> src/renderers/dom/shared/ReactDOMFeatureFlags.js
|
||||
FIBER_TESTS=`\
|
||||
NODE_ENV=test node node_modules/jest/bin/jest --json | \
|
||||
node -e "\
|
||||
var data = JSON.parse(require('fs').readFileSync('/dev/stdin', 'utf8')); \
|
||||
console.log(data.numPassedTests + '/' + data.numTotalTests)\
|
||||
"\
|
||||
`
|
||||
git checkout -- src/renderers/dom/shared/ReactDOMFeatureFlags.js
|
||||
node scripts/facts-tracker/index.js \
|
||||
"fiber-tests" "$FIBER_TESTS"
|
||||
|
||||
./node_modules/.bin/gulp react:extract-errors
|
||||
elif [ "$TEST_TYPE" = flow ]; then
|
||||
set -e
|
||||
./node_modules/.bin/grunt flow
|
||||
|
||||
ALL_FILES=`find src -name '*.js' | grep -v umd/ | grep -v __tests__ | grep -v __mocks__`
|
||||
COUNT_ALL_FILES=`echo "$ALL_FILES" | wc -l`
|
||||
COUNT_WITH_FLOW=`grep '@flow' $ALL_FILES | perl -pe 's/:.+//' | wc -l`
|
||||
node scripts/facts-tracker/index.js \
|
||||
"flow-files" "$COUNT_WITH_FLOW/$COUNT_ALL_FILES"
|
||||
|
||||
else
|
||||
./node_modules/.bin/grunt $TEST_TYPE
|
||||
fi
|
||||
@@ -82,6 +113,7 @@ env:
|
||||
- TEST_TYPE=build
|
||||
- TEST_TYPE=test
|
||||
- TEST_TYPE=lint
|
||||
- TEST_TYPE=flow
|
||||
- TEST_TYPE=build_website
|
||||
global:
|
||||
# SERVER
|
||||
|
||||
209
CHANGELOG.md
209
CHANGELOG.md
@@ -1,3 +1,204 @@
|
||||
## 15.4.0 (November 16, 2016)
|
||||
|
||||
### React
|
||||
* React package and browser build no longer "secretly" includes React DOM. ([@sebmarkbage](https://github.com/sebmarkbage) in [#7164](https://github.com/facebook/react/pull/7164) and [#7168](https://github.com/facebook/react/pull/7168))
|
||||
* Required PropTypes now fail with specific messages for null and undefined. ([@chenglou](https://github.com/chenglou) in [#7291](https://github.com/facebook/react/pull/7291))
|
||||
* Improved development performance by freezing children instead of copying. ([@keyanzhang](https://github.com/keyanzhang) in [#7455](https://github.com/facebook/react/pull/7455))
|
||||
|
||||
### React DOM
|
||||
* Fixed occasional test failures when React DOM is used together with shallow renderer. ([@goatslacker](https://github.com/goatslacker) in [#8097](https://github.com/facebook/react/pull/8097))
|
||||
* Added a warning for invalid `aria-` attributes. ([@jessebeach](https://github.com/jessebeach) in [#7744](https://github.com/facebook/react/pull/7744))
|
||||
* Added a warning for using `autofocus` rather than `autoFocus`. ([@hkal](https://github.com/hkal) in [#7694](https://github.com/facebook/react/pull/7694))
|
||||
* Removed an unnecessary warning about polyfilling `String.prototype.split`. ([@nhunzaker](https://github.com/nhunzaker) in [#7629](https://github.com/facebook/react/pull/7629))
|
||||
* Clarified the warning about not calling PropTypes manually. ([@jedwards1211](https://github.com/jedwards1211) in [#7777](https://github.com/facebook/react/pull/7777))
|
||||
* The unstable `batchedUpdates` API now passes the wrapped function's return value through. ([@bgnorlov](https://github.com/bgnorlov) in [#7444](https://github.com/facebook/react/pull/7444))
|
||||
* Fixed a bug with updating text in IE 8. ([@mnpenner](https://github.com/mnpenner) in [#7832](https://github.com/facebook/react/pull/7832))
|
||||
|
||||
### React Perf
|
||||
* When ReactPerf is started, you can now view the relative time spent in components as a chart in Chrome Timeline. ([@gaearon](https://github.com/gaearon) in [#7549](https://github.com/facebook/react/pull/7549))
|
||||
|
||||
### React Test Utils
|
||||
* If you call `Simulate.click()` on a `<input disabled onClick={foo} />` then `foo` will get called whereas it didn't before. ([@nhunzaker](https://github.com/nhunzaker) in [#7642](https://github.com/facebook/react/pull/7642))
|
||||
|
||||
### React Test Renderer
|
||||
* Due to packaging changes, it no longer crashes when imported together with React DOM in the same file. ([@sebmarkbage](https://github.com/sebmarkbage) in [#7164](https://github.com/facebook/react/pull/7164) and [#7168](https://github.com/facebook/react/pull/7168))
|
||||
* `ReactTestRenderer.create()` now accepts `{createNodeMock: element => mock}` as an optional argument so you can mock refs with snapshot testing. ([@Aweary](https://github.com/Aweary) in [#7649](https://github.com/facebook/react/pull/7649), [#8261](https://github.com/facebook/react/pull/8261))
|
||||
|
||||
|
||||
## 15.3.2 (September 19, 2016)
|
||||
|
||||
### React
|
||||
- Remove plain object warning from React.createElement & React.cloneElement. ([@spudly](https://github.com/spudly) in [#7724](https://github.com/facebook/react/pull/7724))
|
||||
|
||||
### React DOM
|
||||
- Add `playsInline` to supported HTML attributes. ([@reaperhulk](https://github.com/reaperhulk) in [#7519](https://github.com/facebook/react/pull/7519))
|
||||
- Add `as` to supported HTML attributes. ([@kevinslin](https://github.com/kevinslin) in [#7582](https://github.com/facebook/react/pull/7582))
|
||||
- Improve DOM nesting validation warning about whitespace. ([@spicyj](https://github.com/spicyj) in [#7515](https://github.com/facebook/react/pull/7515))
|
||||
- Avoid "Member not found" exception in IE10 when calling `preventDefault()` in Synthetic Events. ([@g-palmer](https://github.com/g-palmer) in [#7411](https://github.com/facebook/react/pull/7411))
|
||||
- Fix memory leak in `onSelect` implementation. ([@AgtLucas](https://github.com/AgtLucas) in [#7533](https://github.com/facebook/react/pull/7533))
|
||||
- Improve robustness of `document.documentMode` checks to handle Google Tag Manager. ([@SchleyB](https://github.com/SchleyB) in [#7594](https://github.com/facebook/react/pull/7594))
|
||||
- Add more cases to controlled inputs warning. ([@marcin-mazurek](https://github.com/marcin-mazurek) in [#7544](https://github.com/facebook/react/pull/7544))
|
||||
- Handle case of popup blockers overriding `document.createEvent`. ([@Andarist](https://github.com/Andarist) in [#7621](https://github.com/facebook/react/pull/7621))
|
||||
- Fix issue with `dangerouslySetInnerHTML` and SVG in Internet Explorer. ([@zpao](https://github.com/zpao) in [#7618](https://github.com/facebook/react/pull/7618))
|
||||
- Improve handling of Japanese IME on Internet Explorer. ([@msmania](https://github.com/msmania) in [#7107](https://github.com/facebook/react/pull/7107))
|
||||
|
||||
### React Test Renderer
|
||||
- Support error boundaries. ([@millermedeiros](https://github.com/millermedeiros) in [#7558](https://github.com/facebook/react/pull/7558), [#7569](https://github.com/facebook/react/pull/7569), [#7619](https://github.com/facebook/react/pull/7619))
|
||||
- Skip null ref warning. ([@Aweary](https://github.com/Aweary) in [#7658](https://github.com/facebook/react/pull/7658))
|
||||
|
||||
### React Perf Add-on
|
||||
- Ensure lifecycle timers are stopped on errors. ([@gaearon](https://github.com/gaearon) in [#7548](https://github.com/facebook/react/pull/7548))
|
||||
|
||||
|
||||
## 15.3.1 (August 19, 2016)
|
||||
|
||||
### React
|
||||
|
||||
- Improve performance of development builds in various ways. ([@gaearon](https://github.com/gaearon) in [#7461](https://github.com/facebook/react/pull/7461), [#7463](https://github.com/facebook/react/pull/7463), [#7483](https://github.com/facebook/react/pull/7483), [#7488](https://github.com/facebook/react/pull/7488), [#7491](https://github.com/facebook/react/pull/7491), [#7510](https://github.com/facebook/react/pull/7510))
|
||||
- Cleanup internal hooks to improve performance of development builds. ([@gaearon](https://github.com/gaearon) in [#7464](https://github.com/facebook/react/pull/7464), [#7472](https://github.com/facebook/react/pull/7472), [#7481](https://github.com/facebook/react/pull/7481), [#7496](https://github.com/facebook/react/pull/7496))
|
||||
- Upgrade fbjs to pick up another performance improvement from [@gaearon](https://github.com/gaearon) for development builds. ([@zpao](https://github.com/zpao) in [#7532](https://github.com/facebook/react/pull/7532))
|
||||
- Improve startup time of React in Node. ([@zertosh](https://github.com/zertosh) in [#7493](https://github.com/facebook/react/pull/7493))
|
||||
- Improve error message of `React.Children.only`. ([@spicyj](https://github.com/spicyj) in [#7514](https://github.com/facebook/react/pull/7514))
|
||||
|
||||
### React DOM
|
||||
- Avoid `<input>` validation warning from browsers when changing `type`. ([@nhunzaker](https://github.com/nhunzaker) in [#7333](https://github.com/facebook/react/pull/7333))
|
||||
- Avoid "Member not found" exception in IE10 when calling `stopPropagation()` in Synthetic Events. ([@nhunzaker](https://github.com/nhunzaker) in [#7343](https://github.com/facebook/react/pull/7343))
|
||||
- Fix issue resulting in inability to update some `<input>` elements in mobile browsers. ([@keyanzhang](https://github.com/keyanzhang) in [#7397](https://github.com/facebook/react/pull/7397))
|
||||
- Fix memory leak in server rendering. ([@keyanzhang](https://github.com/keyanzhang) in [#7410](https://github.com/facebook/react/pull/7410))
|
||||
- Fix issue resulting in `<input type="range">` values not updating when changing `min` or `max`. ([@troydemonbreun](https://github.com/troydemonbreun) in [#7486](https://github.com/facebook/react/pull/7486))
|
||||
- Add new warning for rare case of attempting to unmount a container owned by a different copy of React. ([@ventuno](https://github.com/ventuno) in [#7456](https://github.com/facebook/react/pull/7456))
|
||||
|
||||
### React Test Renderer
|
||||
- Fix ReactTestInstance::toJSON() with empty top-level components. ([@Morhaus](https://github.com/Morhaus) in [#7523](https://github.com/facebook/react/pull/7523))
|
||||
|
||||
### React Native Renderer
|
||||
- Change `trackedTouchCount` invariant into a console.error for better reliability. ([@yungsters](https://github.com/yungsters) in [#7400](https://github.com/facebook/react/pull/7400))
|
||||
|
||||
|
||||
## 15.3.0 (July 29, 2016)
|
||||
|
||||
### React
|
||||
- Add `React.PureComponent` - a new base class to extend, replacing `react-addons-pure-render-mixin` now that mixins don't work with ES2015 classes. ([@spicyj](https://github.com/spicyj) in [#7195](https://github.com/facebook/react/pull/7195))
|
||||
- Add new warning when modifying `this.props.children`. ([@jimfb](https://github.com/jimfb) in [#7001](https://github.com/facebook/react/pull/7001))
|
||||
- Fixed issue with ref resolution order. ([@gaearon](https://github.com/gaearon) in [#7101](https://github.com/facebook/react/pull/7101))
|
||||
- Warn when mixin is undefined. ([@swaroopsm](https://github.com/swaroopsm) in [#6158](https://github.com/facebook/react/pull/6158))
|
||||
- Downgrade "unexpected batch number" invariant to a warning. ([@spicyj](https://github.com/spicyj) in [#7133](https://github.com/facebook/react/pull/7133))
|
||||
- Validate arguments to `oneOf` and `oneOfType` PropTypes sooner. ([@troydemonbreun](https://github.com/troydemonbreun) in [#6316](https://github.com/facebook/react/pull/6316))
|
||||
- Warn when calling PropTypes directly. ([@Aweary](https://github.com/Aweary) in [#7132](https://github.com/facebook/react/pull/7132), [#7194](https://github.com/facebook/react/pull/7194))
|
||||
- Improve warning when using Maps as children. ([@keyanzhang](https://github.com/keyanzhang) in [#7260](https://github.com/facebook/react/pull/7260))
|
||||
- Add additional type information to the `PropTypes.element` warning. ([@alexzherdev](https://github.com/alexzherdev) in [#7319](https://github.com/facebook/react/pull/7319))
|
||||
- Improve component identification in no-op `setState` warning. ([@keyanzhang](https://github.com/keyanzhang) in [#7326](https://github.com/facebook/react/pull/7326))
|
||||
|
||||
### React DOM
|
||||
- Fix issue with nested server rendering. ([@Aweary](https://github.com/Aweary) in [#7033](https://github.com/facebook/react/pull/7033))
|
||||
- Add `xmlns`, `xmlnsXlink` to supported SVG attributes. ([@salzhrani](https://github.com/salzhrani) in [#6471](https://github.com/facebook/react/pull/6471))
|
||||
- Add `referrerPolicy` to supported HTML attributes. ([@Aweary](https://github.com/Aweary) in [#7274](https://github.com/facebook/react/pull/7274))
|
||||
- Fix issue resulting in `<input type="range">` initial value being rounded. ([@troydemonbreun](https://github.com/troydemonbreun) in [#7251](https://github.com/facebook/react/pull/7251))
|
||||
|
||||
### React Test Renderer
|
||||
- Initial public release of package allowing more focused testing. Install with `npm install react-test-renderer`. ([@spicyj](https://github.com/spicyj) in [#6944](https://github.com/facebook/react/pull/6944), [#7258](https://github.com/facebook/react/pull/7258), [@iamdustan](https://github.com/iamdustan) in [#7362](https://github.com/facebook/react/pull/7362))
|
||||
|
||||
### React Perf Add-on
|
||||
- Fix issue resulting in excessive warnings when encountering an internal measurement error. ([@sassanh](https://github.com/sassanh) in [#7299](https://github.com/facebook/react/pull/7299))
|
||||
|
||||
### React TestUtils Add-on
|
||||
- Implement `type` property on for events created via `TestUtils.Simulate.*`. ([@yaycmyk](https://github.com/yaycmyk) in [#6154](https://github.com/facebook/react/pull/6154))
|
||||
- Fix crash when running TestUtils with the production build of React. ([@gaearon](https://github.com/gaearon) in [#7246](https://github.com/facebook/react/pull/7246))
|
||||
|
||||
|
||||
## 15.2.1 (July 8, 2016)
|
||||
|
||||
### React
|
||||
- Fix errant warning about missing React element. ([@gaearon](https://github.com/gaearon) in [#7193](https://github.com/facebook/react/pull/7193))
|
||||
- Better removal of dev-only code, leading to a small reduction in the minified production bundle size. ([@gaearon](https://github.com/gaearon) in [#7188](https://github.com/facebook/react/pull/7188), [#7189](https://github.com/facebook/react/pull/7189))
|
||||
|
||||
### React DOM
|
||||
- Add stack trace to null input value warning. ([@jimfb](https://github.com/jimfb) in [#7040](https://github.com/facebook/react/pull/7040))
|
||||
- Fix webcomponents example. ([@jalexanderfox](https://github.com/jalexanderfox) in [#7057](https://github.com/facebook/react/pull/7057))
|
||||
- Fix `unstable_renderSubtreeIntoContainer` so that context properly updates when linked to state. ([@gaearon](https://github.com/gaearon) in [#7125](https://github.com/facebook/react/pull/7125))
|
||||
- Improve invariant wording for void elements. ([@starkch](https://github.com/starkch) in [#7066](https://github.com/facebook/react/pull/7066))
|
||||
- Ensure no errors are thrown due to event handlers in server rendering. ([@rricard](https://github.com/rricard) in [#7127](https://github.com/facebook/react/pull/7127))
|
||||
- Fix regression resulting in `value`-less submit and reset inputs removing the browser-default text. ([@zpao](https://github.com/zpao) in [#7197](https://github.com/facebook/react/pull/7197))
|
||||
- Fix regression resulting in empty `name` attribute being added to inputs when not provided. ([@okonet](https://github.com/okonet) in [#7199](https://github.com/facebook/react/pull/7199))
|
||||
- Fix issue with nested server rendering. ([@Aweary](https://github.com/Aweary) in [#7033](https://github.com/facebook/react/pull/7033))
|
||||
|
||||
### React Perf Add-on
|
||||
- Make `ReactPerf.start()` work properly during lifecycle methods. ([@gaearon](https://github.com/gaearon) in [#7208](https://github.com/facebook/react/pull/7208)).
|
||||
|
||||
### React CSSTransitionGroup Add-on
|
||||
- Fix issue resulting in spurious unknown property warnings. ([@batusai513](https://github.com/batusai513) in [#7165](https://github.com/facebook/react/pull/7165))
|
||||
|
||||
### React Native Renderer
|
||||
- Improve error handling in cross-platform touch event handling. ([@yungsters](https://github.com/yungsters) in [#7143](https://github.com/facebook/react/pull/7143))
|
||||
|
||||
|
||||
## 15.2.0 (July 1, 2016)
|
||||
|
||||
### React
|
||||
- Add error codes to production invariants, with links to the view the full error text. ([@keyanzhang](https://github.com/keyanzhang) in [#6948](https://github.com/facebook/react/pull/6948))
|
||||
- Include component stack information in PropType validation warnings. ([@troydemonbreun](https://github.com/troydemonbreun) in [#6398](https://github.com/facebook/react/pull/6398), [@spicyj](https://github.com/spicyj) in [#6771](https://github.com/facebook/react/pull/6771))
|
||||
- Include component stack information in key warnings. ([@keyanzhang](https://github.com/keyanzhang) in [#6799](https://github.com/facebook/react/pull/6799))
|
||||
- Stop validating props at mount time, only validate at element creation. ([@keyanzhang](https://github.com/keyanzhang) in [#6824](https://github.com/facebook/react/pull/6824))
|
||||
- New invariant providing actionable error in missing instance case. ([@yungsters](https://github.com/yungsters) in [#6990](https://github.com/facebook/react/pull/6990))
|
||||
- Add `React.PropTypes.symbol` to support ES2015 Symbols as props. ([@puradox](https://github.com/puradox) in [#6377](https://github.com/facebook/react/pull/6377))
|
||||
- Fix incorrect coercion of ref or key that are undefined in development ([@gaearon](https://github.com/gaearon) in [#6880](https://github.com/facebook/react/pull/6880))
|
||||
- Fix a false positive when passing other element’s props to cloneElement ([@ericmatthys](https://github.com/ericmatthys) in [#6268](https://github.com/facebook/react/pull/6268))
|
||||
- Warn if you attempt to define `childContextTypes` on a functional component ([@Aweary](https://github.com/Aweary) in [#6933](https://github.com/facebook/react/pull/6933))
|
||||
|
||||
### React DOM
|
||||
- Add warning for unknown properties on DOM elements. ([@jimfb](https://github.com/jimfb) in [#6800](https://github.com/facebook/react/pull/6800), [@gm758](https://github.com/gm758) in [#7152](https://github.com/facebook/react/pull/7152))
|
||||
- Properly remove attributes from custom elements. ([@grassator](https://github.com/grassator) in [#6748](https://github.com/facebook/react/pull/6748))
|
||||
- Fix invalid unicode escape in attribute name regular expression. ([@nbjahan](https://github.com/nbjahan) in [#6772](https://github.com/facebook/react/pull/6772))
|
||||
- Add `onLoad` handling to `<link>` element. ([@roderickhsiao](https://github.com/roderickhsiao) in [#6815](https://github.com/facebook/react/pull/6815))
|
||||
- Add `onError` handling to `<source>` element. ([@wadahiro](https://github.com/wadahiro) in [#6941](https://github.com/facebook/react/pull/6941))
|
||||
- Handle `value` and `defaultValue` more accurately in the DOM. ([@jimfb](https://github.com/jimfb) in [#6406](https://github.com/facebook/react/pull/6406))
|
||||
- Fix events issue in environments with mutated `Object.prototype`. ([@Weizenlol](https://github.com/Weizenlol) in [#6886](https://github.com/facebook/react/pull/6886))
|
||||
- Fix issue where `is="null"` ended up in the DOM in Firefox. ([@darobin](https://github.com/darobin) in [#6896](https://github.com/facebook/react/pull/6896))
|
||||
- Improved performance of text escaping by using [escape-html](https://github.com/component/escape-html). ([@aickin](https://github.com/aickin) in [#6862](https://github.com/facebook/react/pull/6862))
|
||||
- Fix issue with `dangerouslySetInnerHTML` and SVG in Internet Explorer. ([@joshhunt](https://github.com/joshhunt) in [#6982](https://github.com/facebook/react/pull/6982))
|
||||
- Fix issue with `<textarea>` placeholders. ([@jimfb](https://github.com/jimfb) in [#7002](https://github.com/facebook/react/pull/7002))
|
||||
- Fix controlled vs uncontrolled detection of `<input type="radio"/>`. ([@jimfb](https://github.com/jimfb) in [#7003](https://github.com/facebook/react/pull/7003))
|
||||
- Improve performance of updating text content. ([@trueadm](https://github.com/trueadm) in [#7005](https://github.com/facebook/react/pull/7005))
|
||||
- Ensure controlled `<select>` components behave the same on initial render as they do on updates. ([@yiminghe](https://github.com/yiminghe) in [#5362](https://github.com/facebook/react/pull/5362))
|
||||
|
||||
### React Perf Add-on
|
||||
- Add `isRunning()` API. ([@nfcampos](https://github.com/nfcampos) in [#6763](https://github.com/facebook/react/pull/6763))
|
||||
- Improve accuracy of lifecycle hook timing. ([@gaearon](https://github.com/gaearon) in [#6858](https://github.com/facebook/react/pull/6858))
|
||||
- Fix internal errors when using ReactPerf with portal components. ([@gaearon](https://github.com/gaearon) in [#6860](https://github.com/facebook/react/pull/6860))
|
||||
- Fix performance regression. ([@spicyj](https://github.com/spicyj) in [#6770](https://github.com/facebook/react/pull/6770))
|
||||
- Add warning that ReactPerf is not enabled in production. ([@sashashakun](https://github.com/sashashakun) in [#6884](https://github.com/facebook/react/pull/6884))
|
||||
|
||||
### React CSSTransitionGroup Add-on
|
||||
- Fix timing issue with `null` node. ([@keyanzhang](https://github.com/keyanzhang) in [#6958](https://github.com/facebook/react/pull/6958))
|
||||
|
||||
### React Native Renderer
|
||||
- Dependencies on React Native modules use CommonJS requires instead of providesModule. ([@davidaurelio](https://github.com/davidaurelio) in [#6715](https://github.com/facebook/react/pull/6715))
|
||||
|
||||
|
||||
## 15.1.0 (May 20, 2016)
|
||||
|
||||
### React
|
||||
- Ensure we're using the latest `object-assign`, which has protection against a non-spec-compliant native `Object.assign`. ([@zpao](https://github.com/zpao) in [#6681](https://github.com/facebook/react/pull/6681))
|
||||
- Add a new warning to communicate that `props` objects passed to `createElement` must be plain objects. ([@richardscarrott](https://github.com/richardscarrott) in [#6134](https://github.com/facebook/react/pull/6134))
|
||||
- Fix a batching bug resulting in some lifecycle methods incorrectly being called multiple times. ([@spicyj](https://github.com/spicyj) in [#6650](https://github.com/facebook/react/pull/6650))
|
||||
|
||||
### React DOM
|
||||
- Fix regression in custom elements support. ([@jscissr](https://github.com/jscissr) in [#6570](https://github.com/facebook/react/pull/6570))
|
||||
- Stop incorrectly warning about using `onScroll` event handler with server rendering. ([@Aweary](https://github.com/Aweary) in [#6678](https://github.com/facebook/react/pull/6678))
|
||||
- Fix grammar in the controlled input warning. ([@jakeboone02](https://github.com/jakeboone02) in [#6657](https://github.com/facebook/react/pull/6657))
|
||||
- Fix issue preventing `<object>` nodes from being able to read `<param>` nodes in IE. ([@syranide](https://github.com/syranide) in [#6691](https://github.com/facebook/react/pull/6691))
|
||||
- Fix issue resulting in crash when using experimental error boundaries with server rendering. ([@jimfb](https://github.com/jimfb) in [#6694](https://github.com/facebook/react/pull/6694))
|
||||
- Add additional information to the controlled input warning. ([@borisyankov](https://github.com/borisyankov) in [#6341](https://github.com/facebook/react/pull/6341))
|
||||
|
||||
### React Perf Add-on
|
||||
- Completely rewritten to collect data more accurately and to be easier to maintain. ([@gaearon](https://github.com/gaearon) in [#6647](https://github.com/facebook/react/pull/6647), [#6046](https://github.com/facebook/react/pull/6046))
|
||||
|
||||
### React Native Renderer
|
||||
- Remove some special cases for platform specific branching. ([@sebmarkbage](https://github.com/sebmarkbage) in [#6660](https://github.com/facebook/react/pull/6660))
|
||||
- Remove use of `merge` utility. ([@sebmarkbage](https://github.com/sebmarkbage) in [#6634](https://github.com/facebook/react/pull/6634))
|
||||
- Renamed some modules to better indicate usage ([@javache](https://github.com/javache) in [#6643](https://github.com/facebook/react/pull/6643))
|
||||
|
||||
|
||||
## 15.0.2 (April 29, 2016)
|
||||
|
||||
### React
|
||||
@@ -106,7 +307,7 @@ Each of these changes will continue to work as before with a new warning until t
|
||||
|
||||
### Other improvements
|
||||
|
||||
- React now uses `loose-envify` instead of `envify` so it installs less transitive dependencies. ([@qerub](https://github.com/qerub) in [#6303](https://github.com/facebook/react/pull/6303))
|
||||
- React now uses `loose-envify` instead of `envify` so it installs fewer transitive dependencies. ([@qerub](https://github.com/qerub) in [#6303](https://github.com/facebook/react/pull/6303))
|
||||
- Shallow renderer now exposes `getMountedInstance()`. ([@glenjamin](https://github.com/glenjamin) in [#4918](https://github.com/facebook/react/pull/4918))
|
||||
- Shallow renderer now returns the rendered output from `render()`. ([@simonewebdesign](https://github.com/simonewebdesign) in [#5411](https://github.com/facebook/react/pull/5411))
|
||||
- React no longer depends on ES5 *shams* for `Object.create` and `Object.freeze` in older environments. It still, however, requires ES5 *shims* in those environments. ([@dgreensp](https://github.com/dgreensp) in [#4959](https://github.com/facebook/react/pull/4959))
|
||||
@@ -319,7 +520,7 @@ Each of these changes will continue to work as before with a new warning until t
|
||||
|
||||
#### Bug Fixes
|
||||
|
||||
* Immutabilty Helpers: Ensure it supports `hasOwnProperty` as an object key
|
||||
* Immutability Helpers: Ensure it supports `hasOwnProperty` as an object key
|
||||
|
||||
### React Tools
|
||||
|
||||
@@ -850,14 +1051,14 @@ Each of these changes will continue to work as before with a new warning until t
|
||||
|
||||
* Upgrade Commoner so `require` statements are no longer relativized when passing through the transformer. This was a feature needed when building React, but doesn't translate well for other consumers of `bin/jsx`.
|
||||
* Upgraded our dependencies on Commoner and Recast so they use a different directory for their cache.
|
||||
* Freeze our esprima dependency.
|
||||
* Freeze our Esprima dependency.
|
||||
|
||||
|
||||
## 0.3.2 (May 31, 2013)
|
||||
|
||||
### JSX
|
||||
|
||||
* Improved compatability with other coding styles (specifically, multiple assignments with a single `var`).
|
||||
* Improved compatibility with other coding styles (specifically, multiple assignments with a single `var`).
|
||||
|
||||
### react-tools
|
||||
|
||||
|
||||
@@ -1,100 +1,5 @@
|
||||
# Contributing to React
|
||||
|
||||
React is one of Facebook's first open source projects that is both under very active development and is also being used to ship code to everybody on [facebook.com](https://www.facebook.com). We're still working out the kinks to make contributing to this project as easy and transparent as possible, but we're not quite there yet. Hopefully this document makes the process for contributing clear and answers some questions that you may have.
|
||||
Want to contribute to React? There are a few things you need to know.
|
||||
|
||||
## [Code of Conduct](https://code.facebook.com/codeofconduct)
|
||||
|
||||
Facebook has adopted a Code of Conduct that we expect project participants to adhere to. Please read [the full text](https://code.facebook.com/codeofconduct) so that you can understand what actions will and will not be tolerated.
|
||||
|
||||
## Our Development Process
|
||||
|
||||
Some of the core team will be working directly on GitHub. These changes will be public from the beginning. Other changesets will come via a bridge with Facebook's internal source control. This is a necessity as it allows engineers at Facebook outside of the core team to move fast and contribute from an environment they are comfortable in.
|
||||
|
||||
### `master` is unsafe
|
||||
|
||||
We will do our best to keep `master` in good shape, with tests passing at all times. But in order to move fast, we will make API changes that your application might not be compatible with. We will do our best to communicate these changes and always version appropriately so you can lock into a specific version if need be.
|
||||
|
||||
### Test Suite
|
||||
|
||||
Use `grunt test` to run the full test suite with PhantomJS.
|
||||
|
||||
This command is just a facade to [Jest](https://facebook.github.io/jest/). You may optionally run `npm install -g jest-cli` and use Jest commands directly to have more control over how tests are executed.
|
||||
|
||||
For example, `jest --watch` lets you automatically run the test suite on every file change.
|
||||
|
||||
You can also run a subset of tests by passing a prefix to `jest`. For instance, `jest ReactDOMSVG` will only run tests in the files that start with `ReactDOMSVG`, such as `ReactDOMSVG-test.js`.
|
||||
|
||||
When you know which tests you want to run, you can achieve a fast feedback loop by using these two features together. For example, `jest ReactDOMSVG --watch` will re-run only the matching tests on every change.
|
||||
|
||||
Just make sure to run the whole test suite before submitting a pull request!
|
||||
|
||||
### Pull Requests
|
||||
|
||||
**Working on your first Pull Request?** You can learn how from this *free* series [How to Contribute to an Open Source Project on GitHub](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github)
|
||||
|
||||
The core team will be monitoring for pull requests. When we get one, we'll run some Facebook-specific integration tests on it first. From here, we'll need to get another person to sign off on the changes and then merge the pull request. For API changes we may need to fix internal uses, which could cause some delay. We'll do our best to provide updates and feedback throughout the process.
|
||||
|
||||
*Before* submitting a pull request, please make sure the following is done…
|
||||
|
||||
1. Fork the repo and create your branch from `master`.
|
||||
2. If you've added code that should be tested, add tests!
|
||||
3. If you've changed APIs, update the documentation.
|
||||
4. Ensure the test suite passes (`grunt test`).
|
||||
5. Make sure your code lints (`grunt lint`) - we've done our best to make sure these rules match our internal linting guidelines.
|
||||
6. If you haven't already, complete the CLA.
|
||||
|
||||
### Contributor License Agreement (CLA)
|
||||
|
||||
In order to accept your pull request, we need you to submit a CLA. You only need to do this once, so if you've done this for another Facebook open source project, you're good to go. If you are submitting a pull request for the first time, just let us know that you have completed the CLA and we can cross-check with your GitHub username.
|
||||
|
||||
[Complete your CLA here.](https://code.facebook.com/cla)
|
||||
|
||||
## Bugs
|
||||
|
||||
### Where to Find Known Issues
|
||||
|
||||
We will be using GitHub Issues for our public bugs. We will keep a close eye on this and try to make it clear when we have an internal fix in progress. Before filing a new task, try to make sure your problem doesn't already exist.
|
||||
|
||||
### Reporting New Issues
|
||||
|
||||
The best way to get your bug fixed is to provide a reduced test case. jsFiddle, jsBin, and other sites provide a way to give live examples. Those are especially helpful though may not work for `JSX`-based code.
|
||||
|
||||
### Security Bugs
|
||||
|
||||
Facebook has a [bounty program](https://www.facebook.com/whitehat/) for the safe disclosure of security bugs. With that in mind, please do not file public issues; go through the process outlined on that page.
|
||||
|
||||
## How to Get in Touch
|
||||
|
||||
* IRC - [#reactjs on freenode](https://webchat.freenode.net/?channels=reactjs)
|
||||
* Discussion forum - [discuss.reactjs.org](https://discuss.reactjs.org/)
|
||||
|
||||
## Meeting Notes
|
||||
|
||||
React team meets once a week to discuss the development of React, future plans, and priorities.
|
||||
You can find the meeting notes in a [dedicated repository](https://github.com/reactjs/core-notes/).
|
||||
|
||||
## Style Guide
|
||||
|
||||
Our linter will catch most styling issues that may exist in your code.
|
||||
You can check the status of your code styling by simply running: `grunt lint`
|
||||
|
||||
However, there are still some styles that the linter cannot pick up. If you are unsure about something, looking at [Airbnb's Style Guide](https://github.com/airbnb/javascript) will guide you in the right direction.
|
||||
|
||||
### Code Conventions
|
||||
|
||||
* Use semicolons `;`
|
||||
* Commas last `,`
|
||||
* 2 spaces for indentation (no tabs)
|
||||
* Prefer `'` over `"`
|
||||
* `'use strict';`
|
||||
* 80 character line length
|
||||
* Write "attractive" code
|
||||
* Do not use the optional parameters of `setTimeout` and `setInterval`
|
||||
|
||||
### Documentation
|
||||
|
||||
* Do not wrap lines at 80 characters
|
||||
|
||||
## License
|
||||
|
||||
By contributing to React, you agree that your contributions will be licensed under its BSD license.
|
||||
We wrote a **[contribution guide](https://facebook.github.io/react/contributing/how-to-contribute.html)** to help you get started.
|
||||
|
||||
59
Gruntfile.js
59
Gruntfile.js
@@ -52,10 +52,18 @@ module.exports = function(grunt) {
|
||||
grunt.loadNpmTasks(npmTaskName);
|
||||
});
|
||||
|
||||
grunt.registerTask('eslint', require('./grunt/tasks/eslint'));
|
||||
grunt.registerTask('eslint', function() {
|
||||
// Use gulp here.
|
||||
spawnGulp(['eslint'], null, this.async());
|
||||
});
|
||||
|
||||
grunt.registerTask('lint', ['eslint']);
|
||||
|
||||
grunt.registerTask('flow', function() {
|
||||
// Use gulp here.
|
||||
spawnGulp(['flow'], null, this.async());
|
||||
});
|
||||
|
||||
grunt.registerTask('delete-build-modules', function() {
|
||||
// Use gulp here.
|
||||
spawnGulp(['react:clean'], null, this.async());
|
||||
@@ -82,7 +90,14 @@ module.exports = function(grunt) {
|
||||
grunt.registerTask('npm-react-addons:release', npmReactAddonsTasks.buildReleases);
|
||||
grunt.registerTask('npm-react-addons:pack', npmReactAddonsTasks.packReleases);
|
||||
|
||||
grunt.registerTask('version-check', require('./grunt/tasks/version-check'));
|
||||
var npmReactTestRendererTasks = require('./grunt/tasks/npm-react-test');
|
||||
grunt.registerTask('npm-react-test:release', npmReactTestRendererTasks.buildRelease);
|
||||
grunt.registerTask('npm-react-test:pack', npmReactTestRendererTasks.packRelease);
|
||||
|
||||
grunt.registerTask('version-check', function() {
|
||||
// Use gulp here.
|
||||
spawnGulp(['version-check'], null, this.async());
|
||||
});
|
||||
|
||||
grunt.registerTask('build:basic', [
|
||||
'build-modules',
|
||||
@@ -102,12 +117,41 @@ module.exports = function(grunt) {
|
||||
'build-modules',
|
||||
'browserify:addonsMin',
|
||||
]);
|
||||
grunt.registerTask('build:dom', [
|
||||
'build-modules',
|
||||
'version-check',
|
||||
'browserify:dom',
|
||||
]);
|
||||
grunt.registerTask('build:dom-min', [
|
||||
'build-modules',
|
||||
'version-check',
|
||||
'browserify:domMin',
|
||||
]);
|
||||
grunt.registerTask('build:dom-server', [
|
||||
'build-modules',
|
||||
'version-check',
|
||||
'browserify:domServer',
|
||||
]);
|
||||
grunt.registerTask('build:dom-server-min', [
|
||||
'build-modules',
|
||||
'version-check',
|
||||
'browserify:domServerMin',
|
||||
]);
|
||||
grunt.registerTask('build:dom-fiber', [
|
||||
'build-modules',
|
||||
'version-check',
|
||||
'browserify:domFiber',
|
||||
]);
|
||||
grunt.registerTask('build:dom-fiber-min', [
|
||||
'build-modules',
|
||||
'version-check',
|
||||
'browserify:domFiberMin',
|
||||
]);
|
||||
grunt.registerTask('build:npm-react', [
|
||||
'version-check',
|
||||
'build-modules',
|
||||
'npm-react:release',
|
||||
]);
|
||||
grunt.registerTask('build:react-dom', require('./grunt/tasks/react-dom'));
|
||||
|
||||
var jestTasks = require('./grunt/tasks/jest');
|
||||
grunt.registerTask('jest:normal', jestTasks.normal);
|
||||
@@ -126,7 +170,12 @@ module.exports = function(grunt) {
|
||||
'browserify:addons',
|
||||
'browserify:min',
|
||||
'browserify:addonsMin',
|
||||
'build:react-dom',
|
||||
'browserify:dom',
|
||||
'browserify:domMin',
|
||||
'browserify:domServer',
|
||||
'browserify:domServerMin',
|
||||
'browserify:domFiber',
|
||||
'browserify:domFiberMin',
|
||||
'npm-react:release',
|
||||
'npm-react:pack',
|
||||
'npm-react-dom:release',
|
||||
@@ -135,6 +184,8 @@ module.exports = function(grunt) {
|
||||
'npm-react-native:pack',
|
||||
'npm-react-addons:release',
|
||||
'npm-react-addons:pack',
|
||||
'npm-react-test:release',
|
||||
'npm-react-test:pack',
|
||||
'compare_size',
|
||||
]);
|
||||
|
||||
|
||||
68
README.md
68
README.md
@@ -2,11 +2,9 @@
|
||||
|
||||
React is a JavaScript library for building user interfaces.
|
||||
|
||||
* **Just the UI:** Lots of people use React as the V in MVC. Since React makes no assumptions about the rest of your technology stack, it's easy to try it out on a small feature in an existing project.
|
||||
* **Virtual DOM:** React abstracts away the DOM from you, giving a simpler programming model and better performance. React can also render on the server using Node, and it can power native apps using [React Native](https://facebook.github.io/react-native/).
|
||||
* **Data flow:** React implements one-way reactive data flow which reduces boilerplate and is easier to reason about than traditional data binding.
|
||||
|
||||
**NEW**! Check out our newest project [React Native](https://github.com/facebook/react-native), which uses React and JavaScript to create native mobile apps.
|
||||
* **Declarative:** React makes it painless to create interactive UIs. Design simple views for each state in your application, and React will efficiently update and render just the right components when your data changes. Declarative views make your code more predictable, simpler to understand, and easier to debug.
|
||||
* **Component-Based:** Build encapsulated components that manage their own state, then compose them to make complex UIs. Since component logic is written in JavaScript instead of templates, you can easily pass rich data through your app and keep state out of the DOM.
|
||||
* **Learn Once, Write Anywhere:** We don't make assumptions about the rest of your technology stack, so you can develop new features in React without rewriting existing code. React can also render on the server using Node and power mobile apps using [React Native](https://facebook.github.io/react-native/).
|
||||
|
||||
[Learn how to use React in your own project](https://facebook.github.io/react/docs/getting-started.html).
|
||||
|
||||
@@ -15,11 +13,11 @@ React is a JavaScript library for building user interfaces.
|
||||
We have several examples [on the website](https://facebook.github.io/react/). Here is the first one to get you started:
|
||||
|
||||
```js
|
||||
var HelloMessage = React.createClass({
|
||||
render: function() {
|
||||
class HelloMessage extends React.Component {
|
||||
render() {
|
||||
return <div>Hello {this.props.name}</div>;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ReactDOM.render(
|
||||
<HelloMessage name="John" />,
|
||||
@@ -33,16 +31,16 @@ You'll notice that we used an HTML-like syntax; [we call it JSX](https://faceboo
|
||||
|
||||
## Installation
|
||||
|
||||
The fastest way to get started is to serve JavaScript from the CDN (also available on [cdnjs](https://cdnjs.com/libraries/react) and [jsdelivr](https://www.jsdelivr.com/projects/react)):
|
||||
The fastest way to get started is to serve JavaScript from a CDN. We're using [unpkg](https://unpkg.com/) below but React is also available on [cdnjs](https://cdnjs.com/libraries/react) and [jsdelivr](https://www.jsdelivr.com/projects/react):
|
||||
|
||||
```html
|
||||
<!-- The core React library -->
|
||||
<script src="https://fb.me/react-15.0.2.js"></script>
|
||||
<script src="https://unpkg.com/react@15.4.0/dist/react.js"></script>
|
||||
<!-- The ReactDOM Library -->
|
||||
<script src="https://fb.me/react-dom-15.0.2.js"></script>
|
||||
<script src="https://unpkg.com/react-dom@15.4.0/dist/react-dom.js"></script>
|
||||
```
|
||||
|
||||
We've also built a [starter kit](https://facebook.github.io/react/downloads/react-15.0.2.zip) which might be useful if this is your first time using React. It includes a webpage with an example of using React with live code.
|
||||
We've also built a [starter kit](https://facebook.github.io/react/downloads/react-15.4.0.zip) which might be useful if this is your first time using React. It includes a webpage with an example of using React with live code.
|
||||
|
||||
If you'd like to use [bower](http://bower.io), it's as easy as:
|
||||
|
||||
@@ -56,49 +54,17 @@ And it's just as easy with [npm](http://npmjs.com):
|
||||
npm i --save react
|
||||
```
|
||||
|
||||
## Contribute
|
||||
## Contributing
|
||||
|
||||
The main purpose of this repository is to continue to evolve React core, making it faster and easier to use. If you're interested in helping with that, then keep reading. If you're not interested in helping right now that's ok too. :) Any feedback you have about using React would be greatly appreciated.
|
||||
The main purpose of this repository is to continue to evolve React core, making it faster and easier to use. If you're interested in helping with that, check out our [contribution guide](https://facebook.github.io/react/contributing/how-to-contribute.html).
|
||||
|
||||
### Building Your Copy of React
|
||||
### [Code of Conduct](https://code.facebook.com/codeofconduct)
|
||||
|
||||
The process to build `react.js` is built entirely on top of node.js, using many libraries you may already be familiar with.
|
||||
|
||||
#### Prerequisites
|
||||
|
||||
* You have `node` installed at v4.0.0+ and `npm` at v2.0.0+.
|
||||
* You are familiar with `npm` and know whether or not you need to use `sudo` when installing packages globally.
|
||||
* You are familiar with `git`.
|
||||
|
||||
#### Build
|
||||
|
||||
Once you have the repository cloned, building a copy of `react.js` is really easy.
|
||||
|
||||
```sh
|
||||
# grunt-cli is needed by grunt; you might have this installed already
|
||||
npm install -g grunt-cli
|
||||
npm install
|
||||
grunt build
|
||||
```
|
||||
|
||||
At this point, you should now have a `build/` directory populated with everything you need to use React. The examples should all work.
|
||||
|
||||
### Grunt
|
||||
|
||||
We use grunt to automate many tasks. Run `grunt -h` to see a mostly complete listing. The important ones to know:
|
||||
|
||||
```sh
|
||||
# Build and run tests with PhantomJS
|
||||
grunt test
|
||||
# Lint the code with ESLint
|
||||
grunt lint
|
||||
# Wipe out build directory
|
||||
grunt clean
|
||||
```
|
||||
Facebook has adopted a Code of Conduct that we expect project participants to adhere to. Please read [the full text](https://code.facebook.com/codeofconduct) so that you can understand what actions will and will not be tolerated.
|
||||
|
||||
### Good First Bug
|
||||
To help you get your feet wet and get you familiar with our contribution process, we have a list of [good first bugs](https://github.com/facebook/react/labels/good%20first%20bug) that contain bugs which are fairly easy to fix. This is a great place to get started.
|
||||
|
||||
To help you get your feet wet and get you familiar with our contribution process, we have a list of [good first bugs](https://github.com/facebook/react/labels/good%20first%20bug) that contain bugs which are fairly easy to fix. This is a great place to get started.
|
||||
|
||||
### License
|
||||
|
||||
@@ -108,9 +74,5 @@ React documentation is [Creative Commons licensed](./LICENSE-docs).
|
||||
|
||||
Examples provided in this repository and in the documentation are [separately licensed](./LICENSE-examples).
|
||||
|
||||
### More…
|
||||
|
||||
There's only so much we can cram in here. To read more about the community and guidelines for submitting pull requests, please read the [Contributing document](CONTRIBUTING.md).
|
||||
|
||||
## Troubleshooting
|
||||
See the [Troubleshooting Guide](https://github.com/facebook/react/wiki/Troubleshooting)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
---
|
||||
layout: single
|
||||
title: Page Not Found
|
||||
permalink: 404.html
|
||||
---
|
||||
|
||||
We couldn't find what you were looking for.
|
||||
|
||||
16
docs/Gemfile
16
docs/Gemfile
@@ -3,11 +3,12 @@ source 'https://rubygems.org'
|
||||
gem 'rake'
|
||||
|
||||
# jekyll, which builds it all
|
||||
# 2.0 includes sass processing
|
||||
gem 'jekyll', '~>2.0'
|
||||
# 3.0 includes sass processing
|
||||
gem 'jekyll', '~>3.1'
|
||||
|
||||
# Auto redirect pages
|
||||
# Jekyll extensions
|
||||
gem 'jekyll-redirect-from'
|
||||
gem 'jekyll-paginate'
|
||||
|
||||
# JSON
|
||||
gem 'json'
|
||||
@@ -17,3 +18,12 @@ gem 'rb-fsevent'
|
||||
|
||||
# For markdown header cleanup
|
||||
gem 'sanitize', '~>2.0'
|
||||
|
||||
# Markdown
|
||||
gem 'redcarpet'
|
||||
|
||||
# Syntax highlighting
|
||||
gem 'pygments.rb'
|
||||
|
||||
# Avoid having to poll for changes on Windows
|
||||
gem 'wdm', '>= 0.1.0' if Gem.win_platform?
|
||||
@@ -1,85 +1,70 @@
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
blankslate (2.1.2.4)
|
||||
celluloid (0.15.2)
|
||||
timers (~> 1.1.0)
|
||||
classifier (1.3.4)
|
||||
fast-stemmer (>= 1.0.0)
|
||||
coffee-script (2.3.0)
|
||||
coffee-script-source
|
||||
execjs
|
||||
coffee-script-source (1.7.1)
|
||||
colorator (0.1)
|
||||
execjs (2.2.1)
|
||||
fast-stemmer (1.0.2)
|
||||
ffi (1.9.3)
|
||||
jekyll (2.2.0)
|
||||
classifier (~> 1.3)
|
||||
ffi (1.9.14)
|
||||
ffi (1.9.14-x64-mingw32)
|
||||
jekyll (3.1.6)
|
||||
colorator (~> 0.1)
|
||||
jekyll-coffeescript (~> 1.0)
|
||||
jekyll-gist (~> 1.0)
|
||||
jekyll-paginate (~> 1.0)
|
||||
jekyll-sass-converter (~> 1.0)
|
||||
jekyll-watch (~> 1.0)
|
||||
jekyll-watch (~> 1.1)
|
||||
kramdown (~> 1.3)
|
||||
liquid (~> 2.6.1)
|
||||
liquid (~> 3.0)
|
||||
mercenary (~> 0.3.3)
|
||||
pygments.rb (~> 0.6.0)
|
||||
redcarpet (~> 3.1)
|
||||
rouge (~> 1.7)
|
||||
safe_yaml (~> 1.0)
|
||||
toml (~> 0.1.0)
|
||||
jekyll-coffeescript (1.0.0)
|
||||
coffee-script (~> 2.2)
|
||||
jekyll-gist (1.1.0)
|
||||
jekyll-paginate (1.0.0)
|
||||
jekyll-redirect-from (0.5.0)
|
||||
jekyll (~> 2.0)
|
||||
jekyll-sass-converter (1.2.0)
|
||||
sass (~> 3.2)
|
||||
jekyll-watch (1.1.0)
|
||||
listen (~> 2.7)
|
||||
json (1.8.1)
|
||||
kramdown (1.4.1)
|
||||
liquid (2.6.1)
|
||||
listen (2.7.9)
|
||||
celluloid (>= 0.15.2)
|
||||
rb-fsevent (>= 0.9.3)
|
||||
rb-inotify (>= 0.9)
|
||||
mercenary (0.3.4)
|
||||
mini_portile (0.6.0)
|
||||
nokogiri (1.6.3.1)
|
||||
mini_portile (= 0.6.0)
|
||||
parslet (1.5.0)
|
||||
blankslate (~> 2.0)
|
||||
posix-spawn (0.3.9)
|
||||
pygments.rb (0.6.0)
|
||||
jekyll-paginate (1.1.0)
|
||||
jekyll-redirect-from (0.11.0)
|
||||
jekyll (>= 2.0)
|
||||
jekyll-sass-converter (1.4.0)
|
||||
sass (~> 3.4)
|
||||
jekyll-watch (1.4.0)
|
||||
listen (~> 3.0, < 3.1)
|
||||
json (2.0.1)
|
||||
kramdown (1.11.1)
|
||||
liquid (3.0.6)
|
||||
listen (3.0.8)
|
||||
rb-fsevent (~> 0.9, >= 0.9.4)
|
||||
rb-inotify (~> 0.9, >= 0.9.7)
|
||||
mercenary (0.3.6)
|
||||
mini_portile2 (2.1.0)
|
||||
nokogiri (1.6.8)
|
||||
mini_portile2 (~> 2.1.0)
|
||||
pkg-config (~> 1.1.7)
|
||||
nokogiri (1.6.8-x64-mingw32)
|
||||
mini_portile2 (~> 2.1.0)
|
||||
pkg-config (~> 1.1.7)
|
||||
pkg-config (1.1.7)
|
||||
posix-spawn (0.3.11)
|
||||
pygments.rb (0.6.3)
|
||||
posix-spawn (~> 0.3.6)
|
||||
yajl-ruby (~> 1.1.0)
|
||||
rake (10.3.2)
|
||||
rb-fsevent (0.9.4)
|
||||
rb-inotify (0.9.5)
|
||||
yajl-ruby (~> 1.2.0)
|
||||
rake (11.2.2)
|
||||
rb-fsevent (0.9.7)
|
||||
rb-inotify (0.9.7)
|
||||
ffi (>= 0.5.0)
|
||||
redcarpet (3.1.2)
|
||||
redcarpet (3.3.4)
|
||||
rouge (1.11.1)
|
||||
safe_yaml (1.0.4)
|
||||
sanitize (2.0.6)
|
||||
sanitize (2.1.0)
|
||||
nokogiri (>= 1.4.4)
|
||||
sass (3.3.14)
|
||||
timers (1.1.0)
|
||||
toml (0.1.1)
|
||||
parslet (~> 1.5.0)
|
||||
yajl-ruby (1.1.0)
|
||||
sass (3.4.22)
|
||||
yajl-ruby (1.2.1)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
x64-mingw32
|
||||
|
||||
DEPENDENCIES
|
||||
jekyll (~> 2.0)
|
||||
jekyll (~> 3.1)
|
||||
jekyll-paginate
|
||||
jekyll-redirect-from
|
||||
json
|
||||
pygments.rb
|
||||
rake
|
||||
rb-fsevent
|
||||
redcarpet
|
||||
sanitize (~> 2.0)
|
||||
|
||||
BUNDLED WITH
|
||||
1.10.1
|
||||
1.11.2
|
||||
|
||||
@@ -34,7 +34,7 @@ Use Jekyll to serve the website locally (by default, at `http://localhost:4000`)
|
||||
$ cd react/docs
|
||||
$ bundle exec rake
|
||||
$ bundle exec jekyll serve -w
|
||||
$ open http://localhost:4000/react/
|
||||
$ open http://localhost:4000/react/index.html
|
||||
```
|
||||
|
||||
We use [SASS](http://sass-lang.com/) (with [Bourbon](http://bourbon.io/)) for our CSS, and we use JSX to transform some of our JS.
|
||||
|
||||
@@ -6,8 +6,8 @@ require('open-uri')
|
||||
desc "download babel-browser"
|
||||
task :fetch_remotes do
|
||||
IO.copy_stream(
|
||||
open('https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.34/browser.min.js'),
|
||||
'js/babel-browser.min.js'
|
||||
open('https://unpkg.com/babel-standalone@6.15.0/babel.min.js'),
|
||||
'js/babel.min.js'
|
||||
)
|
||||
end
|
||||
|
||||
@@ -61,8 +61,15 @@ task :update_acknowledgements do
|
||||
File.open('_data/acknowledgements.yml', 'w+') { |f| f.write(cols.to_yaml) }
|
||||
end
|
||||
|
||||
desc "copy error codes to docs"
|
||||
task :copy_error_codes do
|
||||
codes_json = File.read('../scripts/error-codes/codes.json')
|
||||
codes_js = "var errorMap = #{codes_json.chomp};\n"
|
||||
File.write('js/errorMap.js', codes_js)
|
||||
end
|
||||
|
||||
desc "build into ../../react-gh-pages"
|
||||
task :release => [:update_version, :js, :fetch_remotes] do
|
||||
task :release => [:update_version, :js, :fetch_remotes, :copy_error_codes] do
|
||||
system "jekyll build -d ../../react-gh-pages"
|
||||
end
|
||||
|
||||
|
||||
@@ -5,21 +5,44 @@ url: https://facebook.github.io
|
||||
baseurl: "/react"
|
||||
permalink: "/blog/:year/:month/:day/:title.html"
|
||||
paginate_path: "/blog/page:num/"
|
||||
relative_permalinks: true
|
||||
paginate: 5
|
||||
timezone: America/Los_Angeles
|
||||
highlighter: pygments
|
||||
defaults:
|
||||
- scope:
|
||||
path: ''
|
||||
type: post
|
||||
type: posts
|
||||
values:
|
||||
layout: post
|
||||
sectionid: blog
|
||||
- scope:
|
||||
path: blog
|
||||
type: pages
|
||||
values:
|
||||
sectionid: blog
|
||||
- scope:
|
||||
path: tutorial
|
||||
type: pages
|
||||
values:
|
||||
layout: tutorial
|
||||
sectionid: tutorial
|
||||
- scope:
|
||||
path: docs
|
||||
type: page
|
||||
type: pages
|
||||
values:
|
||||
layout: docs
|
||||
sectionid: docs
|
||||
- scope:
|
||||
path: contributing
|
||||
type: pages
|
||||
values:
|
||||
sectionid: docs
|
||||
- scope:
|
||||
path: community
|
||||
type: pages
|
||||
values:
|
||||
layout: community
|
||||
sectionid: community
|
||||
exclude:
|
||||
- Gemfile
|
||||
- Gemfile.lock
|
||||
@@ -36,13 +59,14 @@ sass:
|
||||
sass_dir: _css
|
||||
gems:
|
||||
- jekyll-redirect-from
|
||||
react_version: 15.0.1
|
||||
- jekyll-paginate
|
||||
react_version: 15.3.2
|
||||
react_hashes:
|
||||
dev: PcrCc8vAh3jounTGQGibvUE4liSu8s91ycPotf/cfEHdSnq9qaW2c9tFr3oyDzW4
|
||||
prod: S9sTQnq5vvBUhj91S9s9dhE4fiZWgytnfFyIW7hu3Vk5leHzq03A9dULSd0IqW9N
|
||||
addons_dev: TUMXymomVw+mFbSSojSWXtBVJiWEfUKUYzgZsgvUsdD9fL/y0PPc55825Ui2ZPY6
|
||||
addons_prod: rBjtXXl33XbsJR2IbEYJRYH5VnUUMi4o6Zr7ai4UPxcrY0Cw3QpnaU9iIJ2GcyLy
|
||||
dom_dev: ukADzi8g85qHW1NDinecbLJu/a+yfhgXK6G2Kl7vCckNICr4Pt1hN7mpfPzsgbD2
|
||||
dom_prod: n1Sg+vSen3Mb4Ggzsi2jq4MHCXmlKD0spQXmiYaPSt/8WR7PzpwLTmH8OI+yAluA
|
||||
dom_server_dev: eQOoGEpIR1fqOenVhLKRmPctitl54hZLIFg9uMYElEMx0r175Qedt3utJwCjsSrr
|
||||
dom_server_prod: 41Tbqk6dOco41BSH7Fb2xAWh8PJTYntH+OR/m80NT+L5IF6XWcq/kvNZGzhBws60
|
||||
dev: bQIyvl+8Ufi5KiKZPG9VItNWmhcAXA1pa5nHIEoBGob+rdbjJnpNV3s288Mz2yZu
|
||||
prod: drG4TSBgFQ0Hb/A3ynRyFDT22irpJDL+duuxvYD5mkC9adCYDqEwnX13371waqiH
|
||||
addons_dev: gCLxBq3yes/qREmjcw3Tdk5dUh3iB54huWqgxq1lAJZTYzLahJqEik5ZiVnq9Zt4
|
||||
addons_prod: pmUKSclxJREtkrfcUJvBYTEoJCvO6Vj5ob8IgPSiIX0G3c4w2dKBJMoGEhlv9Gev
|
||||
dom_dev: ZzFfcTbsRst34N23lWs6TtlfonXwDgpeALh+ObwYXav5BSo0j7KsaAtcdn+xrnS1
|
||||
dom_prod: MTxlP+/p3lyvc2+LZc2B5xy5reGwrA80whnflxNc6zPgLUmMvbwUoKy7qorBH+P4
|
||||
dom_server_dev: jHjmbawtj2AhVuJlmE/O1HXAIbQMzHvoXRZEVdhTSrfJXACRVpZm/BpuAi4K89xn
|
||||
dom_server_prod: LCYUMPll/9t/UsNa/Q1zfti2awxxiiczBUZcQBdeGACH0sU6BEAllZuGxo5b6/kf
|
||||
|
||||
@@ -37,7 +37,7 @@ html * {
|
||||
border-bottom: 1px dotted #cb4b16;
|
||||
}
|
||||
.cm-s-solarized-light span.cm-keyword {
|
||||
color: #268bd2;
|
||||
color: #859900;
|
||||
}
|
||||
.cm-s-solarized-light span.cm-atom {
|
||||
color: #2aa198;
|
||||
@@ -61,7 +61,7 @@ html * {
|
||||
color: #93a1a1;
|
||||
}
|
||||
.cm-s-solarized-light span.cm-property {
|
||||
color: #637c84;
|
||||
color: #657b83;
|
||||
}
|
||||
.cm-s-solarized-light span.cm-operator {
|
||||
color: #657b83;
|
||||
@@ -74,14 +74,13 @@ html * {
|
||||
border-bottom: 1px dotted #cb4b16;
|
||||
}
|
||||
.cm-s-solarized-light span.cm-bracket {
|
||||
color: #cb4b16;
|
||||
color: #268bd2;
|
||||
}
|
||||
.cm-s-solarized-light span.cm-tag {
|
||||
color: #657b83;
|
||||
color: #268bd2;
|
||||
}
|
||||
.cm-s-solarized-light span.cm-attribute {
|
||||
color: #586e75;
|
||||
font-weight: bold;
|
||||
}
|
||||
.cm-s-solarized-light span.cm-meta {
|
||||
color: #268bd2;
|
||||
@@ -166,7 +165,6 @@ html * {
|
||||
}
|
||||
.cm-s-solarized-dark span.cm-attribute {
|
||||
color: #93a1a1;
|
||||
font-weight: bold;
|
||||
}
|
||||
.cm-s-solarized-dark span.cm-meta {
|
||||
color: #268bd2;
|
||||
|
||||
@@ -112,8 +112,6 @@ li {
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
a {
|
||||
color: $linkColor;
|
||||
text-decoration: none;
|
||||
@@ -131,3 +129,7 @@ a {
|
||||
.center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
input {
|
||||
font-family: inherit;
|
||||
}
|
||||
|
||||
@@ -31,6 +31,9 @@ jingc:
|
||||
josephsavona:
|
||||
name: Joseph Savona
|
||||
url: https://twitter.com/en_JS
|
||||
keyanzhang:
|
||||
name: Keyan Zhang
|
||||
url: https://twitter.com/keyanzhang
|
||||
kmeht:
|
||||
name: Kunal Mehta
|
||||
url: https://github.com/kmeht
|
||||
|
||||
14
docs/_data/nav_community.yml
Normal file
14
docs/_data/nav_community.yml
Normal file
@@ -0,0 +1,14 @@
|
||||
- title: Community Resources
|
||||
items:
|
||||
- id: support
|
||||
title: Where To Get Support
|
||||
- id: conferences
|
||||
title: Conferences
|
||||
- id: videos
|
||||
title: Videos
|
||||
- id: complementary-tools
|
||||
title: Complementary Tools
|
||||
href: https://github.com/facebook/react/wiki/Complementary-Tools
|
||||
- id: examples
|
||||
title: Examples
|
||||
href: https://github.com/facebook/react/wiki/Examples
|
||||
10
docs/_data/nav_contributing.yml
Normal file
10
docs/_data/nav_contributing.yml
Normal file
@@ -0,0 +1,10 @@
|
||||
- title: Contributing
|
||||
items:
|
||||
- id: how-to-contribute
|
||||
title: How to Contribute
|
||||
- id: codebase-overview
|
||||
title: Codebase Overview
|
||||
- id: implementation-notes
|
||||
title: Implementation Notes
|
||||
- id: design-principles
|
||||
title: Design Principles
|
||||
@@ -1,112 +1,84 @@
|
||||
- title: Quick Start
|
||||
items:
|
||||
- id: getting-started
|
||||
title: Getting Started
|
||||
- id: tutorial
|
||||
title: Tutorial
|
||||
- id: thinking-in-react
|
||||
title: Thinking in React
|
||||
- title: Community Resources
|
||||
- id: installation
|
||||
title: Installation
|
||||
- id: hello-world
|
||||
title: Hello World
|
||||
- id: introducing-jsx
|
||||
title: Introducing JSX
|
||||
- id: rendering-elements
|
||||
title: Rendering Elements
|
||||
- id: components-and-props
|
||||
title: Components and Props
|
||||
- id: state-and-lifecycle
|
||||
title: State and Lifecycle
|
||||
- id: handling-events
|
||||
title: Handling Events
|
||||
- id: conditional-rendering
|
||||
title: Conditional Rendering
|
||||
- id: lists-and-keys
|
||||
title: Lists and Keys
|
||||
- id: forms
|
||||
title: Forms
|
||||
- id: lifting-state-up
|
||||
title: Lifting State Up
|
||||
- id: composition-vs-inheritance
|
||||
title: Composition vs Inheritance
|
||||
- id: thinking-in-react
|
||||
title: Thinking In React
|
||||
- title: Advanced Guides
|
||||
items:
|
||||
- id: conferences
|
||||
title: Conferences
|
||||
- id: videos
|
||||
title: Videos
|
||||
- id: complementary-tools
|
||||
title: Complementary Tools
|
||||
href: https://github.com/facebook/react/wiki/Complementary-Tools
|
||||
- id: examples
|
||||
title: Examples
|
||||
href: https://github.com/facebook/react/wiki/Examples
|
||||
- title: Guides
|
||||
items:
|
||||
- id: why-react
|
||||
title: Why React?
|
||||
- id: displaying-data
|
||||
title: Displaying Data
|
||||
subitems:
|
||||
- id: jsx-in-depth
|
||||
title: JSX in Depth
|
||||
- id: jsx-spread
|
||||
title: JSX Spread Attributes
|
||||
- id: jsx-gotchas
|
||||
title: JSX Gotchas
|
||||
- id: interactivity-and-dynamic-uis
|
||||
title: Interactivity and Dynamic UIs
|
||||
- id: multiple-components
|
||||
title: Multiple Components
|
||||
- id: reusable-components
|
||||
title: Reusable Components
|
||||
- id: transferring-props
|
||||
title: Transferring Props
|
||||
- id: forms
|
||||
title: Forms
|
||||
- id: working-with-the-browser
|
||||
title: Working With the Browser
|
||||
subitems:
|
||||
- id: more-about-refs
|
||||
title: Refs to Components
|
||||
- id: tooling-integration
|
||||
title: Tooling Integration
|
||||
subitems:
|
||||
- id: language-tooling
|
||||
title: Language Tooling
|
||||
- id: package-management
|
||||
title: Package Management
|
||||
- id: environments
|
||||
title: Server-side Environments
|
||||
- id: addons
|
||||
title: Add-Ons
|
||||
subitems:
|
||||
- id: animation
|
||||
title: Animation
|
||||
- id: two-way-binding-helpers
|
||||
title: Two-Way Binding Helpers
|
||||
- id: test-utils
|
||||
title: Test Utilities
|
||||
- id: clone-with-props
|
||||
title: Cloning Elements
|
||||
- id: create-fragment
|
||||
title: Keyed Fragments
|
||||
- id: update
|
||||
title: Immutability Helpers
|
||||
- id: pure-render-mixin
|
||||
title: PureRenderMixin
|
||||
- id: perf
|
||||
title: Performance Tools
|
||||
- id: shallow-compare
|
||||
title: Shallow Compare
|
||||
- id: advanced-performance
|
||||
title: Advanced Performance
|
||||
- id: context
|
||||
title: Context
|
||||
title: JSX In Depth
|
||||
- id: typechecking-with-proptypes
|
||||
title: Typechecking With PropTypes
|
||||
- id: refs-and-the-dom
|
||||
title: Refs and the DOM
|
||||
- id: uncontrolled-components
|
||||
title: Uncontrolled Components
|
||||
- id: optimizing-performance
|
||||
title: Optimizing Performance
|
||||
- id: react-without-es6
|
||||
title: React Without ES6
|
||||
- id: react-without-jsx
|
||||
title: React Without JSX
|
||||
- id: reconciliation
|
||||
title: Reconciliation
|
||||
- id: context
|
||||
title: Context
|
||||
- id: web-components
|
||||
title: Web Components
|
||||
- title: Reference
|
||||
items:
|
||||
- id: top-level-api
|
||||
title: Top-Level API
|
||||
- id: component-api
|
||||
title: Component API
|
||||
- id: component-specs
|
||||
title: Component Specs and Lifecycle
|
||||
- id: tags-and-attributes
|
||||
title: Supported Tags and Attributes
|
||||
- id: events
|
||||
title: Event System
|
||||
- id: dom-differences
|
||||
title: DOM Differences
|
||||
- id: special-non-dom-attributes
|
||||
title: Special Non-DOM Attributes
|
||||
- id: reconciliation
|
||||
title: Reconciliation
|
||||
- id: webcomponents
|
||||
title: Web Components
|
||||
- id: glossary
|
||||
title: React (Virtual) DOM Terminology
|
||||
- title: Flux
|
||||
items:
|
||||
- id: flux-overview
|
||||
title: Flux Overview
|
||||
href: https://facebook.github.io/flux/docs/overview.html
|
||||
- id: flux-todo-list
|
||||
title: Flux TodoMVC Tutorial
|
||||
href: https://facebook.github.io/flux/docs/todo-list.html
|
||||
- id: react-api
|
||||
title: React
|
||||
subitems:
|
||||
- id: react-component
|
||||
title: React.Component
|
||||
- id: react-dom
|
||||
title: ReactDOM
|
||||
- id: react-dom-server
|
||||
title: ReactDOMServer
|
||||
- id: dom-elements
|
||||
title: DOM Elements
|
||||
- id: events
|
||||
title: SyntheticEvent
|
||||
- id: addons
|
||||
title: Add-Ons
|
||||
subitems:
|
||||
- id: perf
|
||||
title: Performance Tools
|
||||
- id: test-utils
|
||||
title: Test Utilities
|
||||
- id: animation
|
||||
title: Animation
|
||||
- id: create-fragment
|
||||
title: Keyed Fragments
|
||||
- id: update
|
||||
title: Immutability Helpers
|
||||
- id: pure-render-mixin
|
||||
title: PureRenderMixin
|
||||
- id: shallow-compare
|
||||
title: Shallow Compare
|
||||
- id: two-way-binding-helpers
|
||||
title: Two-way Binding Helpers
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
- title: Tips
|
||||
items:
|
||||
- id: introduction
|
||||
title: Introduction
|
||||
- id: inline-styles
|
||||
title: Inline Styles
|
||||
- id: if-else-in-JSX
|
||||
title: If-Else in JSX
|
||||
- id: self-closing-tag
|
||||
title: Self-Closing Tag
|
||||
- id: maximum-number-of-jsx-root-nodes
|
||||
title: Maximum Number of JSX Root Nodes
|
||||
- id: style-props-value-px
|
||||
title: Shorthand for Specifying Pixel Values in style props
|
||||
- id: children-props-type
|
||||
title: Type of the Children props
|
||||
- id: controlled-input-null-value
|
||||
title: Value of null for Controlled Input
|
||||
- id: componentWillReceiveProps-not-triggered-after-mounting
|
||||
title: componentWillReceiveProps Not Triggered After Mounting
|
||||
- id: props-in-getInitialState-as-anti-pattern
|
||||
title: Props in getInitialState Is an Anti-Pattern
|
||||
- id: dom-event-listeners
|
||||
title: DOM Event Listeners in a Component
|
||||
- id: initial-ajax
|
||||
title: Load Initial Data via AJAX
|
||||
- id: false-in-jsx
|
||||
title: False in JSX
|
||||
- id: communicate-between-components
|
||||
title: Communicate Between Components
|
||||
- id: expose-component-functions
|
||||
title: Expose Component Functions
|
||||
- id: children-undefined
|
||||
title: this.props.children undefined
|
||||
- id: use-react-with-other-libraries
|
||||
title: Use React with Other Libraries
|
||||
- id: dangerously-set-inner-html
|
||||
title: Dangerously Set innerHTML
|
||||
71
docs/_data/nav_tutorial.yml
Normal file
71
docs/_data/nav_tutorial.yml
Normal file
@@ -0,0 +1,71 @@
|
||||
- title: Tutorial
|
||||
items:
|
||||
- id: tutorial
|
||||
title: Overview
|
||||
subitems:
|
||||
- id: what-were-building
|
||||
title: What We're Building
|
||||
href: /react/tutorial/tutorial.html#what-were-building
|
||||
forceInternal: true
|
||||
- id: what-is-react
|
||||
title: What is React?
|
||||
href: /react/tutorial/tutorial.html#what-is-react
|
||||
forceInternal: true
|
||||
- id: getting-started
|
||||
title: Getting Started
|
||||
href: /react/tutorial/tutorial.html#getting-started
|
||||
forceInternal: true
|
||||
- id: passing-data-through-props
|
||||
title: Passing Data Through Props
|
||||
href: /react/tutorial/tutorial.html#passing-data-through-props
|
||||
forceInternal: true
|
||||
- id: an-interactive-component
|
||||
title: An Interactive Component
|
||||
href: /react/tutorial/tutorial.html#an-interactive-component
|
||||
forceInternal: true
|
||||
- id: developer-tools
|
||||
title: Developer Tools
|
||||
href: /react/tutorial/tutorial.html#developer-tools
|
||||
forceInternal: true
|
||||
- id: lifting-state-up
|
||||
title: Lifting State Up
|
||||
href: /react/tutorial/tutorial.html#lifting-state-up
|
||||
forceInternal: true
|
||||
subitems:
|
||||
- id: why-immutability-is-important
|
||||
title: Why Immutability Is Important
|
||||
href: /react/tutorial/tutorial.html#why-immutability-is-important
|
||||
forceInternal: true
|
||||
- id: functional-components
|
||||
title: Functional Components
|
||||
href: /react/tutorial/tutorial.html#functional-components
|
||||
forceInternal: true
|
||||
- id: taking-turns
|
||||
title: Taking Turns
|
||||
href: /react/tutorial/tutorial.html#taking-turns
|
||||
forceInternal: true
|
||||
- id: declaring-a-winner
|
||||
title: Declaring a Winner
|
||||
href: /react/tutorial/tutorial.html#declaring-a-winner
|
||||
forceInternal: true
|
||||
- id: storing-a-history
|
||||
title: Storing A History
|
||||
href: /react/tutorial/tutorial.html#storing-a-history
|
||||
forceInternal: true
|
||||
subitems:
|
||||
- id: showing-the-moves
|
||||
title: Showing the Moves
|
||||
href: /react/tutorial/tutorial.html#showing-the-moves
|
||||
forceInternal: true
|
||||
- id: keys
|
||||
title: Keys
|
||||
href: /react/tutorial/tutorial.html#keys
|
||||
forceInternal: true
|
||||
- id: implementing-time-travel
|
||||
title: Implementing Time Travel
|
||||
href: /react/tutorial/tutorial.html#implementing-time-travel
|
||||
forceInternal: true
|
||||
- id: wrapping-up
|
||||
title: Wrapping Up
|
||||
href: /react/tutorial/tutorial.html#wrapping-up
|
||||
forceInternal: true
|
||||
41
docs/_includes/footer.html
Normal file
41
docs/_includes/footer.html
Normal file
@@ -0,0 +1,41 @@
|
||||
<footer class="nav-footer">
|
||||
<section class="sitemap">
|
||||
<a href="/react/" class="nav-home">
|
||||
</a>
|
||||
<div>
|
||||
<h5><a href="/react/docs/">Docs</a></h5>
|
||||
<a href="/react/docs/hello-world.html">Quick Start</a>
|
||||
<a href="/react/docs/thinking-in-react.html">Thinking in React</a>
|
||||
<a href="/react/tutorial/tutorial.html">Tutorial</a>
|
||||
<a href="/react/docs/jsx-in-depth.html">Advanced Guides</a>
|
||||
</div>
|
||||
<div>
|
||||
<h5><a href="/react/community/support.html">Community</a></h5>
|
||||
<a href="http://stackoverflow.com/questions/tagged/reactjs" target="_blank">Stack Overflow</a>
|
||||
<a href="https://discuss.reactjs.org/" target="_blank">Discussion Forum</a>
|
||||
<a href="https://discord.gg/0ZcbPKXt5bZjGY5n" target="_blank">Reactiflux Chat</a>
|
||||
<a href="https://www.facebook.com/react" target="_blank">Facebook</a>
|
||||
<a href="https://twitter.com/reactjs" target="_blank">Twitter</a>
|
||||
</div>
|
||||
<div>
|
||||
<h5><a href="/react/community/support.html">Resources</a></h5>
|
||||
<a href="/react/community/conferences.html">Conferences</a>
|
||||
<a href="/react/community/videos.html">Videos</a>
|
||||
<a href="https://github.com/facebook/react/wiki/Examples" target="_blank">Examples</a>
|
||||
<a href="https://github.com/facebook/react/wiki/Complementary-Tools" target="_blank">Complementary Tools</a>
|
||||
</div>
|
||||
<div>
|
||||
<h5>More</h5>
|
||||
<a href="/react/blog/">Blog</a>
|
||||
<a href="https://github.com/facebook/react" target="_blank">GitHub</a>
|
||||
<a href="http://facebook.github.io/react-native/" target="_blank">React Native</a>
|
||||
<a href="/react/acknowledgements.html">Acknowledgements</a>
|
||||
</div>
|
||||
</section>
|
||||
<a href="https://code.facebook.com/projects/" target="_blank" class="fbOpenSource">
|
||||
<img src="/react/img/oss_logo.png" alt="Facebook Open Source" width="170" height="45"/>
|
||||
</a>
|
||||
<section class="copyright">
|
||||
Copyright © {{ site.time | date: '%Y' }} Facebook Inc.
|
||||
</section>
|
||||
</footer>
|
||||
13
docs/_includes/hero.html
Normal file
13
docs/_includes/hero.html
Normal file
@@ -0,0 +1,13 @@
|
||||
<div class="hero">
|
||||
<div class="wrap">
|
||||
<div class="text"><strong>React</strong></div>
|
||||
<div class="minitext">
|
||||
A JavaScript library for building user interfaces
|
||||
</div>
|
||||
|
||||
<div class="buttons-unit">
|
||||
<a href="/react/docs/hello-world.html" class="button">Get Started</a>
|
||||
<a href="/react/tutorial/tutorial.html" class="button">Take the Tutorial</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
24
docs/_includes/nav_community.html
Normal file
24
docs/_includes/nav_community.html
Normal file
@@ -0,0 +1,24 @@
|
||||
<div class="nav-docs">
|
||||
<!-- Community Nav -->
|
||||
{% for section in site.data.nav_community %}
|
||||
<div class="nav-docs-section">
|
||||
<h3>{{ section.title }}</h3>
|
||||
<ul>
|
||||
{% for item in section.items %}
|
||||
<li>
|
||||
{{ item | community_sidebar_link }}
|
||||
{% if item.subitems %}
|
||||
<ul>
|
||||
{% for subitem in item.subitems %}
|
||||
<li>
|
||||
{{ subitem | community_sidebar_link }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
@@ -6,12 +6,12 @@
|
||||
<ul>
|
||||
{% for item in section.items %}
|
||||
<li>
|
||||
{{ item | sidebar_item_link}}
|
||||
{{ item | docs_sidebar_link}}
|
||||
{% if item.subitems %}
|
||||
<ul>
|
||||
{% for subitem in item.subitems %}
|
||||
<li>
|
||||
{{ subitem | sidebar_item_link}}
|
||||
{{ subitem | docs_sidebar_link }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
@@ -22,17 +22,18 @@
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
<!-- Tips Nav -->
|
||||
{% for section in site.data.nav_tips %}
|
||||
<!-- Contributing Nav -->
|
||||
{% for section in site.data.nav_contributing %}
|
||||
<div class="nav-docs-section">
|
||||
<h3>{{ section.title }}</h3>
|
||||
<ul>
|
||||
{% for item in section.items %}
|
||||
<li>
|
||||
<a href="/react/tips/{{ item.id }}.html"{% if page.id == item.id %} class="active"{% endif %}>{{ item.title }}</a>
|
||||
<a href="/react/contributing/{{ item.id }}.html"{% if page.id == item.id %} class="active"{% endif %}>{{ item.title }}</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
</div>
|
||||
|
||||
24
docs/_includes/nav_tutorial.html
Normal file
24
docs/_includes/nav_tutorial.html
Normal file
@@ -0,0 +1,24 @@
|
||||
<div class="nav-docs">
|
||||
<!-- Tutorial Nav -->
|
||||
{% for section in site.data.nav_tutorial %}
|
||||
<div class="nav-docs-section">
|
||||
<h3>{{ section.title }}</h3>
|
||||
<ul>
|
||||
{% for item in section.items %}
|
||||
<li>
|
||||
{{ item | tutorial_sidebar_link }}
|
||||
{% if item.subitems %}
|
||||
<ul>
|
||||
{% for subitem in item.subitems %}
|
||||
<li>
|
||||
{{ subitem | tutorial_sidebar_link }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
23
docs/_includes/navigation.html
Normal file
23
docs/_includes/navigation.html
Normal file
@@ -0,0 +1,23 @@
|
||||
<div class="nav-main">
|
||||
<div class="wrap">
|
||||
<a class="nav-home" href="/react/">
|
||||
<img class="nav-logo" src="/react/img/logo.svg" width="36" height="36">
|
||||
React
|
||||
</a>
|
||||
<div class="nav-lists">
|
||||
<ul class="nav-site nav-site-internal">
|
||||
<li><a href="/react/docs/hello-world.html"{% if page.sectionid == 'docs' or page.sectionid == 'tips' or page.sectionid == 'contributing' %} class="active"{% endif %}>Docs</a></li>
|
||||
<li><a href="/react/tutorial/tutorial.html"{% if page.sectionid == 'tutorial' %} class="active"{% endif %}>Tutorial</a></li>
|
||||
<li><a href="/react/community/support.html"{% if page.sectionid == 'community' %} class="active"{% endif %}>Community</a></li>
|
||||
<li><a href="/react/blog/"{% if page.sectionid == 'blog' %} class="active"{% endif %}>Blog</a></li>
|
||||
<li class="nav-site-search">
|
||||
<input id="algolia-doc-search" type="text" placeholder="Search docs..." />
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="nav-site nav-site-external">
|
||||
<li><a href="https://github.com/facebook/react">GitHub</a></li>
|
||||
<li><a href="https://facebook.github.io/react-native/">React Native</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
111
docs/_js/ErrorDecoderComponent.js
Normal file
111
docs/_js/ErrorDecoderComponent.js
Normal file
@@ -0,0 +1,111 @@
|
||||
/**
|
||||
* Copyright (c) 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
/* global React ReactDOM errorMap:true */
|
||||
'use strict';
|
||||
|
||||
function replaceArgs(msg, argList) {
|
||||
let argIdx = 0;
|
||||
return msg.replace(/%s/g, function() {
|
||||
const arg = argList[argIdx++];
|
||||
return arg === undefined ? '[missing argument]' : arg;
|
||||
});
|
||||
}
|
||||
|
||||
function urlify(str) {
|
||||
const urlRegex = /(https:\/\/fb\.me\/[a-z\-]+)/g;
|
||||
|
||||
const segments = str.split(urlRegex);
|
||||
|
||||
for (let i = 0; i < segments.length; i++) {
|
||||
if (i % 2 === 1) {
|
||||
segments[i] = (<a key={i} target="_blank" href={segments[i]}>{segments[i]}</a>);
|
||||
}
|
||||
}
|
||||
|
||||
return segments;
|
||||
}
|
||||
|
||||
// ?invariant=123&args[]=foo&args[]=bar
|
||||
function parseQueryString() {
|
||||
const rawQueryString = window.location.search.substring(1);
|
||||
if (!rawQueryString) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let code = '';
|
||||
let args = [];
|
||||
|
||||
const queries = rawQueryString.split('&');
|
||||
for (let i = 0; i < queries.length; i++) {
|
||||
const query = decodeURIComponent(queries[i]);
|
||||
if (query.indexOf('invariant=') === 0) {
|
||||
code = query.slice(10);
|
||||
} else if (query.indexOf('args[]=') === 0) {
|
||||
args.push(query.slice(7));
|
||||
}
|
||||
}
|
||||
|
||||
return [code, args];
|
||||
}
|
||||
|
||||
function ErrorResult(props) {
|
||||
const code = props.code;
|
||||
const errorMsg = props.msg;
|
||||
|
||||
if (!code) {
|
||||
return (
|
||||
<p>When you encounter an error, you'll receive a link to this page for that specific error and we'll show you the full error text.</p>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<p>The full text of the error you just encountered is:</p>
|
||||
<code>{urlify(errorMsg)}</code>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
class ErrorDecoder extends React.Component {
|
||||
constructor(...args) {
|
||||
super(...args);
|
||||
|
||||
this.state = {
|
||||
code: null,
|
||||
errorMsg: '',
|
||||
};
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
const parseResult = parseQueryString();
|
||||
if (parseResult != null) {
|
||||
const [code, args] = parseResult;
|
||||
if (errorMap[code]) {
|
||||
this.setState({
|
||||
code: code,
|
||||
errorMsg: replaceArgs(errorMap[code], args),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<ErrorResult
|
||||
code={this.state.code}
|
||||
msg={this.state.errorMsg}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ReactDOM.render(
|
||||
<ErrorDecoder />,
|
||||
document.querySelector('.error-decoder-container')
|
||||
);
|
||||
@@ -1,12 +1,13 @@
|
||||
var name = Math.random() > 0.5 ? 'Jane' : 'John';
|
||||
var HELLO_COMPONENT = `
|
||||
var HelloMessage = React.createClass({
|
||||
render: function() {
|
||||
class HelloMessage extends React.Component {
|
||||
render() {
|
||||
return <div>Hello {this.props.name}</div>;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ReactDOM.render(<HelloMessage name="John" />, mountNode);
|
||||
`;
|
||||
ReactDOM.render(<HelloMessage name="${name}" />, mountNode);
|
||||
`.trim();
|
||||
|
||||
ReactDOM.render(
|
||||
<ReactPlayground codeText={HELLO_COMPONENT} />,
|
||||
|
||||
@@ -1,15 +1,21 @@
|
||||
var MARKDOWN_COMPONENT = `
|
||||
var MarkdownEditor = React.createClass({
|
||||
getInitialState: function() {
|
||||
return {value: 'Type some *markdown* here!'};
|
||||
},
|
||||
handleChange: function() {
|
||||
class MarkdownEditor extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.handleChange = this.handleChange.bind(this);
|
||||
this.state = {value: 'Type some *markdown* here!'};
|
||||
}
|
||||
|
||||
handleChange() {
|
||||
this.setState({value: this.refs.textarea.value});
|
||||
},
|
||||
rawMarkup: function() {
|
||||
return { __html: marked(this.state.value, {sanitize: true}) };
|
||||
},
|
||||
render: function() {
|
||||
}
|
||||
|
||||
getRawMarkup() {
|
||||
var md = new Remarkable();
|
||||
return { __html: md.render(this.state.value) };
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="MarkdownEditor">
|
||||
<h3>Input</h3>
|
||||
@@ -20,15 +26,15 @@ var MarkdownEditor = React.createClass({
|
||||
<h3>Output</h3>
|
||||
<div
|
||||
className="content"
|
||||
dangerouslySetInnerHTML={this.rawMarkup()}
|
||||
dangerouslySetInnerHTML={this.getRawMarkup()}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ReactDOM.render(<MarkdownEditor />, mountNode);
|
||||
`;
|
||||
`.trim();
|
||||
|
||||
ReactDOM.render(
|
||||
<ReactPlayground codeText={MARKDOWN_COMPONENT} />,
|
||||
|
||||
@@ -1,26 +1,33 @@
|
||||
var TIMER_COMPONENT = `
|
||||
var Timer = React.createClass({
|
||||
getInitialState: function() {
|
||||
return {secondsElapsed: 0};
|
||||
},
|
||||
tick: function() {
|
||||
this.setState({secondsElapsed: this.state.secondsElapsed + 1});
|
||||
},
|
||||
componentDidMount: function() {
|
||||
this.interval = setInterval(this.tick, 1000);
|
||||
},
|
||||
componentWillUnmount: function() {
|
||||
class Timer extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {secondsElapsed: 0};
|
||||
}
|
||||
|
||||
tick() {
|
||||
this.setState((prevState) => ({
|
||||
secondsElapsed: prevState.secondsElapsed + 1
|
||||
}));
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.interval = setInterval(() => this.tick(), 1000);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
clearInterval(this.interval);
|
||||
},
|
||||
render: function() {
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>Seconds Elapsed: {this.state.secondsElapsed}</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ReactDOM.render(<Timer />, mountNode);
|
||||
`;
|
||||
`.trim();
|
||||
|
||||
ReactDOM.render(
|
||||
<ReactPlayground codeText={TIMER_COMPONENT} />,
|
||||
|
||||
@@ -1,41 +1,56 @@
|
||||
var TODO_COMPONENT = `
|
||||
var TodoList = React.createClass({
|
||||
render: function() {
|
||||
var createItem = function(item) {
|
||||
return <li key={item.id}>{item.text}</li>;
|
||||
};
|
||||
return <ul>{this.props.items.map(createItem)}</ul>;
|
||||
class TodoApp extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.handleChange = this.handleChange.bind(this);
|
||||
this.handleSubmit = this.handleSubmit.bind(this);
|
||||
this.state = {items: [], text: ''};
|
||||
}
|
||||
});
|
||||
var TodoApp = React.createClass({
|
||||
getInitialState: function() {
|
||||
return {items: [], text: ''};
|
||||
},
|
||||
onChange: function(e) {
|
||||
this.setState({text: e.target.value});
|
||||
},
|
||||
handleSubmit: function(e) {
|
||||
e.preventDefault();
|
||||
var nextItems = this.state.items.concat([{text: this.state.text, id: Date.now()}]);
|
||||
var nextText = '';
|
||||
this.setState({items: nextItems, text: nextText});
|
||||
},
|
||||
render: function() {
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<h3>TODO</h3>
|
||||
<TodoList items={this.state.items} />
|
||||
<form onSubmit={this.handleSubmit}>
|
||||
<input onChange={this.onChange} value={this.state.text} />
|
||||
<input onChange={this.handleChange} value={this.state.text} />
|
||||
<button>{'Add #' + (this.state.items.length + 1)}</button>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
handleChange(e) {
|
||||
this.setState({text: e.target.value});
|
||||
}
|
||||
|
||||
handleSubmit(e) {
|
||||
e.preventDefault();
|
||||
var newItem = {
|
||||
text: this.state.text,
|
||||
id: Date.now()
|
||||
};
|
||||
this.setState((prevState) => ({
|
||||
items: prevState.items.concat(newItem),
|
||||
text: ''
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
class TodoList extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<ul>
|
||||
{this.props.items.map(item => (
|
||||
<li key={item.id}>{item.text}</li>
|
||||
))}
|
||||
</ul>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ReactDOM.render(<TodoApp />, mountNode);
|
||||
`;
|
||||
`.trim();
|
||||
|
||||
ReactDOM.render(
|
||||
<ReactPlayground codeText={TODO_COMPONENT} />,
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
/**
|
||||
* Copyright 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
/**
|
||||
* This is a web interface for the HTML to JSX converter contained in
|
||||
* `html-jsx-lib.js`.
|
||||
*/
|
||||
;(function() {
|
||||
|
||||
var HELLO_COMPONENT = "\
|
||||
<!-- Hello world -->\n\
|
||||
<div class=\"awesome\" style=\"border: 1px solid red\">\n\
|
||||
<label for=\"name\">Enter your name: </label>\n\
|
||||
<input type=\"text\" id=\"name\" />\n\
|
||||
</div>\n\
|
||||
<p>Enter your HTML here</p>\
|
||||
";
|
||||
|
||||
var HTMLtoJSXComponent = React.createClass({
|
||||
getInitialState: function() {
|
||||
return {
|
||||
outputClassName: 'NewComponent',
|
||||
createClass: true
|
||||
};
|
||||
},
|
||||
onReactClassNameChange: function(evt) {
|
||||
this.setState({ outputClassName: evt.target.value });
|
||||
},
|
||||
onCreateClassChange: function(evt) {
|
||||
this.setState({ createClass: evt.target.checked });
|
||||
},
|
||||
setInput: function(input) {
|
||||
this.setState({ input: input });
|
||||
this.convertToJsx();
|
||||
},
|
||||
convertToJSX: function(input) {
|
||||
var converter = new HTMLtoJSX({
|
||||
outputClassName: this.state.outputClassName,
|
||||
createClass: this.state.createClass
|
||||
});
|
||||
return converter.convert(input);
|
||||
},
|
||||
render: function() {
|
||||
return (
|
||||
<div>
|
||||
<div id="options">
|
||||
<label>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={this.state.createClass}
|
||||
onChange={this.onCreateClassChange} />
|
||||
Create class
|
||||
</label>
|
||||
<label style={{display: this.state.createClass ? '' : 'none'}}>
|
||||
·
|
||||
Class name:
|
||||
<input
|
||||
type="text"
|
||||
value={this.state.outputClassName}
|
||||
onChange={this.onReactClassNameChange} />
|
||||
</label>
|
||||
</div>
|
||||
<ReactPlayground
|
||||
codeText={HELLO_COMPONENT}
|
||||
renderCode={true}
|
||||
transformer={this.convertToJSX}
|
||||
showCompiledJSTab={false}
|
||||
editorTabTitle="Live HTML Editor"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
ReactDOM.render(<HTMLtoJSXComponent />, document.getElementById('jsxCompiler'));
|
||||
}());
|
||||
@@ -22,7 +22,7 @@ var CodeMirrorEditor = React.createClass({
|
||||
if (IS_MOBILE) return;
|
||||
|
||||
this.editor = CodeMirror.fromTextArea(ReactDOM.findDOMNode(this.refs.editor), {
|
||||
mode: 'javascript',
|
||||
mode: 'jsx',
|
||||
lineNumbers: this.props.lineNumbers,
|
||||
lineWrapping: true,
|
||||
smartIndent: false, // javascript mode does bad things with jsx indents
|
||||
@@ -90,8 +90,14 @@ var ReactPlayground = React.createClass({
|
||||
|
||||
getDefaultProps: function() {
|
||||
return {
|
||||
transformer: function(code) {
|
||||
return babel.transform(code).code;
|
||||
transformer: function(code, options) {
|
||||
var presets = ['react'];
|
||||
if (!options || !options.skipES2015Transform) {
|
||||
presets.push('es2015');
|
||||
}
|
||||
return Babel.transform(code, {
|
||||
presets
|
||||
}).code;
|
||||
},
|
||||
editorTabTitle: 'Live JSX Editor',
|
||||
showCompiledJSTab: true,
|
||||
@@ -115,15 +121,15 @@ var ReactPlayground = React.createClass({
|
||||
this.setState({mode: mode});
|
||||
},
|
||||
|
||||
compileCode: function() {
|
||||
return this.props.transformer(this.state.code);
|
||||
compileCode: function(options) {
|
||||
return this.props.transformer(this.state.code, options);
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var isJS = this.state.mode === this.MODES.JS;
|
||||
var compiledCode = '';
|
||||
try {
|
||||
compiledCode = this.compileCode();
|
||||
compiledCode = this.compileCode({skipES2015Transform: true});
|
||||
} catch (err) {}
|
||||
|
||||
var JSContent =
|
||||
@@ -201,13 +207,15 @@ var ReactPlayground = React.createClass({
|
||||
} catch (e) { }
|
||||
|
||||
try {
|
||||
var compiledCode = this.compileCode();
|
||||
var compiledCode;
|
||||
if (this.props.renderCode) {
|
||||
compiledCode = this.compileCode({skipES2015Transform: true});
|
||||
ReactDOM.render(
|
||||
<CodeMirrorEditor codeText={compiledCode} readOnly={true} />,
|
||||
mountNode
|
||||
);
|
||||
} else {
|
||||
compiledCode = this.compileCode({skipES2015Transform: false});
|
||||
eval(compiledCode);
|
||||
}
|
||||
} catch (err) {
|
||||
|
||||
29
docs/_layouts/community.html
Normal file
29
docs/_layouts/community.html
Normal file
@@ -0,0 +1,29 @@
|
||||
---
|
||||
layout: default
|
||||
sectionid: community
|
||||
---
|
||||
|
||||
<section class="content wrap communityContent">
|
||||
<div class="inner-content">
|
||||
<a class="edit-page-link"
|
||||
href="https://github.com/facebook/react/tree/master/docs/{{ page.path }}"
|
||||
target="_blank">Edit on GitHub</a>
|
||||
<h1>
|
||||
{{ page.title }}
|
||||
</h1>
|
||||
<div class="subHeader">{{ page.description }}</div>
|
||||
|
||||
{{ content }}
|
||||
|
||||
<div class="docs-prevnext">
|
||||
{% if page.prev %}
|
||||
<a class="docs-prev" href="/react/community/{{ page.prev }}">← Prev</a>
|
||||
{% endif %}
|
||||
{% if page.next %}
|
||||
<a class="docs-next" href="/react/community/{{ page.next }}">Next →</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% include nav_community.html %}
|
||||
</section>
|
||||
@@ -1,11 +1,9 @@
|
||||
---
|
||||
layout: default
|
||||
sectionid: tips
|
||||
sectionid: contributing
|
||||
---
|
||||
|
||||
<section class="content wrap documentationContent">
|
||||
{% include nav_docs.html %}
|
||||
|
||||
<div class="inner-content">
|
||||
<h1>{{ page.title }}</h1>
|
||||
<div class="subHeader">{{ page.description }}</div>
|
||||
@@ -13,11 +11,13 @@ sectionid: tips
|
||||
|
||||
<div class="docs-prevnext">
|
||||
{% if page.prev %}
|
||||
<a class="docs-prev" href="/react/tips/{{ page.prev }}">← Prev</a>
|
||||
<a class="docs-prev" href="/react/contributing/{{ page.prev }}">← Prev</a>
|
||||
{% endif %}
|
||||
{% if page.next %}
|
||||
<a class="docs-next" href="/react/tips/{{ page.next }}">Next →</a>
|
||||
<a class="docs-next" href="/react/contributing/{{ page.next }}">Next →</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% include nav_docs.html %}
|
||||
</section>
|
||||
@@ -1,16 +1,26 @@
|
||||
{% if page.excerpt %}
|
||||
{% assign type = 'article' %}
|
||||
{% assign sectionTitle = 'React Blog' %}
|
||||
{% assign description = page.excerpt | remove: '<p>' | remove: '</p>' %}
|
||||
{% else %}
|
||||
{% assign type = 'website' %}
|
||||
{% assign sectionTitle = 'React' %}
|
||||
{% assign description = 'A JavaScript library for building user interfaces' %}
|
||||
{% endif %}
|
||||
{% assign title = page.title | append: ' - ' | append: sectionTitle %}
|
||||
<!DOCTYPE html>
|
||||
<!--[if IE]><![endif]-->
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<title>{{ page.title }} | React</title>
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<meta property="og:title" content="{{ page.title }} | React">
|
||||
<meta property="og:type" content="website">
|
||||
<title>{{ title }}</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta property="og:title" content="{{ title }}">
|
||||
<meta property="og:type" content="{{ type }}">
|
||||
<meta property="og:url" content="https://facebook.github.io/react{{ page.url }}">
|
||||
<meta property="og:image" content="https://facebook.github.io/react/img/logo_og.png">
|
||||
<meta property="og:description" content="A JavaScript library for building user interfaces">
|
||||
<meta property="og:description" content="{{ description }}">
|
||||
<meta property="fb:app_id" content="623268441017527">
|
||||
|
||||
<link rel="shortcut icon" href="/react/favicon.ico">
|
||||
@@ -32,69 +42,25 @@
|
||||
<script type="text/javascript" src="https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js"></script>
|
||||
<script src="/react/js/codemirror.js"></script>
|
||||
<script src="/react/js/javascript.js"></script>
|
||||
<script src="/react/js/xml.js"></script>
|
||||
<script src="/react/js/jsx.js"></script>
|
||||
<script src="/react/js/react.js"></script>
|
||||
<script src="/react/js/react-dom.js"></script>
|
||||
<script src="/react/js/babel-browser.min.js"></script>
|
||||
<script src="/react/js/babel.min.js"></script>
|
||||
<script src="/react/js/live_editor.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="container">
|
||||
|
||||
<div class="nav-main">
|
||||
<div class="wrap">
|
||||
<a class="nav-home" href="/react/index.html">
|
||||
<img class="nav-logo" src="/react/img/logo.svg" width="36" height="36">
|
||||
React
|
||||
</a>
|
||||
<ul class="nav-site nav-site-internal">
|
||||
<li><a href="/react/docs/getting-started.html"{% if page.sectionid == 'docs' or page.sectionid == 'tips' %} class="active"{% endif %}>Docs</a></li>
|
||||
<li><a href="/react/support.html"{% if page.id == 'support' %} class="active"{% endif %}>Support</a></li>
|
||||
<li><a href="/react/downloads.html"{% if page.id == 'downloads' %} class="active"{% endif %}>Download</a></li>
|
||||
<li><a href="/react/blog/"{% if page.sectionid == 'blog' %} class="active"{% endif %}>Blog</a></li>
|
||||
<li>
|
||||
<input id="algolia-doc-search" type="text" placeholder="Search docs..." />
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<ul class="nav-site nav-site-external">
|
||||
<li><a href="https://github.com/facebook/react">GitHub</a></li>
|
||||
<li><a href="https://facebook.github.io/react-native/">React Native</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if page.id == 'home' %}
|
||||
<div class="hero">
|
||||
<div class="wrap">
|
||||
<div class="text"><strong>React</strong></div>
|
||||
<div class="minitext">
|
||||
A JavaScript library for building user interfaces
|
||||
</div>
|
||||
|
||||
<div class="buttons-unit">
|
||||
<a href="/react/docs/getting-started.html" class="button">Get Started</a>
|
||||
<a href="/react/downloads.html" class="button">Download React v{{site.react_version}}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% include navigation.html %}
|
||||
|
||||
{{ content }}
|
||||
|
||||
<footer class="wrap">
|
||||
<div class="left">
|
||||
A Facebook & Instagram collaboration.<br>
|
||||
<a href="/react/acknowledgements.html">Acknowledgements</a>
|
||||
</div>
|
||||
<div class="right">
|
||||
© 2013–{{ site.time | date: '%Y' }} Facebook Inc.<br>
|
||||
Documentation licensed under <a href="https://creativecommons.org/licenses/by/4.0/">CC BY 4.0</a>.
|
||||
</div>
|
||||
</footer>
|
||||
{% include footer.html %}
|
||||
</div>
|
||||
<div id="fb-root"></div>
|
||||
|
||||
<div id="fb-root"></div>
|
||||
<script>
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||
@@ -109,7 +75,7 @@
|
||||
var js, fjs = d.getElementsByTagName(s)[0];
|
||||
if (d.getElementById(id)) return;
|
||||
js = d.createElement(s); js.id = id;
|
||||
js.src = "//connect.facebook.net/en_US/all.js#xfbml=1&appId=623268441017527";
|
||||
js.src = "//connect.facebook.net/en_US/sdk.js#xfbml=1&version=v2.6&appId=623268441017527";
|
||||
fjs.parentNode.insertBefore(js, fjs);
|
||||
}(document, 'script', 'facebook-jssdk'));
|
||||
|
||||
|
||||
@@ -4,8 +4,6 @@ sectionid: docs
|
||||
---
|
||||
|
||||
<section class="content wrap documentationContent">
|
||||
{% include nav_docs.html %}
|
||||
|
||||
<div class="inner-content">
|
||||
<a class="edit-page-link" href="https://github.com/facebook/react/tree/master/docs/{{ page.path }}" target="_blank">Edit on GitHub</a>
|
||||
<h1>
|
||||
@@ -24,4 +22,6 @@ sectionid: docs
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% include nav_docs.html %}
|
||||
</section>
|
||||
|
||||
11
docs/_layouts/hero.html
Normal file
11
docs/_layouts/hero.html
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
layout: default
|
||||
---
|
||||
|
||||
{% if page.id == 'home' %}
|
||||
{% include hero.html %}
|
||||
{% endif %}
|
||||
|
||||
<section class="content wrap">
|
||||
{{ content }}
|
||||
</section>
|
||||
@@ -4,8 +4,9 @@ sectionid: blog
|
||||
---
|
||||
|
||||
<section class="content wrap blogContent">
|
||||
{% include nav_blog.html %}
|
||||
|
||||
<div class="inner-content">
|
||||
{% include blog_post.html isPermalink="true" page=page content=content %}
|
||||
</div>
|
||||
{% include nav_blog.html %}
|
||||
</section>
|
||||
|
||||
29
docs/_layouts/tutorial.html
Normal file
29
docs/_layouts/tutorial.html
Normal file
@@ -0,0 +1,29 @@
|
||||
---
|
||||
layout: default
|
||||
sectionid: tutorial
|
||||
---
|
||||
|
||||
<section class="content wrap documentationContent">
|
||||
{% include nav_tutorial.html %}
|
||||
|
||||
<div class="inner-content">
|
||||
<a class="edit-page-link"
|
||||
href="https://github.com/facebook/react/tree/master/docs/{{ page.path }}"
|
||||
target="_blank">Edit on GitHub</a>
|
||||
<h1>
|
||||
{{ page.title }}
|
||||
</h1>
|
||||
<div class="subHeader">{{ page.description }}</div>
|
||||
|
||||
{{ content }}
|
||||
|
||||
<div class="docs-prevnext">
|
||||
{% if page.prev %}
|
||||
<a class="docs-prev" href="/react/tutorial/{{ page.prev }}">← Prev</a>
|
||||
{% endif %}
|
||||
{% if page.next %}
|
||||
<a class="docs-next" href="/react/tutorial/{{ page.next }}">Next →</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -6,7 +6,7 @@
|
||||
module Authors
|
||||
class Generator < Jekyll::Generator
|
||||
def generate(site)
|
||||
site.posts.each do |post|
|
||||
site.posts.docs.each do |post|
|
||||
authors = []
|
||||
if post['author'].kind_of?(Array)
|
||||
for author in post['author']
|
||||
|
||||
@@ -2,14 +2,17 @@ require 'redcarpet'
|
||||
require 'sanitize'
|
||||
|
||||
# Simple converter that is probably better than RedCarpet's built in TOC id
|
||||
# generator (which ends up with things lik id="toc_1"... terrible).
|
||||
# generator (which ends up with things like id="toc_1"... terrible).
|
||||
|
||||
class Redcarpet::Render::HTML
|
||||
def header(title, level)
|
||||
# \p{Common} does not seem to include some of the Japanese alphabets and also includes
|
||||
# some undesired characters like colon and parentheses, so we have to write out the
|
||||
# necessary Unicode scripts individually.
|
||||
clean_title = Sanitize.clean(title)
|
||||
.downcase
|
||||
.gsub(/\s+/, "-")
|
||||
.gsub(/[^A-Za-z0-9\-_.]/, "")
|
||||
.gsub(/[^A-Za-z0-9\-_.\p{Cyrillic}\p{Hangul}\p{Hiragana}\p{Katakana}\p{Han}]/, "")
|
||||
|
||||
return "<h#{level}><a class=\"anchor\" name=\"#{clean_title}\"></a>#{title} <a class=\"hash-link\" href=\"##{clean_title}\">#</a></h#{level}>"
|
||||
end
|
||||
|
||||
@@ -1,20 +1,39 @@
|
||||
module Jekyll
|
||||
module SidebarItemFilter
|
||||
def sidebar_item_link(item)
|
||||
def docs_sidebar_link(item)
|
||||
return sidebar_helper(item, 'docs')
|
||||
end
|
||||
|
||||
def docs_old_sidebar_link(item)
|
||||
return sidebar_helper(item, 'docs-old')
|
||||
end
|
||||
|
||||
def community_sidebar_link(item)
|
||||
return sidebar_helper(item, 'community')
|
||||
end
|
||||
|
||||
def tutorial_sidebar_link(item)
|
||||
return sidebar_helper(item, 'tutorial')
|
||||
end
|
||||
|
||||
def sidebar_helper(item, group)
|
||||
forceInternal = item["forceInternal"]
|
||||
|
||||
pageID = @context.registers[:page]["id"]
|
||||
itemID = item["id"]
|
||||
href = item["href"] || "/react/docs/#{itemID}.html"
|
||||
href = item["href"] || "/react/#{group}/#{itemID}.html"
|
||||
classes = []
|
||||
if pageID == itemID
|
||||
classes.push("active")
|
||||
end
|
||||
if item["href"]
|
||||
if item["href"] && (forceInternal == nil)
|
||||
classes.push("external")
|
||||
end
|
||||
className = classes.size > 0 ? " class=\"#{classes.join(' ')}\"" : ""
|
||||
|
||||
return "<a href=\"#{href}\"#{className}>#{item["title"]}</a>"
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ to the DOM.
|
||||
> lightweight description of what the DOM should look like.
|
||||
|
||||
We call this process **reconciliation**. Check out
|
||||
[this jsFiddle](http://jsfiddle.net/fv6RD/3/) to see an example of
|
||||
[this jsFiddle](http://jsfiddle.net/2h6th4ju/) to see an example of
|
||||
reconciliation in action.
|
||||
|
||||
Because this re-render is so fast (around 1ms for TodoMVC), the developer
|
||||
|
||||
@@ -47,7 +47,7 @@ Over the past several weeks, members of our team, [Pete Hunt](http://www.petehun
|
||||
|
||||
[Pete Hunt](http://www.petehunt.net/) recorded himself implementing a simple `<Blink>` tag in React.
|
||||
|
||||
<figure><iframe src="https://player.vimeo.com/video/67248575" width="500" height="340" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe></figure>
|
||||
<figure><iframe src="https://player.vimeo.com/video/67248575" width="100%" height="340" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe></figure>
|
||||
|
||||
## Snake in React
|
||||
|
||||
|
||||
@@ -68,14 +68,14 @@ React.renderComponent(
|
||||
|
||||
[Domenic Denicola](http://domenicdenicola.com/) wrote a slide deck about the great applications of ES6 features and one slide shows how we could use Template Strings to compile JSX at run-time without the need for a pre-processing phase.
|
||||
|
||||
<figure><iframe src="https://www.slideshare.net/slideshow/embed_code/24187146?rel=0&startSlide=36" width="600" height="356" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC;border-width:1px 1px 0;margin-bottom:5px" allowfullscreen webkitallowfullscreen mozallowfullscreen> </iframe></figure>
|
||||
<figure><iframe src="https://www.slideshare.net/slideshow/embed_code/24187146?rel=0&startSlide=36" width="100%" height="356" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC;border-width:1px 1px 0;margin-bottom:5px" allowfullscreen webkitallowfullscreen mozallowfullscreen> </iframe></figure>
|
||||
|
||||
|
||||
## React Presentation
|
||||
|
||||
[Tom Occhino](http://tomocchino.com/) and [Jordan Walke](https://github.com/jordwalke), React developers, did a presentation of React at Facebook Seattle's office. Check out the first 25 minutes for the presentation and the remaining 45 for a Q&A. I highly recommend you watching this video.
|
||||
|
||||
<figure><iframe width="650" height="400" src="//www.youtube-nocookie.com/embed/XxVg_s8xAms" frameborder="0" allowfullscreen></iframe></figure>
|
||||
<figure><iframe width="100%" height="400" src="//www.youtube-nocookie.com/embed/XxVg_s8xAms" frameborder="0" allowfullscreen></iframe></figure>
|
||||
|
||||
|
||||
## Docs
|
||||
|
||||
@@ -29,7 +29,7 @@ We organized a React hackathon last week-end in the Facebook Seattle office. 50
|
||||
|
||||
The video will be available soon on the [JSConf EU website](http://2013.jsconf.eu/speakers/pete-hunt-react-rethinking-best-practices.html), but in the meantime, here are Pete's slides:
|
||||
|
||||
<figure><iframe src="https://www.slideshare.net/slideshow/embed_code/26589373" width="550" height="450" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" allowfullscreen></iframe></figure>
|
||||
<figure><iframe src="https://www.slideshare.net/slideshow/embed_code/26589373" width="100%" height="450" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" allowfullscreen></iframe></figure>
|
||||
|
||||
|
||||
## Pump - Clojure bindings for React
|
||||
@@ -96,4 +96,3 @@ var Table = React.createClass({
|
||||
> You see that React components are defined using a regular JS object. Some properties and methods of the object such as render() have special meanings, the rest is upforgrabs.
|
||||
>
|
||||
> [Read the full article...](http://www.phpied.com/reactive-table/)
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ The best part is that no drastic changes have been required to support all those
|
||||
|
||||
[Pete Hunt](http://www.petehunt.net/)'s talk at JSConf EU 2013 is now available in video.
|
||||
|
||||
<figure><iframe width="600" height="370" src="//www.youtube-nocookie.com/embed/x7cQ3mrcKaY" frameborder="0" allowfullscreen></iframe></figure>
|
||||
<figure><iframe width="100%" height="370" src="//www.youtube-nocookie.com/embed/x7cQ3mrcKaY" frameborder="0" allowfullscreen></iframe></figure>
|
||||
|
||||
|
||||
## Server-side React with PHP
|
||||
|
||||
@@ -9,7 +9,7 @@ This round-up is the proof that React has taken off from its Facebook's root: it
|
||||
|
||||
[Steve Luscher](https://github.com/steveluscher) working at [LeanPub](https://leanpub.com/) made a 30 min talk at [Super VanJS](https://twitter.com/vanjs). He does a remarkable job at explaining why React is so fast with very exciting demos using the HTML5 Audio API.
|
||||
|
||||
<figure><iframe width="600" height="338" src="//www.youtube-nocookie.com/embed/1OeXsL5mr4g" frameborder="0" allowfullscreen></iframe></figure>
|
||||
<figure><iframe width="100%" height="338" src="//www.youtube-nocookie.com/embed/1OeXsL5mr4g" frameborder="0" allowfullscreen></iframe></figure>
|
||||
|
||||
|
||||
## React Tips
|
||||
@@ -64,7 +64,7 @@ This round-up is the proof that React has taken off from its Facebook's root: it
|
||||
>
|
||||
> [Read the full article...](http://rz.scale-it.pl/2013/10/20/frontend_components_in_react.html)
|
||||
|
||||
<figure><iframe src="https://docs.google.com/presentation/d/1JSFbjCuuexwOHCeHWBMNRIJdyfD2Z0ZQwX65WOWkfaI/embed?start=false" frameborder="0" width="600" height="468" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"> </iframe></figure>
|
||||
<figure><iframe src="https://docs.google.com/presentation/d/1JSFbjCuuexwOHCeHWBMNRIJdyfD2Z0ZQwX65WOWkfaI/embed?start=false" frameborder="0" width="100%" height="468" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"> </iframe></figure>
|
||||
|
||||
|
||||
## JSX
|
||||
|
||||
@@ -10,7 +10,7 @@ Happy holidays! This blog post is a little-late Christmas present for all the Re
|
||||
|
||||
[Pete Hunt](http://www.petehunt.net/) wrote three demos showing that React can be used to run 60fps native-like experiences on mobile web. A frosted glass effect, an image gallery with 3d animations and an infinite scroll view.
|
||||
|
||||
<figure><iframe src="//player.vimeo.com/video/79659941" width="220" height="400" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe></figure>
|
||||
<figure><iframe src="//player.vimeo.com/video/79659941" width="100%" height="400" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe></figure>
|
||||
|
||||
[Try out the demos!](https://petehunt.github.io/react-touch/)
|
||||
|
||||
@@ -19,7 +19,7 @@ Happy holidays! This blog post is a little-late Christmas present for all the Re
|
||||
|
||||
[Stoyan Stefanov](http://www.phpied.com/) talked at Joe Dev On Tech about React. He goes over all the features of the library and ends with a concrete example.
|
||||
|
||||
<figure><iframe width="560" height="315" src="//www.youtube-nocookie.com/embed/SMMRJif5QW0" frameborder="0" allowfullscreen></iframe></figure>
|
||||
<figure><iframe width="100%" height="315" src="//www.youtube-nocookie.com/embed/SMMRJif5QW0" frameborder="0" allowfullscreen></iframe></figure>
|
||||
|
||||
|
||||
## JSX: E4X The Good Parts
|
||||
@@ -115,4 +115,3 @@ var MyComponent = React.createClass({
|
||||
## Random Tweet
|
||||
|
||||
<center><blockquote class="twitter-tweet" lang="en"><p>I may be starting to get annoying with this, but ReactJS is really exciting. I truly feel the virtual DOM is a game changer.</p>— Eric Florenzano (@ericflo) <a href="https://twitter.com/ericflo/statuses/413842834974732288">December 20, 2013</a></blockquote></center>
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ author: sebmarkbage
|
||||
|
||||
With the new year, we thought you'd enjoy some new tools for debugging React code. Today we're releasing the [React Developer Tools](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi), an extension to the Chrome Developer Tools. [Download them from the Chrome Web Store](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi).
|
||||
|
||||
<figure><iframe width="560" height="315" src="//www.youtube-nocookie.com/embed/Cey7BS6dE0M" frameborder="0" allowfullscreen></iframe></figure>
|
||||
<figure><iframe width="100%" height="315" src="//www.youtube-nocookie.com/embed/Cey7BS6dE0M" frameborder="0" allowfullscreen></iframe></figure>
|
||||
|
||||
You will get a new tab titled "React" in your Chrome DevTools. This tab shows you a list of the root React Components that are rendered on the page as well as the subcomponents that each root renders.
|
||||
|
||||
@@ -15,4 +15,3 @@ When you inspect a DOM element using the regular Elements tab, you can switch ov
|
||||
<figure>[](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi)</figure>
|
||||
|
||||
We hope these tools will help your team better understand your component hierarchy and track down bugs. We're very excited about this initial launch and appreciate any feedback you may have. As always, we also accept [pull requests on GitHub](https://github.com/facebook/react-devtools).
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ React is only one-piece of your web application stack. [Mark Lussier](https://gi
|
||||
|
||||
## React Rails Tutorial
|
||||
|
||||
[Selem Delul](http://selem.im) bundled the [React Tutorial](/react/docs/tutorial.html) into a rails app. This is a good example on how to get started with a rails project.
|
||||
[Selem Delul](http://selem.im) bundled the [React Tutorial](/react/tutorial/tutorial.html) into a rails app. This is a good example on how to get started with a rails project.
|
||||
|
||||
> ```
|
||||
git clone https://github.com/necrodome/react-rails-tutorial
|
||||
|
||||
@@ -34,7 +34,7 @@ React's one-way data-binding naturally lends itself to a functional programming
|
||||
|
||||
Pete also explains this in detail at his #MeteorDevShop talk (about 30 Minutes):
|
||||
|
||||
<iframe width="560" height="315" src="//www.youtube-nocookie.com/embed/Lqcs6hPOcFw?start=2963" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="315" src="//www.youtube-nocookie.com/embed/Lqcs6hPOcFw?start=2963" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ There have been many posts recently covering the <i>why</i> and <i>how</i> of Re
|
||||
## React in a nutshell
|
||||
Got five minutes to pitch React to your coworkers? John Lynch ([@johnrlynch](https://twitter.com/johnrlynch)) put together [this excellent and refreshing slideshow](http://slid.es/johnlynch/reactjs):
|
||||
|
||||
<iframe src="//slid.es/johnlynch/reactjs/embed" width="576" height="420" scrolling="no" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
|
||||
<iframe src="//slid.es/johnlynch/reactjs/embed" width="100%" height="420" scrolling="no" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ Rafał Cieślak ([@Ravicious](https://twitter.com/Ravicious)) wrote a [React ver
|
||||
|
||||
Emanuele shared this awesome demo video with us:
|
||||
|
||||
<iframe width="560" height="315" src="//www.youtube-nocookie.com/embed/jYcpaemt90M" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="315" src="//www.youtube-nocookie.com/embed/jYcpaemt90M" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ Ian Bicking ([@ianbicking](https://twitter.com/ianbicking)) of Mozilla Labs [exp
|
||||
|
||||
React was also recently mentioned at ng-conf, where the Angular team commented on React's concept of the virtual DOM:
|
||||
|
||||
<iframe width="560" height="315" src="//www.youtube-nocookie.com/embed/srt3OBP2kGc?start=113" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="315" src="//www.youtube-nocookie.com/embed/srt3OBP2kGc?start=113" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
## React and Web Components
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ author: [fisherwebdev, jingc]
|
||||
|
||||
We recently spoke at one of f8's breakout session about Flux, a data flow architecture that works well with React. Check out the video here:
|
||||
|
||||
<figure><iframe width="560" height="315" src="//www.youtube-nocookie.com/embed/nYkdrAPrdcw?list=PLb0IAmt7-GS188xDYE-u1ShQmFFGbrk0v&start=621" frameborder="0" allowfullscreen></iframe></figure>
|
||||
<figure><iframe width="100%" height="315" src="//www.youtube-nocookie.com/embed/nYkdrAPrdcw?list=PLb0IAmt7-GS188xDYE-u1ShQmFFGbrk0v&start=621" frameborder="0" allowfullscreen></iframe></figure>
|
||||
|
||||
To summarize, Flux works well for us because the single directional data flow makes it easy to understand and modify an application as it becomes more complicated. We found that two-way data bindings lead to cascading updates, where changing one data model led to another data model updating, making it very difficult to predict what would change as the result of a single user interaction.
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ These are some of the links that often pop up on the #reactjs IRC channel. If yo
|
||||
|
||||
The core concepts React themselves is something very valuable that the community is exploring and pushing further. A year ago, we wouldn't have imagined something like [Bruce Hauman](http://rigsomelight.com)'s [Flappy Bird ClojureScript port](http://rigsomelight.com/2014/05/01/interactive-programming-flappy-bird-clojurescript.html), whose interactive programming has been made possible through React:
|
||||
|
||||
<iframe width="560" height="315" src="//www.youtube-nocookie.com/embed/KZjFVdU8VLI" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="315" src="//www.youtube-nocookie.com/embed/KZjFVdU8VLI" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
And don't forget [Pete Hunt](https://github.com/petehunt)'s Wolfenstein 3D rendering engine in React ([source code](https://github.com/petehunt/wolfenstein3D-react/blob/master/js/renderer.js#L183)). While it's nearly a year old, it's still a nice demo.
|
||||
|
||||
|
||||
@@ -16,14 +16,14 @@ It's an exciting time for React as there are now more commits from open source c
|
||||
|
||||
At the last [JSConf.us](http://2014.jsconf.us/), Vjeux talked about the design decisions made in the API that allows it to scale to a large number of developers. If you don't have 20 minutes, take a look at the [annotated slides](https://speakerdeck.com/vjeux/why-does-react-scale-jsconf-2014).
|
||||
|
||||
<iframe width="650" height="315" src="//www.youtube-nocookie.com/embed/D-ioDiacTm8" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="315" src="//www.youtube-nocookie.com/embed/D-ioDiacTm8" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
|
||||
## Live Editing
|
||||
|
||||
One of the best features of React is that it provides the foundations to implement concepts that were otherwise extremely difficult, like server-side rendering, undo-redo, rendering to non-DOM environments like canvas... [Dan Abramov](https://twitter.com/dan_abramov) got hot code reloading working with webpack in order to [live edit a React project](https://gaearon.github.io/react-hot-loader/)!
|
||||
|
||||
<iframe src="//player.vimeo.com/video/100010922" width="650" height="315" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
|
||||
<iframe src="//player.vimeo.com/video/100010922" width="100%" height="315" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
|
||||
|
||||
|
||||
## ReactIntl Mixin by Yahoo
|
||||
@@ -63,7 +63,7 @@ If you missed the last [London React Meetup](http://www.meetup.com/London-React-
|
||||
- React on Rails - How to use React with Ruby on Rails to build isomorphic apps
|
||||
- Building an isomorphic, real-time to-do list with moped and node.js
|
||||
|
||||
<iframe width="650" height="315" src="//www.youtube-nocookie.com/embed/CP3lvm5Ppqo" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="315" src="//www.youtube-nocookie.com/embed/CP3lvm5Ppqo" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
In related news, the next [React SF Meetup](http://www.meetup.com/ReactJS-San-Francisco/events/195518392/) will be from Prezi: [“Immediate Mode on the Web: How We Implemented the Prezi Viewer in JavaScript”](https://medium.com/prezi-engineering/how-and-why-prezi-turned-to-javascript-56e0ca57d135). While not in React, their tech is really awesome and shares a lot of React's design principles and perf optimizations.
|
||||
|
||||
|
||||
@@ -104,7 +104,7 @@ var parsedComponent = reactParser(html, React);
|
||||
|
||||
If you haven't yet tried out React, Jacob Rios did a Hangout where he covers the most important aspects and thankfully he recorded it!
|
||||
|
||||
<iframe width="650" height="315" src="//www.youtube-nocookie.com/embed/lAn7GVoGlKU" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="315" src="//www.youtube-nocookie.com/embed/lAn7GVoGlKU" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
|
||||
## Random Tweets
|
||||
|
||||
@@ -20,7 +20,7 @@ This has been an exciting summer as four big companies: Yahoo, Mozilla, Airbnb a
|
||||
|
||||
[Vjeux](http://blog.vjeux.com/), from the React team, gave a talk at OSCON on the history of React and the various optimizations strategies that are implemented. You can also check out the [annotated slides](https://speakerdeck.com/vjeux/oscon-react-architecture) or [Chris Dawson](http://thenewstack.io/author/chrisdawson/)'s notes titled [JavaScript’s History and How it Led To React](http://thenewstack.io/javascripts-history-and-how-it-led-to-reactjs/).
|
||||
|
||||
<iframe width="650" height="315" src="//www.youtube-nocookie.com/embed/eCf5CquV_Bw" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="315" src="//www.youtube-nocookie.com/embed/eCf5CquV_Bw" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
|
||||
## v8 optimizations
|
||||
@@ -89,7 +89,7 @@ var Button = React.createClass({
|
||||
|
||||
If you are getting started with React, [Joe Maddalone](http://www.joemaddalone.com/) made a good tutorial on how to build your first component.
|
||||
|
||||
<iframe width="650" height="200" src="//www.youtube-nocookie.com/embed/rFvZydtmsxM" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="200" src="//www.youtube-nocookie.com/embed/rFvZydtmsxM" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
|
||||
## Saving time & staying sane?
|
||||
|
||||
@@ -10,7 +10,7 @@ This round-up is a special edition on [Flux](https://facebook.github.io/flux/).
|
||||
|
||||
Facebook engineers [Jing Chen](https://github.com/jingc) and [Bill Fisher](https://github.com/fisherwebdev) gave a talk about Flux and React at [ForwardJS](http://forwardjs.com/), and how using an application architecture with a unidirectional data flow helped solve recurring bugs.
|
||||
|
||||
<iframe width="650" height="315" src="//www.youtube-nocookie.com/embed/i__969noyAM" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="315" src="//www.youtube-nocookie.com/embed/i__969noyAM" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
# Yahoo
|
||||
|
||||
@@ -102,7 +102,7 @@ undo: function() {
|
||||
|
||||
[Dan Abramov](https://twitter.com/dan_abramov) working at Stampsy made a talk about React and Flux. It's a very good overview of the concepts at play.
|
||||
|
||||
<iframe src="//slides.com/danabramov/components-react-flux-wip/embed" width="650" height="315" scrolling="no" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
|
||||
<iframe src="//slides.com/danabramov/components-react-flux-wip/embed" width="100%" height="315" scrolling="no" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
|
||||
|
||||
|
||||
## React and Flux
|
||||
@@ -144,7 +144,7 @@ undo: function() {
|
||||
|
||||
Last but not least, Flux and React ideas are not limited to JavaScript inside of the browser. The iOS team at Facebook re-implemented Newsfeed using very similar patterns.
|
||||
|
||||
<iframe width="650" height="315" src="//www.youtube-nocookie.com/embed/XhXC4SKOGfQ" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="315" src="//www.youtube-nocookie.com/embed/XhXC4SKOGfQ" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
|
||||
## Random Tweet
|
||||
|
||||
@@ -14,11 +14,11 @@ Murilo Pereira ([mpereira](https://github.com/mpereira)) tussles with the topic
|
||||
|
||||
I ([steveluscher](https://github.com/steveluscher)) spoke at Manning Publications' “Powered By JavaScript” Strangeloop pre-conf in St. Louis. There, I proposed a new notation to talk about development complexity – Big-Coffee Notation ☕(n) – and spoke about the features of React that help keep our Big-Coffee from going quadratic, as our user interfaces get more complex.
|
||||
|
||||
<iframe width="560" height="315" src="//www.youtube-nocookie.com/embed/rI0GQc__0SM" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="315" src="//www.youtube-nocookie.com/embed/rI0GQc__0SM" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
James Pearce ([jamesgpearce](https://github.com/jamesgpearce)) carried Big-Coffee all the way to Raleigh, NC. At the _All Things Open_ conference, he spoke about some of the design decisions that went into React, particularly those that lend themselves to simpler, more reliable code.
|
||||
|
||||
<iframe width="560" height="315" src="//www.youtube-nocookie.com/embed/m2fuO2wl_3c" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="315" src="//www.youtube-nocookie.com/embed/m2fuO2wl_3c" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
## All About Isomorphism
|
||||
|
||||
@@ -38,7 +38,7 @@ Ryan Florence ([rpflorence](https://github.com/rpflorence])) and Michael Jackson
|
||||
|
||||
Jonathan Beebe ([somethingkindawierd](https://github.com/somethingkindawierd)) spoke about how he uses React to build tools that deliver hope to those trying to make the best of a bad situation. Watch his talk from this year's _Nodevember_ conference in Nashville
|
||||
|
||||
<iframe width="420" height="315" src="//www.youtube-nocookie.com/embed/uZgAq1CZ1N8" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="315" src="//www.youtube-nocookie.com/embed/uZgAq1CZ1N8" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
If you take a peek under the covers, you'll find that React powers [Carousel](https://blog.carousel.com/2014/11/introducing-carousel-for-web-ipad-and-android-tablet/), Dropbox's new photo and video gallery app.
|
||||
|
||||
@@ -48,7 +48,7 @@ We enjoyed a cinematic/narrative experience with this React-powered, interactive
|
||||
|
||||
Spend the next 60 seconds watching Daniel Woelfel ([dwwoelfel](https://github.com/dwwoelfel)) serialize a React app's state as a string, then deserialize it to produce a working UI. Read about how he uses this technique to [reproduce bugs](http://blog.circleci.com/local-state-global-concerns/) reported to him by his users.
|
||||
|
||||
<iframe width="420" height="315" src="//www.youtube-nocookie.com/embed/5yHFTN-_mOo" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="315" src="//www.youtube-nocookie.com/embed/5yHFTN-_mOo" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
## Community Components
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ It was a privilege to welcome the React community to Facebook HQ on January 28
|
||||
</p>
|
||||
</div>
|
||||
<div class="skinny-col">
|
||||
<iframe width="305" height="171" src="https://www.youtube-nocookie.com/embed/KVZ-P-ZI6W4" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="171" src="https://www.youtube-nocookie.com/embed/KVZ-P-ZI6W4" frameborder="0" allowfullscreen></iframe>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -28,7 +28,7 @@ It was a privilege to welcome the React community to Facebook HQ on January 28
|
||||
</p>
|
||||
</div>
|
||||
<div class="skinny-col">
|
||||
<iframe width="305" height="171" src="https://www.youtube-nocookie.com/embed/yaymfLj5tjA" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="171" src="https://www.youtube-nocookie.com/embed/yaymfLj5tjA" frameborder="0" allowfullscreen></iframe>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -40,7 +40,7 @@ It was a privilege to welcome the React community to Facebook HQ on January 28
|
||||
</p>
|
||||
</div>
|
||||
<div class="skinny-col">
|
||||
<iframe width="305" height="171" src="https://www.youtube-nocookie.com/embed/OZGgVxFxSIs" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="171" src="https://www.youtube-nocookie.com/embed/OZGgVxFxSIs" frameborder="0" allowfullscreen></iframe>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -52,7 +52,7 @@ It was a privilege to welcome the React community to Facebook HQ on January 28
|
||||
</p>
|
||||
</div>
|
||||
<div class="skinny-col">
|
||||
<iframe width="305" height="171" src="https://www.youtube-nocookie.com/embed/9sc8Pyc51uU" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="171" src="https://www.youtube-nocookie.com/embed/9sc8Pyc51uU" frameborder="0" allowfullscreen></iframe>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -64,7 +64,7 @@ It was a privilege to welcome the React community to Facebook HQ on January 28
|
||||
</p>
|
||||
</div>
|
||||
<div class="skinny-col">
|
||||
<iframe width="305" height="171" src="https://www.youtube-nocookie.com/embed/W2DgDNQZOwo" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="171" src="https://www.youtube-nocookie.com/embed/W2DgDNQZOwo" frameborder="0" allowfullscreen></iframe>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -76,7 +76,7 @@ It was a privilege to welcome the React community to Facebook HQ on January 28
|
||||
</p>
|
||||
</div>
|
||||
<div class="skinny-col">
|
||||
<iframe width="305" height="171" src="https://www.youtube-nocookie.com/embed/XZfvW1a8Xac" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="171" src="https://www.youtube-nocookie.com/embed/XZfvW1a8Xac" frameborder="0" allowfullscreen></iframe>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -88,7 +88,7 @@ It was a privilege to welcome the React community to Facebook HQ on January 28
|
||||
</p>
|
||||
</div>
|
||||
<div class="skinny-col">
|
||||
<iframe width="305" height="171" src="https://www.youtube-nocookie.com/embed/KtmjkCuV-EU" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="171" src="https://www.youtube-nocookie.com/embed/KtmjkCuV-EU" frameborder="0" allowfullscreen></iframe>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -100,7 +100,7 @@ It was a privilege to welcome the React community to Facebook HQ on January 28
|
||||
</p>
|
||||
</div>
|
||||
<div class="skinny-col">
|
||||
<iframe width="305" height="171" src="https://www.youtube-nocookie.com/embed/KYzlpRvWZ6c" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="171" src="https://www.youtube-nocookie.com/embed/KYzlpRvWZ6c" frameborder="0" allowfullscreen></iframe>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -112,7 +112,7 @@ It was a privilege to welcome the React community to Facebook HQ on January 28
|
||||
</p>
|
||||
</div>
|
||||
<div class="skinny-col">
|
||||
<iframe width="305" height="171" src="https://www.youtube-nocookie.com/embed/Sla-DkvmIHY" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="171" src="https://www.youtube-nocookie.com/embed/Sla-DkvmIHY" frameborder="0" allowfullscreen></iframe>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -124,7 +124,7 @@ It was a privilege to welcome the React community to Facebook HQ on January 28
|
||||
</p>
|
||||
</div>
|
||||
<div class="skinny-col">
|
||||
<iframe width="305" height="171" src="https://www.youtube-nocookie.com/embed/z5e7kWSHWTg" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="171" src="https://www.youtube-nocookie.com/embed/z5e7kWSHWTg" frameborder="0" allowfullscreen></iframe>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -136,7 +136,7 @@ It was a privilege to welcome the React community to Facebook HQ on January 28
|
||||
</p>
|
||||
</div>
|
||||
<div class="skinny-col">
|
||||
<iframe width="305" height="171" src="https://www.youtube-nocookie.com/embed/7rDsRXj9-cU" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="171" src="https://www.youtube-nocookie.com/embed/7rDsRXj9-cU" frameborder="0" allowfullscreen></iframe>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -148,7 +148,7 @@ It was a privilege to welcome the React community to Facebook HQ on January 28
|
||||
</p>
|
||||
</div>
|
||||
<div class="skinny-col">
|
||||
<iframe width="305" height="171" src="https://www.youtube-nocookie.com/embed/g0TD0efcwVg" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="171" src="https://www.youtube-nocookie.com/embed/g0TD0efcwVg" frameborder="0" allowfullscreen></iframe>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -160,7 +160,7 @@ It was a privilege to welcome the React community to Facebook HQ on January 28
|
||||
</p>
|
||||
</div>
|
||||
<div class="skinny-col">
|
||||
<iframe width="305" height="171" src="https://www.youtube-nocookie.com/embed/I7IdS-PbEgI" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="171" src="https://www.youtube-nocookie.com/embed/I7IdS-PbEgI" frameborder="0" allowfullscreen></iframe>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -171,7 +171,7 @@ It was a privilege to welcome the React community to Facebook HQ on January 28
|
||||
<strong>Jafar Husain</strong> told us a story about how Netflix was able to push React into places where the DOM could not go.
|
||||
</div>
|
||||
<div class="skinny-col">
|
||||
<iframe width="305" height="171" src="https://www.youtube-nocookie.com/embed/eNC0mRYGWgc" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="171" src="https://www.youtube-nocookie.com/embed/eNC0mRYGWgc" frameborder="0" allowfullscreen></iframe>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -182,7 +182,7 @@ It was a privilege to welcome the React community to Facebook HQ on January 28
|
||||
<strong>Zach Nation</strong> showed us how we can produce visualizations from over 45 million data points without breaking a sweat.
|
||||
</div>
|
||||
<div class="skinny-col">
|
||||
<iframe width="305" height="171" src="https://www.youtube-nocookie.com/embed/2ii1lEkIv1s" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="171" src="https://www.youtube-nocookie.com/embed/2ii1lEkIv1s" frameborder="0" allowfullscreen></iframe>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -193,7 +193,7 @@ It was a privilege to welcome the React community to Facebook HQ on January 28
|
||||
<strong>David Nolen</strong> gave us a view of React from a non-JavaScript perspective, challenging some common intuition along the way.
|
||||
</div>
|
||||
<div class="skinny-col">
|
||||
<iframe width="305" height="171" src="https://www.youtube-nocookie.com/embed/5hGHdETNteE" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="171" src="https://www.youtube-nocookie.com/embed/5hGHdETNteE" frameborder="0" allowfullscreen></iframe>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -204,7 +204,7 @@ It was a privilege to welcome the React community to Facebook HQ on January 28
|
||||
<strong>Bill Fisher</strong> coordinated a Flux panel together with <strong>Michael Ridgway</strong>, <strong>Spike Brehm</strong>, <strong>Andres Suarez</strong>, <strong>Jing Chen</strong>, <strong>Ian Obermiller</strong>, and <strong>Kyle Davis</strong>.
|
||||
</div>
|
||||
<div class="skinny-col">
|
||||
<iframe width="305" height="171" src="https://www.youtube-nocookie.com/embed/LTj4O7WJJ98" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="171" src="https://www.youtube-nocookie.com/embed/LTj4O7WJJ98" frameborder="0" allowfullscreen></iframe>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -215,7 +215,7 @@ It was a privilege to welcome the React community to Facebook HQ on January 28
|
||||
<strong>Bonnie Eisenman</strong> led us through the ‘adapter’ approach to inter-component communication taken by her team at Codecademy.
|
||||
</div>
|
||||
<div class="skinny-col">
|
||||
<iframe width="305" height="171" src="https://www.youtube-nocookie.com/embed/ZM6wXoFTY3o" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="171" src="https://www.youtube-nocookie.com/embed/ZM6wXoFTY3o" frameborder="0" allowfullscreen></iframe>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -226,7 +226,7 @@ It was a privilege to welcome the React community to Facebook HQ on January 28
|
||||
<strong>James Brantly</strong> demonstrated how we can reap the benefits of static typing using both Flow and TypeScript.
|
||||
</div>
|
||||
<div class="skinny-col">
|
||||
<iframe width="305" height="171" src="https://www.youtube-nocookie.com/embed/9PTa9-PPVAc" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="171" src="https://www.youtube-nocookie.com/embed/9PTa9-PPVAc" frameborder="0" allowfullscreen></iframe>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -237,7 +237,7 @@ It was a privilege to welcome the React community to Facebook HQ on January 28
|
||||
<strong>Tom Occhino</strong>, <strong>Ben Alpert</strong>, <strong>Lee Byron</strong>, <strong>Christopher Chedeau</strong>, <strong>Sebastian Markbåge</strong>, <strong>Jing Chen</strong>, and <strong>Dan Schafer</strong> closed the conference with a Q&A session.
|
||||
</div>
|
||||
<div class="skinny-col">
|
||||
<iframe width="305" height="171" src="https://www.youtube-nocookie.com/embed/EPpkboSKvPI" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="171" src="https://www.youtube-nocookie.com/embed/EPpkboSKvPI" frameborder="0" allowfullscreen></iframe>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -266,4 +266,4 @@ And, in case you missed a session, you can borrow **Michael Chan’s** [drawings
|
||||
|
||||
**All proceeds from React.js Conf 2015 were donated to the wonderful programs at [code.org](http://code.org)**. These programs aim to increase access to the field of computer science by underrepresented members of our community. Watch this video to learn more.
|
||||
|
||||
<iframe width="305" height="171" src="https://www.youtube-nocookie.com/embed/FC5FbmsH4fw" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="171" src="https://www.youtube-nocookie.com/embed/FC5FbmsH4fw" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
@@ -8,7 +8,7 @@ author: wincent
|
||||
|
||||
There's more to building an application than creating a user interface. Data fetching is still a tricky problem, especially as applications become more complicated. At [React.js Conf](http://conf.reactjs.com/) we announced two projects we've created at Facebook to make data fetching simple for developers, even as a product grows to include dozens of contributors and the application becomes as complex as Facebook itself.
|
||||
|
||||
<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/9sc8Pyc51uU" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="315" src="https://www.youtube-nocookie.com/embed/9sc8Pyc51uU" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
The two projects — Relay and GraphQL — have been in use in production at Facebook for some time, and we're excited to be bringing them to the world as open source in the future. In the meantime, we wanted to share some additional information about the projects here.
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ Interest in React has been exploding recently, so it's a good time to explore so
|
||||
|
||||
[Formidable Labs](https://github.com/FormidableLabs) and [Seattle JS](http://www.meetup.com/seattlejs/) recently hosted a series of React, Flux, and Flow workshops, and the first part is available to watch online:
|
||||
|
||||
<iframe width="650" height="300" src="//www.youtube-nocookie.com/embed/Pd6Ub7Ju2RM" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="300" src="//www.youtube-nocookie.com/embed/Pd6Ub7Ju2RM" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
[AEFlash](https://github.com/aearly) writes up [some best practices and tips](http://aeflash.com/2015-02/react-tips-and-best-practices.html) to help you avoid potential pitfalls when developing with React.
|
||||
|
||||
@@ -20,7 +20,7 @@ Black Mutt Media [takes us through their usage of React](http://blackmuttmedia.c
|
||||
|
||||
Our own [Sebastian Markbåge](https://github.com/sebmarkbage) was on the [Web Platform Podcast](http://thewebplatform.libsyn.com/31-building-with-reactjs) to have a chat about all aspects of React.
|
||||
|
||||
<iframe style="border: none" src="//html5-player.libsyn.com/embed/episode/id/3370114/height/75/width/200/theme/standard-mini/direction/no/autoplay/no/autonext/no/thumbnail/yes/preload/no/no_addthis/no/" height="26" width="650" scrolling="no" allowfullscreen="" webkitallowfullscreen="" mozallowfullscreen="" oallowfullscreen="" msallowfullscreen=""></iframe>
|
||||
<iframe style="border: none" src="//html5-player.libsyn.com/embed/episode/id/3370114/height/75/width/200/theme/standard-mini/direction/no/autoplay/no/autonext/no/thumbnail/yes/preload/no/no_addthis/no/" height="26" width="100%" scrolling="no" allowfullscreen="" webkitallowfullscreen="" mozallowfullscreen="" oallowfullscreen="" msallowfullscreen=""></iframe>
|
||||
|
||||
## Community Additions
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ We open sourced React Native last week and the community reception blew away all
|
||||
|
||||
**Give us 6 months**. At Facebook, we strive to only open-source projects that we are using in production. While the Android backend for React Native is starting to work (see video below at 37min), it hasn't been shipped to any users yet. There's a lot of work that goes into open-sourcing a project, and we want to do it right so that you have a great experience when using it.
|
||||
|
||||
<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/X6YbAKiLCLU?start=2220" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="315" src="https://www.youtube-nocookie.com/embed/X6YbAKiLCLU?start=2220" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
|
||||
## Ray Wenderlich - Property Finder
|
||||
@@ -92,4 +92,3 @@ Clay Allsopp wrote a post about [all the crazy things you could do with a JavaSc
|
||||
We've spent a lot of efforts getting the onboarding as easy as possible and we're really happy that people noticed. We still have a lot of work to do on documentation, stay tuned!
|
||||
|
||||
<blockquote class="twitter-tweet" lang="en"><p>Wow. Getting started with React Native might have been the smoothest experience I’ve ever had with a new developer product.</p>— Andreas Eldh (@eldh) <a href="https://twitter.com/eldh/status/581186172094980096">March 26, 2015</a></blockquote>
|
||||
|
||||
|
||||
@@ -19,4 +19,4 @@ You now have three ways to get React Native. You should chose the one you want b
|
||||
|
||||
If you want more details, I highly recommend this video that explains how Facebook mobile release process works and why it was setup this way.
|
||||
|
||||
<iframe width="650" height="300" src="https://www.youtube.com/embed/mOyoTUETmSM" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="300" src="https://www.youtube.com/embed/mOyoTUETmSM" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
@@ -8,39 +8,39 @@ Last month, the first React.js European conference took place in the city of Par
|
||||
|
||||
[Christopher Chedeau](https://github.com/vjeux) gave the opening keynote to the conference:
|
||||
|
||||
<iframe width="650" height="366" src="//www.youtube.com/embed/PAA9O4E1IM4" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="//www.youtube.com/embed/PAA9O4E1IM4" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
[Spencer Ahrens](https://github.com/sahrens) walks through building an advanced gestural UI leveraging the unique power of the React Native layout and animation systems to build a complex and fluid experience:
|
||||
|
||||
<iframe width="650" height="366" src="//www.youtube.com/embed/xDlfrcM6YBk" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="//www.youtube.com/embed/xDlfrcM6YBk" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
[Lee Byron](https://github.com/leebyron) explores GraphQL, its core principles, how it works, and what makes it a powerful tool:
|
||||
|
||||
<iframe width="650" height="366" src="//www.youtube.com/embed/WQLzZf34FJ8" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="//www.youtube.com/embed/WQLzZf34FJ8" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
[Joseph Savona](https://github.com/josephsavona) explores the problems Relay solves, its architecture and the query lifecycle, and how can you use Relay to build more scalable apps. There are examples of how Relay powers applications as complex as the Facebook News Feed:
|
||||
|
||||
<iframe width="650" height="366" src="//www.youtube.com/embed/IrgHurBjQbg" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="//www.youtube.com/embed/IrgHurBjQbg" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
[Nick Schrock](https://github.com/schrockn) and [Dan Schafer](https://github.com/dschafer) take a deeper dive into putting GraphQL to work. How can we build a GraphQL API to work with an existing REST API or server-side data model? What are best practices when building a GraphQL API, and how do they differ from traditional REST best practices? How does Facebook use GraphQL? Most importantly, what does a complete and coherent GraphQL API looks like, and how can we get started building one?
|
||||
|
||||
<iframe width="650" height="366" src="//www.youtube.com/embed/gY48GW87Feo" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="//www.youtube.com/embed/gY48GW87Feo" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
[Sebastian Markbåge](https://github.com/sebmarkbage) talks about why the DOM is flawed and how it is becoming a second-class citizen in the land of React apps:
|
||||
|
||||
<iframe width="650" height="366" src="//www.youtube.com/embed/Zemce4Y1Y-A" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="//www.youtube.com/embed/Zemce4Y1Y-A" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
[Sebastian McKenzie](https://github.com/sebmck) goes over how existing JSX build pipeline infrastructure can be further utilised to perform even more significant code transformations such as transpilation, optimisation, profiling and more, reducing bugs, making your code faster and you as a developer more productive and happy:
|
||||
|
||||
<iframe width="650" height="366" src="//www.youtube.com/embed/OFuDvqZmUrE" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="//www.youtube.com/embed/OFuDvqZmUrE" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
[Cheng Lou](https://github.com/chenglou) gives a talk on the past, the present and the future of animation, and the place React can potentially take in this:
|
||||
|
||||
<iframe width="650" height="366" src="//www.youtube.com/embed/1tavDv5hXpo" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="//www.youtube.com/embed/1tavDv5hXpo" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
And there was a Q&A session with the whole team covering a range of React topics:
|
||||
|
||||
<iframe width="650" height="366" src="//www.youtube.com/embed/CRJZBZ_-6hQ" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="//www.youtube.com/embed/CRJZBZ_-6hQ" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
And there were lots of great talks from the React community:
|
||||
|
||||
|
||||
@@ -237,7 +237,7 @@ Each of these changes will continue to work as before with a new warning until t
|
||||
|
||||
### Other improvements
|
||||
|
||||
- React now uses `loose-envify` instead of `envify` so it installs less transitive dependencies.
|
||||
- React now uses `loose-envify` instead of `envify` so it installs fewer transitive dependencies.
|
||||
<small>[@qerub](https://github.com/qerub) in [#6303](https://github.com/facebook/react/pull/6303)</small>
|
||||
|
||||
- Shallow renderer now exposes `getMountedInstance()`.
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
---
|
||||
title: "Introducing React's Error Code System"
|
||||
author: keyanzhang
|
||||
---
|
||||
|
||||
Building a better developer experience has been one of the things that React deeply cares about, and a crucial part of it is to detect anti-patterns/potential errors early and provide helpful error messages when things (may) go wrong. However, most of these only exist in development mode; in production, we avoid having extra expensive assertions and sending down full error messages in order to reduce the number of bytes sent over the wire.
|
||||
|
||||
Prior to this release, we stripped out error messages at build-time and this is why you might have seen this message in production:
|
||||
|
||||
> Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.
|
||||
|
||||
In order to make debugging in production easier, we're introducing an Error Code System in [15.2.0](https://github.com/facebook/react/releases/tag/v15.2.0). We developed a [gulp script](https://github.com/facebook/react/blob/master/scripts/error-codes/gulp-extract-errors.js) that collects all of our `invariant` error messages and folds them to a [JSON file](https://github.com/facebook/react/blob/master/scripts/error-codes/codes.json), and at build-time Babel uses the JSON to [rewrite](https://github.com/facebook/react/blob/master/scripts/error-codes/dev-expression-with-codes.js) our `invariant` calls in production to reference the corresponding error IDs. Now when things go wrong in production, the error that React throws will contain a URL with an error ID and relevant information. The URL will point you to a page in our documentation where the original error message gets reassembled.
|
||||
|
||||
While we hope you don't see errors often, you can see how it works [here](/react/docs/error-decoder.html?invariant=109&args[]=Foo). This is what the same error from above will look like:
|
||||
|
||||
> Minified React error #109; visit https://facebook.github.io/react/docs/error-decoder.html?invariant=109&args[]=Foo for the full message or use the non-minified dev environment for full errors and additional helpful warnings.
|
||||
|
||||
We do this so that the developer experience is as good as possible, while also keeping the production bundle size as small as possible. This feature shouldn't require any changes on your side — use the `min.js` files in production or bundle your application code with `process.env.NODE_ENV === 'production'` and you should be good to go!
|
||||
614
docs/_posts/2016-07-13-mixins-considered-harmful.md
Normal file
614
docs/_posts/2016-07-13-mixins-considered-harmful.md
Normal file
@@ -0,0 +1,614 @@
|
||||
---
|
||||
title: "Mixins Considered Harmful"
|
||||
author: gaearon
|
||||
---
|
||||
|
||||
“How do I share the code between several components?” is one of the first questions that people ask when they learn React. Our answer has always been to use component composition for code reuse. You can define a component and use it in several other components.
|
||||
|
||||
It is not always obvious how a certain pattern can be solved with composition. React is influenced by functional programming but it came into the field that was dominated by object-oriented libraries. It was hard for engineers both inside and outside of Facebook to give up on the patterns they were used to.
|
||||
|
||||
To ease the initial adoption and learning, we included certain escape hatches into React. The mixin system was one of those escape hatches, and its goal was to give you a way to reuse code between components when you aren’t sure how to solve the same problem with composition.
|
||||
|
||||
Three years passed since React was released. The landscape has changed. Multiple view libraries now adopt a component model similar to React. Using composition over inheritance to build declarative user interfaces is no longer a novelty. We are also more confident in the React component model, and we have seen many creative uses of it both internally and in the community.
|
||||
|
||||
In this post, we will consider the problems commonly caused by mixins. Then we will suggest several alternative patterns for the same use cases. We have found those patterns to scale better with the complexity of the codebase than mixins.
|
||||
|
||||
## Why Mixins are Broken
|
||||
|
||||
At Facebook, React usage has grown from a few components to thousands of them. This gives us a window into how people use React. Thanks to declarative rendering and top-down data flow, many teams were able to fix a bunch of bugs while shipping new features as they adopted React.
|
||||
|
||||
However it’s inevitable that some of our code using React gradually became incomprehensible. Occasionally, the React team would see groups of components in different projects that people were afraid to touch. These components were too easy to break accidentally, were confusing to new developers, and eventually became just as confusing to the people who wrote them in the first place. Much of this confusion was caused by mixins. At the time, I wasn’t working at Facebook but I came to the [same conclusions](https://medium.com/@dan_abramov/mixins-are-dead-long-live-higher-order-components-94a0d2f9e750) after writing my fair share of terrible mixins.
|
||||
|
||||
This doesn’t mean that mixins themselves are bad. People successfully employ them in different languages and paradigms, including some functional languages. At Facebook, we extensively use traits in Hack which are fairly similar to mixins. Nevertheless, we think that mixins are unnecessary and problematic in React codebases. Here’s why.
|
||||
|
||||
### Mixins introduce implicit dependencies
|
||||
|
||||
Sometimes a component relies on a certain method defined in the mixin, such as `getClassName()`. Sometimes it’s the other way around, and mixin calls a method like `renderHeader()` on the component. JavaScript is a dynamic language so it’s hard to enforce or document these dependencies.
|
||||
|
||||
Mixins break the common and usually safe assumption that you can rename a state key or a method by searching for its occurrences in the component file. You might write a stateful component and then your coworker might add a mixin that reads this state. In a few months, you might want to move that state up to the parent component so it can be shared with a sibling. Will you remember to update the mixin to read a prop instead? What if, by now, other components also use this mixin?
|
||||
|
||||
These implicit dependencies make it hard for new team members to contribute to a codebase. A component’s `render()` method might reference some method that isn’t defined on the class. Is it safe to remove? Perhaps it’s defined in one of the mixins. But which one of them? You need to scroll up to the mixin list, open each of those files, and look for this method. Worse, mixins can specify their own mixins, so the search can be deep.
|
||||
|
||||
Often, mixins come to depend on other mixins, and removing one of them breaks the other. In these situations it is very tricky to tell how the data flows in and out of mixins, and what their dependency graph looks like. Unlike components, mixins don’t form a hierarchy: they are flattened and operate in the same namespace.
|
||||
|
||||
### Mixins cause name clashes
|
||||
|
||||
There is no guarantee that two particular mixins can be used together. For example, if `FluxListenerMixin` defines `handleChange()` and `WindowSizeMixin` defines `handleChange()`, you can’t use them together. You also can’t define a method with this name on your own component.
|
||||
|
||||
It’s not a big deal if you control the mixin code. When you have a conflict, you can rename that method on one of the mixins. However it’s tricky because some components or other mixins may already be calling this method directly, and you need to find and fix those calls as well.
|
||||
|
||||
If you have a name conflict with a mixin from a third party package, you can’t just rename a method on it. Instead, you have to use awkward method names on your component to avoid clashes.
|
||||
|
||||
The situation is no better for mixin authors. Even adding a new method to a mixin is always a potentially breaking change because a method with the same name might already exist on some of the components using it, either directly or through another mixin. Once written, mixins are hard to remove or change. Bad ideas don’t get refactored away because refactoring is too risky.
|
||||
|
||||
### Mixins cause snowballing complexity
|
||||
|
||||
Even when mixins start out simple, they tend to become complex over time. The example below is based on a real scenario I’ve seen play out in a codebase.
|
||||
|
||||
A component needs some state to track mouse hover. To keep this logic reusable, you might extract `handleMouseEnter()`, `handleMouseLeave()` and `isHovering()` into a `HoverMixin`. Next, somebody needs to implement a tooltip. They don’t want to duplicate the logic in `HoverMixin` so they create a `TooltipMixin` that uses `HoverMixin`. `TooltipMixin` reads `isHovering()` provided by `HoverMixin` in its `componentDidUpdate()` and either shows or hides the tooltip.
|
||||
|
||||
A few months later, somebody wants to make the tooltip direction configurable. In an effort to avoid code duplication, they add support for a new optional method called `getTooltipOptions()` to `TooltipMixin`. By this time, components that show popovers also use `HoverMixin`. However popovers need a different hover delay. To solve this, somebody adds support for an optional `getHoverOptions()` method and implements it in `TooltipMixin`. Those mixins are now tightly coupled.
|
||||
|
||||
This is fine while there are no new requirements. However this solution doesn’t scale well. What if you want to support displaying multiple tooltips in a single component? You can’t define the same mixin twice in a component. What if the tooltips need to be displayed automatically in a guided tour instead of on hover? Good luck decoupling `TooltipMixin` from `HoverMixin`. What if you need to support the case where the hover area and the tooltip anchor are located in different components? You can’t easily hoist the state used by mixin up into the parent component. Unlike components, mixins don’t lend themselves naturally to such changes.
|
||||
|
||||
Every new requirement makes the mixins harder to understand. Components using the same mixin become increasingly coupled with time. Any new capability gets added to all of the components using that mixin. There is no way to split a “simpler” part of the mixin without either duplicating the code or introducing more dependencies and indirection between mixins. Gradually, the encapsulation boundaries erode, and since it’s hard to change or remove the existing mixins, they keep getting more abstract until nobody understands how they work.
|
||||
|
||||
These are the same problems we faced building apps before React. We found that they are solved by declarative rendering, top-down data flow, and encapsulated components. At Facebook, we have been migrating our code to use alternative patterns to mixins, and we are generally happy with the results. You can read about those patterns below.
|
||||
|
||||
## Migrating from Mixins
|
||||
|
||||
Let’s make it clear that mixins are not technically deprecated. If you use `React.createClass()`, you may keep using them. We only say that they didn’t work well for us, and so we won’t recommend using them in the future.
|
||||
|
||||
Every section below corresponds to a mixin usage pattern that we found in the Facebook codebase. For each of them, we describe the problem and a solution that we think works better than mixins. The examples are written in ES5 but once you don’t need mixins, you can switch to ES6 classes if you’d like.
|
||||
|
||||
We hope that you find this list helpful. Please let us know if we missed important use cases so we can either amend the list or be proven wrong!
|
||||
|
||||
### Performance Optimizations
|
||||
|
||||
One of the most commonly used mixins is [`PureRenderMixin`](/react/docs/pure-render-mixin.html). You might be using it in some components to [prevent unnecessary re-renders](/react/docs/advanced-performance.html#shouldcomponentupdate-in-action) when the props and state are shallowly equal to the previous props and state:
|
||||
|
||||
```javascript
|
||||
var PureRenderMixin = require('react-addons-pure-render-mixin');
|
||||
|
||||
var Button = React.createClass({
|
||||
mixins: [PureRenderMixin],
|
||||
|
||||
// ...
|
||||
|
||||
});
|
||||
```
|
||||
|
||||
#### Solution
|
||||
|
||||
To express the same without mixins, you can use the [`shallowCompare`](/react/docs/shallow-compare.html) function directly instead:
|
||||
|
||||
```js
|
||||
var shallowCompare = require('react-addons-shallow-compare');
|
||||
|
||||
var Button = React.createClass({
|
||||
shouldComponentUpdate: function(nextProps, nextState) {
|
||||
return shallowCompare(this, nextProps, nextState);
|
||||
},
|
||||
|
||||
// ...
|
||||
|
||||
});
|
||||
```
|
||||
|
||||
If you use a custom mixin implementing a `shouldComponentUpdate` function with different algorithm, we suggest exporting just that single function from a module and calling it directly from your components.
|
||||
|
||||
We understand that more typing can be annoying. For the most common case, we plan to [introduce a new base class](https://github.com/facebook/react/pull/7195) called `React.PureComponent` in the next minor release. It uses the same shallow comparison as `PureRenderMixin` does today.
|
||||
|
||||
### Subscriptions and Side Effects
|
||||
|
||||
The second most common type of mixins that we encountered are mixins that subscribe a React component to a third-party data source. Whether this data source is a Flux Store, an Rx Observable, or something else, the pattern is very similar: the subscription is created in `componentDidMount`, destroyed in `componentWillUnmount`, and the change handler calls `this.setState()`.
|
||||
|
||||
```javascript
|
||||
var SubscriptionMixin = {
|
||||
getInitialState: function() {
|
||||
return {
|
||||
comments: DataSource.getComments()
|
||||
};
|
||||
},
|
||||
|
||||
componentDidMount: function() {
|
||||
DataSource.addChangeListener(this.handleChange);
|
||||
},
|
||||
|
||||
componentWillUnmount: function() {
|
||||
DataSource.removeChangeListener(this.handleChange);
|
||||
},
|
||||
|
||||
handleChange: function() {
|
||||
this.setState({
|
||||
comments: DataSource.getComments()
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
var CommentList = React.createClass({
|
||||
mixins: [SubscriptionMixin],
|
||||
|
||||
render: function() {
|
||||
// Reading comments from state managed by mixin.
|
||||
var comments = this.state.comments;
|
||||
return (
|
||||
<div>
|
||||
{comments.map(function(comment) {
|
||||
return <Comment comment={comment} key={comment.id} />
|
||||
})}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = CommentList;
|
||||
```
|
||||
|
||||
#### Solution
|
||||
|
||||
If there is just one component subscribed to this data source, it is fine to embed the subscription logic right into the component. Avoid premature abstractions.
|
||||
|
||||
If several components used this mixin to subscribe to a data source, a nice way to avoid repetition is to use a pattern called [“higher-order components”](https://medium.com/@dan_abramov/mixins-are-dead-long-live-higher-order-components-94a0d2f9e750). It can sound intimidating so we will take a closer look at how this pattern naturally emerges from the component model.
|
||||
|
||||
#### Higher-Order Components Explained
|
||||
|
||||
Let’s forget about React for a second. Consider these two functions that add and multiply numbers, logging the results as they do that:
|
||||
|
||||
```js
|
||||
function addAndLog(x, y) {
|
||||
var result = x + y;
|
||||
console.log('result:', result);
|
||||
return result;
|
||||
}
|
||||
|
||||
function multiplyAndLog(x, y) {
|
||||
var result = x * y;
|
||||
console.log('result:', result);
|
||||
return result;
|
||||
}
|
||||
```
|
||||
|
||||
These two functions are not very useful but they help us demonstrate a pattern that we can later apply to components.
|
||||
|
||||
Let’s say that we want to extract the logging logic out of these functions without changing their signatures. How can we do this? An elegant solution is to write a [higher-order function](https://en.wikipedia.org/wiki/Higher-order_function), that is, a function that takes a function as an argument and returns a function.
|
||||
|
||||
Again, it sounds more intimidating than it really is:
|
||||
|
||||
```js
|
||||
function withLogging(wrappedFunction) {
|
||||
// Return a function with the same API...
|
||||
return function(x, y) {
|
||||
// ... that calls the original function
|
||||
var result = wrappedFunction(x, y);
|
||||
// ... but also logs its result!
|
||||
console.log('result:', result);
|
||||
return result;
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
The `withLogging` higher-order function lets us write `add` and `multiply` without the logging statements, and later wrap them to get `addAndLog` and `multiplyAndLog` with exactly the same signatures as before:
|
||||
|
||||
```js
|
||||
function add(x, y) {
|
||||
return x + y;
|
||||
}
|
||||
|
||||
function multiply(x, y) {
|
||||
return x * y;
|
||||
}
|
||||
|
||||
function withLogging(wrappedFunction) {
|
||||
return function(x, y) {
|
||||
var result = wrappedFunction(x, y);
|
||||
console.log('result:', result);
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
// Equivalent to writing addAndLog by hand:
|
||||
var addAndLog = withLogging(add);
|
||||
|
||||
// Equivalent to writing multiplyAndLog by hand:
|
||||
var multiplyAndLog = withLogging(multiply);
|
||||
```
|
||||
|
||||
Higher-order components are a very similar pattern, but applied to components in React. We will apply this transformation from mixins in two steps.
|
||||
|
||||
As a first step, we will split our `CommentList` component in two, a child and a parent. The child will be only concerned with rendering the comments. The parent will set up the subscription and pass the up-to-date data to the child via props.
|
||||
|
||||
```js
|
||||
// This is a child component.
|
||||
// It only renders the comments it receives as props.
|
||||
var CommentList = React.createClass({
|
||||
render: function() {
|
||||
// Note: now reading from props rather than state.
|
||||
var comments = this.props.comments;
|
||||
return (
|
||||
<div>
|
||||
{comments.map(function(comment) {
|
||||
return <Comment comment={comment} key={comment.id} />
|
||||
})}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
});
|
||||
|
||||
// This is a parent component.
|
||||
// It subscribes to the data source and renders <CommentList />.
|
||||
var CommentListWithSubscription = React.createClass({
|
||||
getInitialState: function() {
|
||||
return {
|
||||
comments: DataSource.getComments()
|
||||
};
|
||||
},
|
||||
|
||||
componentDidMount: function() {
|
||||
DataSource.addChangeListener(this.handleChange);
|
||||
},
|
||||
|
||||
componentWillUnmount: function() {
|
||||
DataSource.removeChangeListener(this.handleChange);
|
||||
},
|
||||
|
||||
handleChange: function() {
|
||||
this.setState({
|
||||
comments: DataSource.getComments()
|
||||
});
|
||||
},
|
||||
|
||||
render: function() {
|
||||
// We pass the current state as props to CommentList.
|
||||
return <CommentList comments={this.state.comments} />;
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = CommentListWithSubscription;
|
||||
```
|
||||
|
||||
There is just one final step left to do.
|
||||
|
||||
Remember how we made `withLogging()` take a function and return another function wrapping it? We can apply a similar pattern to React components.
|
||||
|
||||
We will write a new function called `withSubscription(WrappedComponent)`. Its argument could be any React component. We will pass `CommentList` as `WrappedComponent`, but we could also apply `withSubscription()` to any other component in our codebase.
|
||||
|
||||
This function would return another component. The returned component would manage the subscription and render `<WrappedComponent />` with the current data.
|
||||
|
||||
We call this pattern a “higher-order component”.
|
||||
|
||||
The composition happens at React rendering level rather than with a direct function call. This is why it doesn’t matter whether the wrapped component is defined with `createClass()`, as an ES6 class or a function. If `WrappedComponent` is a React component, the component created by `withSubscription()` can render it.
|
||||
|
||||
```js
|
||||
// This function takes a component...
|
||||
function withSubscription(WrappedComponent) {
|
||||
// ...and returns another component...
|
||||
return React.createClass({
|
||||
getInitialState: function() {
|
||||
return {
|
||||
comments: DataSource.getComments()
|
||||
};
|
||||
},
|
||||
|
||||
componentDidMount: function() {
|
||||
// ... that takes care of the subscription...
|
||||
DataSource.addChangeListener(this.handleChange);
|
||||
},
|
||||
|
||||
componentWillUnmount: function() {
|
||||
DataSource.removeChangeListener(this.handleChange);
|
||||
},
|
||||
|
||||
handleChange: function() {
|
||||
this.setState({
|
||||
comments: DataSource.getComments()
|
||||
});
|
||||
},
|
||||
|
||||
render: function() {
|
||||
// ... and renders the wrapped component with the fresh data!
|
||||
return <WrappedComponent comments={this.state.comments} />;
|
||||
}
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
Now we can declare `CommentListWithSubscription` by applying `withSubscription` to `CommentList`:
|
||||
|
||||
```js
|
||||
var CommentList = React.createClass({
|
||||
render: function() {
|
||||
var comments = this.props.comments;
|
||||
return (
|
||||
<div>
|
||||
{comments.map(function(comment) {
|
||||
return <Comment comment={comment} key={comment.id} />
|
||||
})}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
});
|
||||
|
||||
// withSubscription() returns a new component that
|
||||
// is subscribed to the data source and renders
|
||||
// <CommentList /> with up-to-date data.
|
||||
var CommentListWithSubscription = withSubscription(CommentList);
|
||||
|
||||
// The rest of the app is interested in the subscribed component
|
||||
// so we export it instead of the original unwrapped CommentList.
|
||||
module.exports = CommentListWithSubscription;
|
||||
```
|
||||
|
||||
#### Solution, Revisited
|
||||
|
||||
Now that we understand higher-order components better, let’s take another look at the complete solution that doesn’t involve mixins. There are a few minor changes that are annotated with inline comments:
|
||||
|
||||
```js
|
||||
function withSubscription(WrappedComponent) {
|
||||
return React.createClass({
|
||||
getInitialState: function() {
|
||||
return {
|
||||
comments: DataSource.getComments()
|
||||
};
|
||||
},
|
||||
|
||||
componentDidMount: function() {
|
||||
DataSource.addChangeListener(this.handleChange);
|
||||
},
|
||||
|
||||
componentWillUnmount: function() {
|
||||
DataSource.removeChangeListener(this.handleChange);
|
||||
},
|
||||
|
||||
handleChange: function() {
|
||||
this.setState({
|
||||
comments: DataSource.getComments()
|
||||
});
|
||||
},
|
||||
|
||||
render: function() {
|
||||
// Use JSX spread syntax to pass all props and state down automatically.
|
||||
return <WrappedComponent {...this.props} {...this.state} />;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Optional change: convert CommentList to a functional component
|
||||
// because it doesn't use lifecycle hooks or state.
|
||||
function CommentList(props) {
|
||||
var comments = props.comments;
|
||||
return (
|
||||
<div>
|
||||
{comments.map(function(comment) {
|
||||
return <Comment comment={comment} key={comment.id} />
|
||||
})}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
// Instead of declaring CommentListWithSubscription,
|
||||
// we export the wrapped component right away.
|
||||
module.exports = withSubscription(CommentList);
|
||||
```
|
||||
|
||||
Higher-order components are a powerful pattern. You can pass additional arguments to them if you want to further customize their behavior. After all, they are not even a feature of React. They are just functions that receive components and return components that wrap them.
|
||||
|
||||
Like any solution, higher-order components have their own pitfalls. For example, if you heavily use [refs](/react/docs/more-about-refs.html), you might notice that wrapping something into a higher-order component changes the ref to point to the wrapping component. In practice we discourage using refs for component communication so we don’t think it’s a big issue. In the future, we might consider adding [ref forwarding](https://github.com/facebook/react/issues/4213) to React to solve this annoyance.
|
||||
|
||||
### Rendering Logic
|
||||
|
||||
The next most common use case for mixins that we discovered in our codebase is sharing rendering logic between components.
|
||||
|
||||
Here is a typical example of this pattern:
|
||||
|
||||
```js
|
||||
var RowMixin = {
|
||||
// Called by components from render()
|
||||
renderHeader: function() {
|
||||
return (
|
||||
<div className='row-header'>
|
||||
<h1>
|
||||
{this.getHeaderText() /* Defined by components */}
|
||||
</h1>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
var UserRow = React.createClass({
|
||||
mixins: [RowMixin],
|
||||
|
||||
// Called by RowMixin.renderHeader()
|
||||
getHeaderText: function() {
|
||||
return this.props.user.fullName;
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return (
|
||||
<div>
|
||||
{this.renderHeader() /* Defined by RowMixin */}
|
||||
<h2>{this.props.user.biography}</h2>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
Multiple components may be sharing `RowMixin` to render the header, and each of them would need to define `getHeaderText()`.
|
||||
|
||||
#### Solution
|
||||
|
||||
If you see rendering logic inside a mixin, it’s time to extract a component!
|
||||
|
||||
Instead of `RowMixin`, we will define a `<Row>` component. We will also replace the convention of defining a `getHeaderText()` method with the standard mechanism of top-data flow in React: passing props.
|
||||
|
||||
Finally, since neither of those components currently need lifecycle hooks or state, we can declare them as simple functions:
|
||||
|
||||
```js
|
||||
function RowHeader(props) {
|
||||
return (
|
||||
<div className='row-header'>
|
||||
<h1>{props.text}</h1>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function UserRow(props) {
|
||||
return (
|
||||
<div>
|
||||
<RowHeader text={props.user.fullName} />
|
||||
<h2>{props.user.biography}</h2>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
Props keep component dependencies explicit, easy to replace, and enforceable with tools like [Flow](https://flowtype.org/) and [TypeScript](https://www.typescriptlang.org/).
|
||||
|
||||
> **Note:**
|
||||
>
|
||||
> Defining components as functions is not required. There is also nothing wrong with using lifecycle hooks and state—they are first-class React features. We use functional components in this example because they are easier to read and we didn’t need those extra features, but classes would work just as fine.
|
||||
|
||||
### Context
|
||||
|
||||
Another group of mixins we discovered were helpers for providing and consuming [React context](/react/docs/context.html). Context is an experimental unstable feature, has [certain issues](https://github.com/facebook/react/issues/2517), and will likely change its API in the future. We don’t recommend using it unless you’re confident there is no other way of solving your problem.
|
||||
|
||||
Nevertheless, if you already use context today, you might have been hiding its usage with mixins like this:
|
||||
|
||||
```js
|
||||
var RouterMixin = {
|
||||
contextTypes: {
|
||||
router: React.PropTypes.object.isRequired
|
||||
},
|
||||
|
||||
// The mixin provides a method so that components
|
||||
// don't have to use the context API directly.
|
||||
push: function(path) {
|
||||
this.context.router.push(path)
|
||||
}
|
||||
};
|
||||
|
||||
var Link = React.createClass({
|
||||
mixins: [RouterMixin],
|
||||
|
||||
handleClick: function(e) {
|
||||
e.stopPropagation();
|
||||
|
||||
// This method is defined in RouterMixin.
|
||||
this.push(this.props.to);
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return (
|
||||
<a onClick={this.handleClick}>
|
||||
{this.props.children}
|
||||
</a>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = Link;
|
||||
```
|
||||
|
||||
#### Solution
|
||||
|
||||
We agree that hiding context usage from consuming components is a good idea until the context API stabilizes. However, we recommend using higher-order components instead of mixins for this.
|
||||
|
||||
Let the wrapping component grab something from the context, and pass it down with props to the wrapped component:
|
||||
|
||||
```js
|
||||
function withRouter(WrappedComponent) {
|
||||
return React.createClass({
|
||||
contextTypes: {
|
||||
router: React.PropTypes.object.isRequired
|
||||
},
|
||||
|
||||
render: function() {
|
||||
// The wrapper component reads something from the context
|
||||
// and passes it down as a prop to the wrapped component.
|
||||
var router = this.context.router;
|
||||
return <WrappedComponent {...this.props} router={router} />;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
var Link = React.createClass({
|
||||
handleClick: function(e) {
|
||||
e.stopPropagation();
|
||||
|
||||
// The wrapped component uses props instead of context.
|
||||
this.props.router.push(this.props.to);
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return (
|
||||
<a onClick={this.handleClick}>
|
||||
{this.props.children}
|
||||
</a>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
// Don't forget to wrap the component!
|
||||
module.exports = withRouter(Link);
|
||||
```
|
||||
|
||||
If you’re using a third party library that only provides a mixin, we encourage you to file an issue with them linking to this post so that they can provide a higher-order component instead. In the meantime, you can create a higher-order component around it yourself in exactly the same way.
|
||||
|
||||
### Utility Methods
|
||||
|
||||
Sometimes, mixins are used solely to share utility functions between components:
|
||||
|
||||
```js
|
||||
var ColorMixin = {
|
||||
getLuminance(color) {
|
||||
var c = parseInt(color, 16);
|
||||
var r = (c & 0xFF0000) >> 16;
|
||||
var g = (c & 0x00FF00) >> 8;
|
||||
var b = (c & 0x0000FF);
|
||||
return (0.299 * r + 0.587 * g + 0.114 * b);
|
||||
}
|
||||
};
|
||||
|
||||
var Button = React.createClass({
|
||||
mixins: [ColorMixin],
|
||||
|
||||
render: function() {
|
||||
var theme = this.getLuminance(this.props.color) > 160 ? 'dark' : 'light';
|
||||
return (
|
||||
<div className={theme}>
|
||||
{this.props.children}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
#### Solution
|
||||
|
||||
Put utility functions into regular JavaScript modules and import them. This also makes it easier to test them or use them outside of your components:
|
||||
|
||||
```js
|
||||
var getLuminance = require('../utils/getLuminance');
|
||||
|
||||
var Button = React.createClass({
|
||||
render: function() {
|
||||
var theme = getLuminance(this.props.color) > 160 ? 'dark' : 'light';
|
||||
return (
|
||||
<div className={theme}>
|
||||
{this.props.children}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### Other Use Cases
|
||||
|
||||
Sometimes people use mixins to selectively add logging to lifecycle hooks in some components. In the future, we intend to provide an [official DevTools API](https://github.com/facebook/react/issues/5306) that would let you implement something similar without touching the components. However it’s still very much a work in progress. If you heavily depend on logging mixins for debugging, you might want to keep using those mixins for a little longer.
|
||||
|
||||
If you can’t accomplish something with a component, a higher-order component, or a utility module, it could be mean that React should provide this out of the box. [File an issue](https://github.com/facebook/react/issues/new) to tell us about your use case for mixins, and we’ll help you consider alternatives or perhaps implement your feature request.
|
||||
|
||||
Mixins are not deprecated in the traditional sense. You can keep using them with `React.createClass()`, as we won’t be changing it further. Eventually, as ES6 classes gain more adoption and their usability problems in React are solved, we might split `React.createClass()` into a separate package because most people wouldn’t need it. Even in that case, your old mixins would keep working.
|
||||
|
||||
We believe that the alternatives above are better for the vast majority of cases, and we invite you to try writing React apps without using mixins.
|
||||
165
docs/_posts/2016-07-22-create-apps-with-no-configuration.md
Normal file
165
docs/_posts/2016-07-22-create-apps-with-no-configuration.md
Normal file
@@ -0,0 +1,165 @@
|
||||
---
|
||||
title: "Create Apps with No Configuration"
|
||||
author: gaearon
|
||||
---
|
||||
|
||||
**[Create React App](https://github.com/facebookincubator/create-react-app)** is a new officially supported way to create single-page React applications. It offers a modern build setup with no configuration.
|
||||
|
||||
## Getting Started
|
||||
|
||||
### Installation
|
||||
|
||||
First, install the global package:
|
||||
|
||||
```sh
|
||||
npm install -g create-react-app
|
||||
```
|
||||
|
||||
Node.js 4.x or higher is required.
|
||||
|
||||
### Creating an App
|
||||
|
||||
Now you can use it to create a new app:
|
||||
|
||||
```sh
|
||||
create-react-app hello-world
|
||||
```
|
||||
|
||||
This will take a while as npm installs the transitive dependencies, but once it’s done, you will see a list of commands you can run in the created folder:
|
||||
|
||||

|
||||
|
||||
### Starting the Server
|
||||
|
||||
Run `npm start` to launch the development server. The browser will open automatically with the created app’s URL.
|
||||
|
||||

|
||||
|
||||
Create React App uses both Webpack and Babel under the hood.
|
||||
The console output is tuned to be minimal to help you focus on the problems:
|
||||
|
||||

|
||||
|
||||
ESLint is also integrated so lint warnings are displayed right in the console:
|
||||
|
||||

|
||||
|
||||
We only picked a small subset of lint rules that often lead to bugs.
|
||||
|
||||
### Building for Production
|
||||
|
||||
To build an optimized bundle, run `npm run build`:
|
||||
|
||||

|
||||
|
||||
It is minified, correctly envified, and the assets include content hashes for caching.
|
||||
|
||||
### One Dependency
|
||||
|
||||
Your `package.json` contains only a single build dependency and a few scripts:
|
||||
|
||||
```js
|
||||
{
|
||||
"name": "hello-world",
|
||||
"dependencies": {
|
||||
"react": "^15.2.1",
|
||||
"react-dom": "^15.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"react-scripts": "0.1.0"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"eject": "react-scripts eject"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
We take care of updating Babel, ESLint, and Webpack to stable compatible versions so you can update a single dependency to get them all.
|
||||
|
||||
### Zero Configuration
|
||||
|
||||
It is worth repeating: there are no configuration files or complicated folder structures. The tool only generates the files you need to build your app.
|
||||
|
||||
```
|
||||
hello-world/
|
||||
README.md
|
||||
index.html
|
||||
favicon.ico
|
||||
node_modules/
|
||||
package.json
|
||||
src/
|
||||
App.css
|
||||
App.js
|
||||
index.css
|
||||
index.js
|
||||
logo.svg
|
||||
```
|
||||
|
||||
All the build settings are preconfigured and can’t be changed. Some features, such as testing, are currently missing. This is an intentional limitation, and we recognize it might not work for everybody. And this brings us to the last point.
|
||||
|
||||
### No Lock-In
|
||||
|
||||
We first saw this feature in [Enclave](https://github.com/eanplatter/enclave), and we loved it. We talked to [Ean](https://twitter.com/EanPlatter), and he was excited to collaborate with us. He already sent a few pull requests!
|
||||
|
||||
“Ejecting” lets you leave the comfort of Create React App setup at any time. You run a single command, and all the build dependencies, configs, and scripts are moved right into your project. At this point you can customize everything you want, but effectively you are forking our configuration and going your own way. If you’re experienced with build tooling and prefer to fine-tune everything to your taste, this lets you use Create React App as a boilerplate generator.
|
||||
|
||||
We expect that at early stages, many people will “eject” for one reason or another, but as we learn from them, we will make the default setup more and more compelling while still providing no configuration.
|
||||
|
||||
## Try It Out!
|
||||
|
||||
You can find [**Create React App**](https://github.com/facebookincubator/create-react-app) with additional instructions on GitHub.
|
||||
|
||||
This is an experiment, and only time will tell if it becomes a popular way of creating and building React apps, or fades into obscurity.
|
||||
|
||||
We welcome you to participate in this experiment. Help us build the React tooling that more people can use. We are always [open to feedback](https://github.com/facebookincubator/create-react-app/issues/11).
|
||||
|
||||
## The Backstory
|
||||
|
||||
React was one of the first libraries to embrace transpiling JavaScript. As a result, even though you can [learn React without any tooling](https://github.com/facebook/react/blob/3fd582643ef3d222a00a0c756292c15b88f9f83c/examples/basic-jsx/index.html), the React ecosystem has commonly become associated with an overwhelming explosion of tools.
|
||||
|
||||
Eric Clemmons called this phenomenon the “[JavaScript Fatigue](https://medium.com/@ericclemmons/javascript-fatigue-48d4011b6fc4)”:
|
||||
|
||||
>Ultimately, the problem is that by choosing React (and inherently JSX), you’ve unwittingly opted into a confusing nest of build tools, boilerplate, linters, & time-sinks to deal with before you ever get to create anything.
|
||||
|
||||
It is tempting to write code in ES2015 and JSX. It is sensible to use a bundler to keep the codebase modular, and a linter to catch the common mistakes. It is nice to have a development server with fast rebuilds, and a command to produce optimized bundles for production.
|
||||
|
||||
Combining these tools requires some experience with each of them. Even so, it is far too easy to get dragged into fighting small incompatibilities, unsatisfied peerDependencies, and illegible configuration files.
|
||||
|
||||
Many of those tools are plugin platforms and don’t directly acknowledge each other’s existence. They leave it up to the users to wire them together. The tools mature and change independently, and tutorials quickly get out of date.
|
||||
|
||||
<blockquote class="twitter-tweet" data-lang="en"><p lang="en" dir="ltr">Marc was almost ready to implement his "hello world" React app <a href="https://t.co/ptdg4yteF1">pic.twitter.com/ptdg4yteF1</a></p>— Thomas Fuchs (@thomasfuchs) <a href="https://twitter.com/thomasfuchs/status/708675139253174273">March 12, 2016</a></blockquote>
|
||||
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
|
||||
|
||||
This doesn’t mean those tools aren’t great. To many of us, they have become indispensable, and we very much appreciate the effort of their maintainers. They already have too much on their plates to worry about the state of the React ecosystem.
|
||||
|
||||
Still, we knew it was frustrating to spend days setting up a project when all you wanted was to learn React. We wanted to fix this.
|
||||
|
||||
## Could We Fix This?
|
||||
|
||||
We found ourselves in an unusual dilemma.
|
||||
|
||||
So far, [our strategy](/react/contributing/design-principles.html#dogfooding) has been to only release the code that we are using at Facebook. This helped us ensure that every project is battle-tested and has clearly defined scope and priorities.
|
||||
|
||||
However, tooling at Facebook is different than at many smaller companies. Linting, transpilation, and packaging are all handled by powerful remote development servers, and product engineers don’t need to configure them. While we wish we could give a dedicated server to every user of React, even Facebook cannot scale that well!
|
||||
|
||||
The React community is very important to us. We knew that we couldn’t fix the problem within the limits of our open source philosophy. This is why we decided to make an exception, and to ship something that we didn’t use ourselves, but that we thought would be useful to the community.
|
||||
|
||||
## The Quest for a React <abbr title="Command Line Interface">CLI</abbr>
|
||||
|
||||
Having just attended [EmberCamp](http://embercamp.com/) a week ago, I was excited about [Ember CLI](https://ember-cli.com/). Ember users have a great “getting started” experience thanks to a curated set of tools united under a single command-line interface. I have heard similar feedback about [Elm Reactor](https://github.com/elm-lang/elm-reactor).
|
||||
|
||||
Providing a cohesive curated experience is valuable by itself, even if the user could in theory assemble those parts themselves. Kathy Sierra [explains it best](http://seriouspony.com/blog/2013/7/24/your-app-makes-me-fat):
|
||||
|
||||
>If your UX asks the user to make *choices*, for example, even if those choices are both clear and useful, the act of *deciding* is a cognitive drain. And not just *while* they’re deciding... even *after* we choose, an unconscious cognitive background thread is slowly consuming/leaking resources, “Was *that* the right choice?”
|
||||
|
||||
I never tried to write a command-line tool for React apps, and neither has [Christopher](https://twitter.com/vjeux). We were chatting on Messenger about this idea, and we decided to work together on it for a week as a hackathon project.
|
||||
|
||||
We knew that such projects traditionally haven’t been very successful in the React ecosystem. Christopher told me that multiple “React CLI” projects have started and failed at Facebook. The community tools with similar goals also exist, but so far they have not yet gained enough traction.
|
||||
|
||||
Still, we decided it was worth another shot. Christopher and I created a very rough proof of concept on the weekend, and [Kevin](https://twitter.com/lacker) soon joined us.
|
||||
|
||||
We invited some of the community members to collaborate with us, and we have spent this week working on this tool. We hope that you’ll enjoy using it! [Let us know what you think.](https://github.com/facebookincubator/create-react-app/issues/11)
|
||||
|
||||
We would like to express our gratitude to [Max Stoiber](https://twitter.com/mxstbr), [Jonny Buchanan](https://twitter.com/jbscript), [Ean Platter](https://twitter.com/eanplatter), [Tyler McGinnis](https://github.com/tylermcginnis), [Kent C. Dodds](https://github.com/kentcdodds), and [Eric Clemmons](https://twitter.com/ericclemmons) for their early feedback, ideas, and contributions.
|
||||
81
docs/_posts/2016-08-05-relay-state-of-the-state.md
Normal file
81
docs/_posts/2016-08-05-relay-state-of-the-state.md
Normal file
@@ -0,0 +1,81 @@
|
||||
---
|
||||
title: "Relay: State of the State"
|
||||
author: josephsavona
|
||||
---
|
||||
|
||||
This month marks a year since we released Relay and we'd like to share an update on the project and what's next.
|
||||
|
||||
## A Year In Review
|
||||
|
||||
A year after launch, we're incredibly excited to see an active community forming around Relay and that companies such as Twitter are [using Relay in production](https://fabric.io/blog/building-fabric-mission-control-with-graphql-and-relay):
|
||||
|
||||
> For a project like mission control, GraphQL and Relay were a near-perfect solution, and the cost of building it any other way justified the investment.
|
||||
>
|
||||
> -- <cite>Fin Hopkins</cite>
|
||||
|
||||
This kind of positive feedback is really encouraging (I'll admit to re-reading that post far too many times), and great motivation for us to keep going and make Relay even better.
|
||||
|
||||
With the community's help we've already come a long way since the technical preview. Here are some highlights:
|
||||
|
||||
- In March we added support for server-side rendering and for creating multiple instances of Relay on a single page. This was a coordinated effort over the course of several months by community members [Denis Nedelyaev](https://github.com/denvned) and [Gerald Monaco](https://github.com/devknoll) (now at Facebook).
|
||||
- Also in March we added support for React Native. While we use Relay and React Native together internally, they didn't quite work together in open-source out of the box. We owe a big thanks to [Adam Miskiewicz](https://github.com/skevy), [Tom Burns](https://github.com/boourns), [Gaëtan Renaudeau](https://github.com/gre), [David Aurelio](https://github.com/davidaurelio), [Martín Bigio](https://github.com/martinbigio), [Paul O’Shannessy](https://github.com/zpao), [Ben Alpert](https://github.com/spicyj), and many others who helped track down and resolve issues. Finally, thanks to [Steven Luscher](https://github.com/steveluscher) for coordinating this effort and building the first Relay/ReactNative example app.
|
||||
|
||||
We've also seen some great open-source projects spring up around Relay:
|
||||
|
||||
- [Denis Nedelyaev](https://github.com/denvned) created [isomorphic-relay](https://github.com/denvned/isomorphic-relay/), a package that helps developers build server-rendered Relay apps where data is prepared on the server and then used to bootstrap the app on the client.
|
||||
- [Jimmy Jia](https://github.com/taion) created [react-router-relay](https://github.com/relay-tools/react-router-relay) to integrate Relay data-fetching into React Router.
|
||||
- [Pavel Chertorogov](https://github.com/nodkz) released [relay-network-layer](https://github.com/nodkz/react-relay-network-layer), which adds features such as batching query requests, middleware, authentication, logging, and more.
|
||||
|
||||
This is just a small sampling of the community's contributions. So far we've merged over 300 PRs - about 25% of our commits - from over 80 of you. These PRs have improved everything from the website and docs down the very core of the framework. We're humbled by these outstanding contributions and excited to keep working with each of you!
|
||||
|
||||
# Retrospective & Roadmap
|
||||
|
||||
Earlier this year we paused to reflect on the state of the project. What was working well? What could be improved? What features should we add, and what could we remove? A few themes emerged: performance on mobile, developer experience, and empowering the community.
|
||||
|
||||
## Mobile Perf
|
||||
|
||||
First, Relay was built to serve the needs of product developers at Facebook. In 2016, that means helping developers to build apps that work well on [mobile devices connecting on slower networks](https://newsroom.fb.com/news/2015/10/news-feed-fyi-building-for-all-connectivity/). For example, people in developing markets commonly use [2011 year-class phones](https://code.facebook.com/posts/307478339448736/year-class-a-classification-system-for-android/) and connect via [2G class networks](https://code.facebook.com/posts/952628711437136/classes-performance-and-network-segmentation-on-android/). These scenarios present their own challenges.
|
||||
|
||||
Therefore, one of our primary goals this year is to optimize Relay for performance on low-end mobile devices *first*, knowing that this can translate to improved performance on high-end devices as well. In addition to standard approaches such as benchmarking, profiling, and optimizations, we're also working on big-picture changes.
|
||||
|
||||
For example, in today's Relay, here's what happens when an app is opened. First, React Native starts initializing the JavaScript context (loading and parsing your code and then running it). When this finishes, the app executes and Relay sees that you need data. It constructs and prints the query, uploads the query text to the server, processes the response, and renders your app. (Note that this process applies on the web, except that the code has to be *downloaded* instead of loaded from the device.)
|
||||
|
||||
Ideally, though, we could begin fetching data as soon as the native code had loaded - in parallel with the JS context initialization. By the time your JS code was ready to run, the data-fetching would already be under way. To do this we would need a way to determine *statically* - at build time - what query an application would send.
|
||||
|
||||
The key is that GraphQL is already static - we just need to fully embrace this fact. More on this later.
|
||||
|
||||
## Developer Experience
|
||||
|
||||
Next, we've paid attention to the community's feedback and know that, to put it simply, Relay could be "easier" to use (and "simpler" too). This isn't entirely surprising to us - Relay was originally designed as a routing library and gradually morphed into a data-fetching library. Concepts like Relay "routes", for example, no longer serve as critical a role and are just one more concept that developers have to learn about. Another example is mutations: while writes *are* inherently more complex than reads, our API doesn't make the simple things simple enough.
|
||||
|
||||
Alongside our focus on mobile performance, we've also kept the developer experience in mind as we evolve Relay core.
|
||||
|
||||
## Empowering the Community
|
||||
|
||||
Finally, we want to make it easier for people in the community to develop useful libraries that work with Relay. By comparison, React's small surface area - components - allows developers to build cool things like routing, higher-order components, or reusable text editors. For Relay, this would mean having the framework provide core primitives that users can build upon. We want it to be possible for the community to integrate Relay with view libraries other than React, or to build real-time subscriptions as a complementary library.
|
||||
|
||||
# What's Next
|
||||
|
||||
These were big goals, and also a bit scary; we knew that incremental improvements would only allow us to move so fast. So in April we started a project to build a new implementation of Relay core targeting low-end mobile devices from the start.
|
||||
|
||||
As you can guess since we're writing this, the experiment was a success. The result is a new core that retains the best parts of Relay today - colocated components & data-dependencies, automatic data/view consistency, declarative data-fetching - while improving performance on mobile devices and addressing several common areas of confusion.
|
||||
|
||||
We're currently focused on shipping the first applications using the new core: ironing out bugs, refining the API changes and developer experience, and adding any missing features. We're excited to bring these changes to open source, and will do so once we've proven them in production. We'll go into more detail in some upcoming talks - links below - but for now here's an overview:
|
||||
|
||||
- **Static Queries**: By adding a couple of Relay-specific directives, we've been able to retain the expressivity of current Relay queries using static syntax (concretely: you know what query an app will execute just by looking at the source text, without having to run that code). For starters this will allow Relay apps to start fetching data in parallel with JavaScript initialization. But it also unlocks other possibilities: knowing the query ahead of time means that we can generate optimized code for handling query responses, for example, or for reading query data from an offline cache.
|
||||
- **Expressive Mutations**: We'll continue to support a higher-level mutation API for common cases, but will also provide a lower-level API that allows "raw" data access where necessary. If you need to order a list of cached elements, for example, there will be a way to `sort()` it.
|
||||
- **Route-less Relay**: Routes will be gone in open source. Instead of a route with multiple query definitions, you'll just provide a single query with as many root fields as you want.
|
||||
- **Cache Eviction/Garbage Collection**: The API and architecture is designed from the start to allow removing cached data that is no longer referenced by a mounted view.
|
||||
|
||||
Stepping back, we recognize that any API changes will require an investment on your part. To make the transition easier, though, *we will continue to support the current API for the foreseeable future* (we're still using it too). And as much as possible we will open-source the tools that we use to migrate our own code. Ideas that we're exploring include codemods, an interoperability layer for the old/new APIs, and tutorials & guides to ease migration.
|
||||
|
||||
Ultimately, we're making these changes because we believe they make Relay better all around: simpler for developers building apps and faster for the people using them.
|
||||
|
||||
# Conclusion
|
||||
|
||||
If you made it this far, congrats and thanks for reading! We'll be sharing more information about these changes in some upcoming talks:
|
||||
|
||||
- [Greg Hurrell](https://github.com/wincent) will presenting a Relay "Deep Dive" at the [Silicon Valley ReactJS Meetup](http://www.meetup.com/Silicon-Valley-ReactJS-Meetup/events/232236845/) on August 17th.
|
||||
- I ([@josephsavona](https://github.com/josephsavona)) will be speaking about Relay at [React Rally](http://www.reactrally.com) on August 25th.
|
||||
|
||||
We can't wait to share the new code with you and are working as fast as we can to do so!
|
||||
230
docs/_posts/2016-09-28-our-first-50000-stars.md
Normal file
230
docs/_posts/2016-09-28-our-first-50000-stars.md
Normal file
@@ -0,0 +1,230 @@
|
||||
---
|
||||
title: "Our First 50,000 Stars"
|
||||
author: vjeux
|
||||
---
|
||||
|
||||
Just three and a half years ago we open sourced a little JavaScript library called React. The journey since that day has been incredibly exciting.
|
||||
|
||||
## Commemorative T-Shirt
|
||||
|
||||
In order to celebrate 50,000 GitHub stars, [Maggie Appleton](http://www.maggieappleton.com/) from [egghead.io](http://egghead.io/) has designed us a special T-shirt, which will be available for purchase from Teespring **only for a week** through Thursday, October 6. Maggie also wrote [a blog post](https://www.behance.net/gallery/43269677/Reacts-50000-Stars-Shirt) showing all the different concepts she came up with before settling on the final design.
|
||||
|
||||
<a target="_blank" href="https://teespring.com/react-50000-stars"><img src="/react/img/blog/react-50k-tshirt.jpg" width="650" height="340" alt="React 50k Tshirt" /></a>
|
||||
|
||||
The T-shirts are super soft using American Apparel's tri-blend fabric; we also have kids and toddler T-shirts and baby onesies available.
|
||||
|
||||
* [Adult T-shirts (straight-cut and fitted)](https://teespring.com/react-50000-stars)
|
||||
* [Kids T-shirts](https://teespring.com/react-50000-stars-kids)
|
||||
* [Toddler T-Shirts](https://teespring.com/react-50000-stars-toddler)
|
||||
* [Baby Onesies](https://teespring.com/react-50000-stars-baby)
|
||||
|
||||
Proceeds from the shirts will be donated to [CODE2040](http://www.code2040.org/), a nonprofit that creates access, awareness, and opportunities in technology for underrepresented minorities with a specific focus on Black and Latinx talent.
|
||||
|
||||
## Archeology
|
||||
|
||||
We've spent a lot of time trying to explain the concepts behind React and the problems it attempts to solve, but we haven't talked much about how React evolved before being open sourced. This milestone seemed like as good a time as any to dig through the earliest commits and share some of the more important moments and fun facts.
|
||||
|
||||
The story begins in our ads org, where we were building incredibly sophisticated client side web apps using an internal MVC framework called [BoltJS](http://web.archive.org/web/20130608154901/http://shaneosullivan.github.io/boltjs/intro.html). Here's a sample of what some Bolt code looked like:
|
||||
|
||||
```js
|
||||
var CarView = require('javelin/core').createClass({
|
||||
name: 'CarView',
|
||||
extend: require('container').Container,
|
||||
properties: {
|
||||
wheels: 4,
|
||||
},
|
||||
declare: function() {
|
||||
return {
|
||||
childViews: [
|
||||
{ content: 'I have ' },
|
||||
{ ref: 'wheelView' },
|
||||
{ content: ' wheels' }
|
||||
]
|
||||
};
|
||||
},
|
||||
setWheels: function(wheels) {
|
||||
this.findRef('wheelView').setContent(wheels);
|
||||
},
|
||||
getWheels: function() {
|
||||
return this.findRef('wheelView').getContent();
|
||||
},
|
||||
});
|
||||
|
||||
var car = new CarView();
|
||||
car.setWheels(3);
|
||||
car.placeIn(document.body);
|
||||
//<div>
|
||||
// <div>I have </div>
|
||||
// <div>3</div>
|
||||
// <div> wheels</div>
|
||||
//</div>
|
||||
```
|
||||
|
||||
Bolt introduced a number of APIs and features that would eventually make their way into React including `render`, `createClass`, and `refs`. Bolt introduced the concept of `refs` as a way to create references to nodes that can be used imperatively. This was relevant for legacy interoperability and incremental adoption, and while React would eventually strive to be a lot more functional, `refs` proved to be a very useful way to break out of the functional paradigm when the need arose.
|
||||
|
||||
But as our applications grew more and more sophisticated, our Bolt codebases got pretty complicated. Recognizing some of the framework's shortcomings, [Jordan Walke](https://twitter.com/jordwalke) started experimenting with a side-project called [FaxJS](https://github.com/jordwalke/FaxJs). His goal was to solve many of the same problems as Bolt, but in a very different way. This is actually where most of React's fundamentals were born, including props, state, re-evaluating large portions of the tree to “diff” the UI, server-side rendering, and a basic concept of components.
|
||||
|
||||
```js
|
||||
TestProject.PersonDisplayer = {
|
||||
structure : function() {
|
||||
return Div({
|
||||
classSet: { personDisplayerContainer: true },
|
||||
titleDiv: Div({
|
||||
classSet: { personNameTitle: true },
|
||||
content: this.props.name
|
||||
}),
|
||||
nestedAgeDiv: Div({
|
||||
content: 'Interests: ' + this.props.interests
|
||||
})
|
||||
});
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
## FBolt is Born
|
||||
|
||||
Through his FaxJS experiment, Jordan became convinced that functional APIs — which discouraged mutation — offered a better, more scalable way to build user interfaces. He imported his library into Facebook's codebase in March of 2012 and renamed it “FBolt”, signifying an extension of Bolt where components are written in a functional programming style. Or maybe “FBolt” was a nod to FaxJS – he didn't tell us! ;)
|
||||
|
||||
The interoperability between FBolt and Bolt allowed us to experiment with replacing just one component at a time with more functional component APIs. We could test the waters of this new functional paradigm, without having to go all in. We started with the components that were clearly best expressed functionally and then we would later continue to push the boundaries of what we could express as functions.
|
||||
|
||||
Realizing that FBolt wouldn't be a great name for the library when used on its own, Jordan Walke and [Tom Occhino](https://twitter.com/tomocchino) decided on a new name: “React.” After Tom sent out the diff to rename everything to React, Jordan commented:
|
||||
|
||||
|
||||
> Jordan Walke:
|
||||
I might add for the sake of discussion, that many systems advertise some kind of reactivity, but they usually require that you set up some kind of point-to-point listeners and won't work on structured data. This API reacts to any state or property changes, and works with data of any form (as deeply structured as the graph itself) so I think the name is fitting.
|
||||
|
||||
|
||||
Most of Tom's other commits at the time were on the first version of [GraphiQL](https://github.com/graphql/graphiql), a project which was recently open sourced.
|
||||
|
||||
## Adding JSX
|
||||
|
||||
Since about 2010 Facebook has been using an extension of PHP called [XHP](https://www.facebook.com/notes/facebook-engineering/xhp-a-new-way-to-write-php/294003943919/), which enables engineers to create UIs using XML literals right inside their PHP code. It was first introduced to help prevent XSS holes but ended up being an excellent way to structure applications with custom components.
|
||||
|
||||
```js
|
||||
final class :a:post extends :x:element {
|
||||
attribute :a;
|
||||
protected function render(): XHPRoot {
|
||||
$anchor = <a>{$this->getChildren()}</a>;
|
||||
$form = (
|
||||
<form
|
||||
method="post"
|
||||
action={$this->:href}
|
||||
target={$this->:target}
|
||||
class="postLink"
|
||||
>{$anchor}</form>
|
||||
);
|
||||
$this->transferAllAttributes($anchor);
|
||||
return $form;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Before Jordan's work had even made its way into the Facebook codebase, Adam Hupp implemented an XHP-like concept for JavaScript, written in Haskell. This system enabled you to write the following inside a JavaScript file:
|
||||
|
||||
```js
|
||||
function :example:hello(attrib, children) {
|
||||
return (
|
||||
<div class="special">
|
||||
<h1>Hello, World!</h1>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
It would compile the above into the following normal ES3-compatible JavaScript:
|
||||
|
||||
```js
|
||||
function jsx_example_hello(attrib, children) {
|
||||
return (
|
||||
S.create("div", {"class": "special"}, [
|
||||
S.create("h1", {}, ["Hello, World!"]),
|
||||
children
|
||||
]
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
In this prototype, `S.create` would immediately create and return a DOM node. Most of the conversations on this prototype revolved around the performance characteristics of `innerHTML` versus creating DOM nodes directly. At the time, it would have been less than ideal to push developers universally in the direction of creating DOM nodes directly since it did not perform as well, especially in Firefox and IE. Facebook's then-CTO [Bret Taylor](https://twitter.com/btaylor) chimed in on the discussion at the time in favor of `innerHTML` over `document.createElement`:
|
||||
|
||||
|
||||
> Bret Taylor:
|
||||
If you are not convinced about innerHTML, here is a small microbenchmark. It is about the same in Chrome. innerHTML is about 30% faster in the latest version of Firefox (much more in previous versions), and about 90% faster in IE8.
|
||||
|
||||
|
||||
This work was eventually abandoned but was revived after React made its way into the codebase. Jordan sidelined the previous performance discussions by introducing the concept of a “Virtual DOM,” though its eventual name didn't exist yet.
|
||||
|
||||
|
||||
> Jordan Walke:
|
||||
> For the first step, I propose that we do the easiest, yet most general transformation possible. My suggestion is to simply map xml expressions to function call expressions.
|
||||
>
|
||||
> - `<x></x>` becomes `x( )`
|
||||
> - `<x height=12></x>` becomes `x( {height:12} )`
|
||||
> - `<x> <y> </y> </x>` becomes `x({ childList: [y( )] })`
|
||||
>
|
||||
> At this point, JSX doesn't need to know about React - it's just a convenient way to write function calls. Coincidentally, React's primary abstraction is the function. Okay maybe it's not so coincidental ;)
|
||||
|
||||
|
||||
Adam made a very insightful comment, which is now the default way we write lists in React with JSX.
|
||||
|
||||
|
||||
> Adam Hupp:
|
||||
> I think we should just treat arrays of elements as a frag. This is useful for constructs like:
|
||||
>
|
||||
> ```js
|
||||
<ul>{foo.map(function(i) { return <li>{i.data}</li>; })}</ul>
|
||||
```
|
||||
>
|
||||
> In this case the ul(..) will get a childList with a single child, which is itself a list.
|
||||
|
||||
|
||||
React didn't end up using Adam's implementation directly. Instead, we created JSX by forking [js-xml-literal](https://github.com/laverdet/js-xml-literal), a side project by XHP creator Marcel Laverdet. JSX took its name from js-xml-literal, which Jordan modified to just be syntactic sugar for deeply nested function calls.
|
||||
|
||||
## API Churn
|
||||
|
||||
During the first year of React, internal adoption was growing quickly but there was quite a lot of churn in the component APIs and naming conventions:
|
||||
|
||||
* `project` was renamed to `declare` then to `structure` and finally to `render`.
|
||||
* `Componentize` was renamed to `createComponent` and finally to `createClass`.
|
||||
|
||||
As the project was about to be open sourced, [Lee Byron](https://twitter.com/leeb) sat down with Jordan Walke, Tom Occhino and Sebastian Markbåge in order to refactor, reimplement, and rename one of React's most beloved features – the lifecycle API. Lee [came up with a well-designed API](https://gist.github.com/vjeux/f2b015d230cc1ab18ed1df30550495ed) that is still in place today.
|
||||
|
||||
* Concepts
|
||||
* component - a ReactComponent instance
|
||||
* state - internal state to a component
|
||||
* props - external state to a component
|
||||
* markup - the stringy HTML-ish stuff components generate
|
||||
* DOM - the document and elements within the document
|
||||
* Actions
|
||||
* mount - to put a component into a DOM
|
||||
* initialize - to prepare a component for rendering
|
||||
* update - a transition of state (and props) resulting a render.
|
||||
* render - a side-effect-free process to get the representation (markup) of a component.
|
||||
* validate - make assertions about something created and provided
|
||||
* destroy - opposite of initialize
|
||||
* Operands
|
||||
* create - make a new thing
|
||||
* get - get an existing thing
|
||||
* set - merge into existing
|
||||
* replace - replace existing
|
||||
* receive - respond to new data
|
||||
* force - skip checks to do action
|
||||
* Notifications
|
||||
* shouldObjectAction
|
||||
* objectWillAction
|
||||
* objectDidAction
|
||||
|
||||
## Instagram
|
||||
|
||||
In 2012, Instagram got acquired by Facebook. [Pete Hunt](https://twitter.com/floydophone), who was working on Facebook photos and videos at the time, joined their newly formed web team. He wanted to build their website completely in React, which was in stark contrast with the incremental adoption model that had been used at Facebook.
|
||||
|
||||
To make this happen, React had to be decoupled from Facebook's infrastructure, since Instagram didn't use any of it. This project acted as a forcing function to do the work needed to open source React. In the process, Pete also discovered and promoted a little project called Webpack. He also implemented the `renderToString` primitive which was needed to do server-side rendering.
|
||||
|
||||
As we started to prepare for the open source launch, [Maykel Loomans](https://twitter.com/miekd), a designer on Instagram, made a mock of what the website could look like. The header ended up defining the visual identity of React: its logo and the electric blue color!
|
||||
|
||||
<center><a target="_blank" href="/react/img/blog/react-50k-mock-full.jpg"><img src="/react/img/blog/react-50k-mock.jpg" width="400" height="410" alt="React website mock" /></a></center>
|
||||
|
||||
In its earliest days, React benefitted tremendously from feedback, ideas, and technical contributions of early adopters and collaborators all over the company. While it might look like an overnight success in hindsight, the story of React is actually a great example of how new ideas often need to go through several rounds of refinement, iteration, and course correction over a long period of time before reaching their full potential.
|
||||
|
||||
React's approach to building user interfaces with functional programming principles has changed the way we do things in just a few short years. It goes without saying, but React would be nothing without the amazing open source community that's built up around it!
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
id: acknowledgements
|
||||
title: Acknowledgements
|
||||
layout: single
|
||||
permalink: acknowledgements.html
|
||||
---
|
||||
|
||||
We'd like to thank all of our contributors:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
permalink: complementary-tools-it-IT.html
|
||||
permalink: docs/complementary-tools-it-IT.html
|
||||
layout: redirect
|
||||
dest_url: https://github.com/facebook/react/wiki/Complementary-Tools
|
||||
---
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
permalink: complementary-tools-ko-KR.html
|
||||
permalink: docs/complementary-tools-ko-KR.html
|
||||
layout: redirect
|
||||
dest_url: https://github.com/facebook/react/wiki/Complementary-Tools
|
||||
---
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
permalink: complementary-tools.html
|
||||
permalink: docs/complementary-tools.html
|
||||
layout: redirect
|
||||
dest_url: https://github.com/facebook/react/wiki/Complementary-Tools
|
||||
---
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
permalink: complementary-tools-zh-CN.html
|
||||
permalink: docs/complementary-tools-zh-CN.html
|
||||
layout: redirect
|
||||
dest_url: https://github.com/facebook/react/wiki/Complementary-Tools
|
||||
---
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
id: conferences-it-IT
|
||||
title: Conferenze
|
||||
permalink: conferences-it-IT.html
|
||||
permalink: docs/conferences-it-IT.html
|
||||
prev: thinking-in-react-it-IT.html
|
||||
next: videos-it-IT.html
|
||||
---
|
||||
@@ -11,7 +11,7 @@ next: videos-it-IT.html
|
||||
|
||||
[Sito web](http://conf.reactjs.com/) - [Agenda](http://conf.reactjs.com/schedule.html) - [Video](https://www.youtube-nocookie.com/playlist?list=PLb0IAmt7-GS1cbw4qonlQztYV1TAW0sCr)
|
||||
|
||||
<iframe width="650" height="315" src="//www.youtube-nocookie.com/embed/KVZ-P-ZI6W4?list=PLb0IAmt7-GS1cbw4qonlQztYV1TAW0sCr" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="315" src="//www.youtube-nocookie.com/embed/KVZ-P-ZI6W4?list=PLb0IAmt7-GS1cbw4qonlQztYV1TAW0sCr" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
### ReactEurope 2015
|
||||
2 e 3 Luglio
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
id: conferences-ko-KR
|
||||
title: 컨퍼런스들
|
||||
permalink: conferences-ko-KR.html
|
||||
permalink: docs/conferences-ko-KR.html
|
||||
prev: thinking-in-react-ko-KR.html
|
||||
next: videos-ko-KR.html
|
||||
---
|
||||
@@ -11,7 +11,7 @@ next: videos-ko-KR.html
|
||||
|
||||
[웹사이트](http://conf.reactjs.com/) - [스케줄](http://conf.reactjs.com/schedule.html) - [비디오들](https://www.youtube-nocookie.com/playlist?list=PLb0IAmt7-GS1cbw4qonlQztYV1TAW0sCr)
|
||||
|
||||
<iframe width="650" height="315" src="//www.youtube-nocookie.com/embed/KVZ-P-ZI6W4?list=PLb0IAmt7-GS1cbw4qonlQztYV1TAW0sCr" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="315" src="//www.youtube-nocookie.com/embed/KVZ-P-ZI6W4?list=PLb0IAmt7-GS1cbw4qonlQztYV1TAW0sCr" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
### ReactEurope 2015
|
||||
7월 2일 & 3일
|
||||
95
docs/community/conferences.md
Normal file
95
docs/community/conferences.md
Normal file
@@ -0,0 +1,95 @@
|
||||
---
|
||||
id: conferences
|
||||
title: Conferences
|
||||
layout: community
|
||||
sectionid: community
|
||||
permalink: community/conferences.html
|
||||
redirect_from: "docs/conferences.html"
|
||||
---
|
||||
|
||||
## Upcoming Conferences
|
||||
|
||||
### Agent Conference 2017
|
||||
January 20-21 in Dornbirn, Austria
|
||||
|
||||
[Website](http://agent.sh/)
|
||||
|
||||
### ReactEurope 2017
|
||||
May 18th & 19th in Paris, France
|
||||
|
||||
[Website](http://www.react-europe.org/) - [Schedule](http://www.react-europe.org/#schedule)
|
||||
|
||||
### React Amsterdam 2017
|
||||
April 21st in Amsterdam, The Netherlands
|
||||
|
||||
[Website](https://react.amsterdam) - [Twitter](https://twitter.com/reactamsterdam)
|
||||
|
||||
### Chain React 2017
|
||||
Summer 2017, Portland, Oregon USA
|
||||
|
||||
[Website](https://infinite.red/ChainReactConf) - [Twitter](https://twitter.com/chainreactconf)
|
||||
|
||||
### React Native EU 2017
|
||||
Fall 2017, Poland
|
||||
|
||||
[Website](http://react-native.eu/)
|
||||
|
||||
|
||||
## Past Conferences
|
||||
|
||||
### React.js Conf 2015
|
||||
January 28 & 29 in Facebook HQ, CA
|
||||
|
||||
[Website](http://conf2015.reactjs.org/) - [Schedule](http://conf2015.reactjs.org/schedule.html) - [Videos](https://www.youtube.com/playlist?list=PLb0IAmt7-GS1cbw4qonlQztYV1TAW0sCr)
|
||||
|
||||
<iframe width="100%" height="315" src="//www.youtube-nocookie.com/embed/KVZ-P-ZI6W4?list=PLb0IAmt7-GS1cbw4qonlQztYV1TAW0sCr" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
### ReactEurope 2015
|
||||
July 2 & 3 in Paris, France
|
||||
|
||||
[Website](http://www.react-europe.org/) - [Schedule](http://www.react-europe.org/#schedule) - [Videos](https://www.youtube.com/channel/UCorlLn2oZfgOJ-FUcF2eZ1A/playlists)
|
||||
|
||||
### Reactive 2015
|
||||
November 2-4 in Bratislava, Slovakia
|
||||
|
||||
[Website](https://reactive2015.com/) - [Schedule](https://reactive2015.com/schedule_speakers.html#schedule)
|
||||
|
||||
### React.js Conf 2016
|
||||
February 22 & 23 in San Francisco, CA
|
||||
|
||||
[Website](http://conf.reactjs.com/) - [Schedule](http://conf.reactjs.com/schedule.html) - [Videos](https://www.youtube.com/playlist?list=PLb0IAmt7-GS0M8Q95RIc2lOM6nc77q1IY)
|
||||
|
||||
### React Amsterdam 2016
|
||||
April 16 in Amsterdam, The Netherlands
|
||||
|
||||
[Website](https://react.amsterdam/2016) - [Videos](https://youtu.be/sXDZBxbRRag?list=PLNBNS7NRGKMG3uLrm5fgY02hJ87Wzb4IU)
|
||||
|
||||
### ReactEurope 2016
|
||||
June 2 & 3 in Paris, France
|
||||
|
||||
[Website](http://www.react-europe.org/) - [Schedule](http://www.react-europe.org/#schedule) - [Videos](https://www.youtube.com/channel/UCorlLn2oZfgOJ-FUcF2eZ1A/playlists)
|
||||
|
||||
### ReactRally 2016
|
||||
August 25-26 in Salt Lake City, UT
|
||||
|
||||
[Website](http://www.reactrally.com/) - [Schedule](http://www.reactrally.com/#/schedule) - [Videos](https://www.youtube.com/playlist?list=PLUD4kD-wL_zYSfU3tIYsb4WqfFQzO_EjQ)
|
||||
|
||||
### ReactNext 2016
|
||||
September 15 in Tel Aviv, Israel
|
||||
|
||||
[Website](http://react-next.com/) - [Schedule](http://react-next.com/#schedule) - [Videos](https://www.youtube.com/channel/UC3BT8hh3yTTYxbLQy_wbk2w)
|
||||
|
||||
### ReactNL 2016
|
||||
October 13 in Amsterdam, The Netherlands - [Schedule](http://reactnl.org/#program)
|
||||
|
||||
[Website](http://reactnl.org/)
|
||||
|
||||
### Reactive 2016
|
||||
October 26-28 in Bratislava, Slovakia
|
||||
|
||||
[Website](https://reactiveconf.com/)
|
||||
|
||||
### React Remote Conf 2016
|
||||
October 26-28 online
|
||||
|
||||
[Website](https://allremoteconfs.com/react-2016) - [Schedule](https://allremoteconfs.com/react-2016#schedule)
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
id: conferences-zh-CN
|
||||
title: 会议
|
||||
permalink: conferences-zh-CN.html
|
||||
permalink: docs/conferences-zh-CN.html
|
||||
prev: thinking-in-react-zh-CN.html
|
||||
next: videos-zh-CN.html
|
||||
---
|
||||
@@ -11,7 +11,7 @@ next: videos-zh-CN.html
|
||||
|
||||
[Website](http://conf.reactjs.com/) - [Schedule](http://conf.reactjs.com/schedule.html) - [Videos](https://www.youtube-nocookie.com/playlist?list=PLb0IAmt7-GS1cbw4qonlQztYV1TAW0sCr)
|
||||
|
||||
<iframe width="650" height="315" src="//www.youtube-nocookie.com/embed/KVZ-P-ZI6W4?list=PLb0IAmt7-GS1cbw4qonlQztYV1TAW0sCr" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="315" src="//www.youtube-nocookie.com/embed/KVZ-P-ZI6W4?list=PLb0IAmt7-GS1cbw4qonlQztYV1TAW0sCr" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
### ReactEurope 2015
|
||||
七月 2 & 3
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
permalink: examples-it-IT.html
|
||||
permalink: docs/examples-it-IT.html
|
||||
layout: redirect
|
||||
dest_url: https://github.com/facebook/react/wiki/Examples
|
||||
---
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
permalink: examples-ko-KR.html
|
||||
permalink: docs/examples-ko-KR.html
|
||||
layout: redirect
|
||||
dest_url: https://github.com/facebook/react/wiki/Examples
|
||||
---
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
permalink: examples.html
|
||||
permalink: docs/examples.html
|
||||
layout: redirect
|
||||
dest_url: https://github.com/facebook/react/wiki/Examples
|
||||
---
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
permalink: examples-zh-CN.html
|
||||
permalink: docs/examples-zh-CN.html
|
||||
layout: redirect
|
||||
dest_url: https://github.com/facebook/react/wiki/Examples
|
||||
---
|
||||
@@ -1,7 +1,10 @@
|
||||
---
|
||||
title: Need help?
|
||||
layout: single
|
||||
id: support
|
||||
title: Where To Get Support
|
||||
layout: community
|
||||
sectionid: community
|
||||
permalink: community/support.html
|
||||
redirect_from: "support.html"
|
||||
---
|
||||
|
||||
**React** is worked on full-time by Facebook's product infrastructure and Instagram's user interface engineering teams. They're often around and available for questions.
|
||||
@@ -16,12 +19,12 @@ For longer-form conversations about React, we've set up a [discussion forum at *
|
||||
|
||||
In the forum there's also a category for job posts and a category for discussion of our weekly meeting notes.
|
||||
|
||||
## IRC
|
||||
## Reactiflux Chat
|
||||
|
||||
Many developers and users idle on Freenode.net's IRC network in **[#reactjs on freenode](irc://chat.freenode.net/reactjs)**.
|
||||
If you need an answer right away, check out the [Reactiflux Discord](https://discord.gg/0ZcbPKXt5bZjGY5n) community. There are usually a number of React experts there who can help out or point you to somewhere you might want to look.
|
||||
|
||||
## Twitter
|
||||
## Facebook and Twitter
|
||||
|
||||
For the latest news about React, [follow **@reactjs** on Twitter](https://twitter.com/reactjs). In addition, you can use the #reactjs hashtag to see what others are saying or add to the conversation.
|
||||
For the latest news about React, [like us on Facebook](https://facebook.com/react) and [follow **@reactjs** on Twitter](https://twitter.com/reactjs). In addition, you can use the [#reactjs](https://twitter.com/hashtag/reactjs) hashtag to see what others are saying or add to the conversation.
|
||||
|
||||
<div><a class="twitter-timeline" data-dnt="true" data-chrome="nofooter noheader transparent" href="https://twitter.com/search?q=%23reactjs" data-widget-id="342522405270470656"></a></div>
|
||||
@@ -1,14 +1,14 @@
|
||||
---
|
||||
id: videos-it-IT
|
||||
title: Video
|
||||
permalink: videos-it-IT.html
|
||||
permalink: docs/videos-it-IT.html
|
||||
prev: conferences-it-IT.html
|
||||
next: complementary-tools-it-IT.html
|
||||
---
|
||||
|
||||
### Riconsiderare le best practice - JSConf.eu
|
||||
|
||||
<iframe width="650" height="366" src="https://www.youtube-nocookie.com/embed/x7cQ3mrcKaY" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/x7cQ3mrcKaY" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
"A Facebook e Instagram, con React stiamo provando a spingerci oltre i limiti di ciò che è possibile realizzare sul web. Il mio talk comincerà con una breve introduzione al framework, e poi approfondirà tre argomenti controversi: Gettare via la nozione dei template e costruire le viste con JavaScript, effettuare il “ri-rendering” dell'intera applicazione quando i dati cambiano, e un'implementazione leggera del DOM e degli eventi." -- [Pete Hunt](http://www.petehunt.net/)
|
||||
|
||||
@@ -23,7 +23,7 @@ Un video di [tagtree.tv](http://tagtree.tv/) che espone i principi di [Pensare i
|
||||
|
||||
### I Segreti del DOM Virtuale - MtnWest JS
|
||||
|
||||
<iframe width="650" height="366" src="https://www.youtube-nocookie.com/embed/h3KksH8gfcQ" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/h3KksH8gfcQ" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
"In questo talk discuterò perché abbiamo costruito un DOM virtuale, i vantaggi rispetto ad altri sistemi, e la sua rilevanza per il futuro della tecnologia dei browser." -- [Pete Hunt](http://www.petehunt.net/)
|
||||
|
||||
@@ -99,14 +99,14 @@ Un video di [tagtree.tv](http://tagtree.tv/) che espone i principi di [Pensare i
|
||||
|
||||
### Introduzione a React.js - Facebook Seattle
|
||||
|
||||
<iframe width="650" height="366" src="https://www.youtube-nocookie.com/embed/XxVg_s8xAms" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/XxVg_s8xAms" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
Di [Tom Occhino](http://tomocchino.com/) e [Jordan Walke](https://github.com/jordwalke)
|
||||
|
||||
* * *
|
||||
|
||||
### Backbone + React + Middleman Screencast
|
||||
<iframe width="650" height="488" src="https://www.youtube-nocookie.com/embed/iul1fWHVU6A" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="488" src="https://www.youtube-nocookie.com/embed/iul1fWHVU6A" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
Backbone è una grande maniera di interfacciare una API REST con React. Questo screencast mostra come integrare i due usando [Backbone-React-Component](https://github.com/magalhas/backbone-react-component). Middleman è il framework utilizzato in questo esempio, ma può essere facilmente sostituito con altri framework. Si può trovare un template supportato per questo esempio [qui](https://github.com/jbhatab/middleman-backbone-react-template). -- [Open Minded Innovations](http://www.openmindedinnovations.com/)
|
||||
|
||||
@@ -114,7 +114,7 @@ Backbone è una grande maniera di interfacciare una API REST con React. Questo s
|
||||
|
||||
### Sviluppare Interfacce Utente Con React - Super VanJS
|
||||
|
||||
<iframe width="650" height="366" src="https://www.youtube-nocookie.com/embed/1OeXsL5mr4g" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/1OeXsL5mr4g" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
Di [Steven Luscher](https://github.com/steveluscher)
|
||||
|
||||
@@ -122,7 +122,7 @@ Di [Steven Luscher](https://github.com/steveluscher)
|
||||
|
||||
### Introduzione a React - LAWebSpeed meetup
|
||||
|
||||
<iframe width="650" height="366" src="https://www.youtube-nocookie.com/embed/SMMRJif5QW0" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/SMMRJif5QW0" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
Di [Stoyan Stefanov](http://www.phpied.com/)
|
||||
|
||||
@@ -130,7 +130,7 @@ Di [Stoyan Stefanov](http://www.phpied.com/)
|
||||
|
||||
### React, o come rendere la vita più semplice - FrontEnd Dev Conf '14
|
||||
|
||||
<iframe width="650" height="366" src="https://www.youtube-nocookie.com/embed/YJNUK0EA_Jo" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/YJNUK0EA_Jo" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
**In Russo** di [Alexander Solovyov](http://solovyov.net/)
|
||||
|
||||
@@ -138,19 +138,19 @@ Di [Stoyan Stefanov](http://www.phpied.com/)
|
||||
|
||||
### "Programmazione funzionale del DOM" - Meteor DevShop 11
|
||||
|
||||
<iframe width="650" height="366" src="https://www.youtube-nocookie.com/embed/qqVbr_LaCIo" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/qqVbr_LaCIo" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
* * *
|
||||
|
||||
### "Ripensare lo Sviluppo di Applicazioni Web a Facebook" - Facebook F8 Conference 2014
|
||||
|
||||
<iframe width="650" height="366" src="https://www.youtube-nocookie.com/embed/nYkdrAPrdcw" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/nYkdrAPrdcw" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
* * *
|
||||
|
||||
### React e Flux: Costruire Applicazioni con un Flusso Dati Unidirezionale - Forward JS 2014
|
||||
|
||||
<iframe width="650" height="366" src="https://www.youtube-nocookie.com/embed/i__969noyAM" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/i__969noyAM" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
Gli ingegneri di Facebook [Bill Fisher](https://twitter.com/fisherwebdev) e [Jing Chen](https://twitter.com/jingc) parlano di Flux e React, e di come usare un'architettura dell'applicazione con un flusso di dati unidirezionale rende gran parte del loro codice più pulito.
|
||||
|
||||
@@ -158,7 +158,7 @@ Gli ingegneri di Facebook [Bill Fisher](https://twitter.com/fisherwebdev) e [Jin
|
||||
|
||||
### Rendering Lato Server di Applicazioni Isomorfiche a SoundCloud
|
||||
|
||||
<iframe src="https://player.vimeo.com/video/108488724" width="650" height="365" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
|
||||
<iframe src="https://player.vimeo.com/video/108488724" width="100%" height="365" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
|
||||
|
||||
[Andres Suarez](https://github.com/zertosh) ci accompagna alla scoperta di come [SoundCloud](https://developers.soundcloud.com/blog/) usa React e Flux per il rendering lato server.
|
||||
|
||||
@@ -168,6 +168,6 @@ Gli ingegneri di Facebook [Bill Fisher](https://twitter.com/fisherwebdev) e [Jin
|
||||
|
||||
### Introduzione a React Native (+Playlist) - React.js Conf 2015
|
||||
|
||||
<iframe width="650" height="366" src="https://www.youtube-nocookie.com/embed/KVZ-P-ZI6W4?list=PLb0IAmt7-GS1cbw4qonlQztYV1TAW0sCr" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/KVZ-P-ZI6W4?list=PLb0IAmt7-GS1cbw4qonlQztYV1TAW0sCr" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
[Tom Occhino](https://twitter.com/tomocchino) ripercorre il passato e il presente di React nel 2015, e ci mostra dove è diretto nell'immediato futuro.
|
||||
@@ -1,14 +1,14 @@
|
||||
---
|
||||
id: videos-ko-KR
|
||||
title: 비디오들
|
||||
permalink: videos-ko-KR.html
|
||||
permalink: docs/videos-ko-KR.html
|
||||
prev: conferences-ko-KR.html
|
||||
next: complementary-tools-ko-KR.html
|
||||
---
|
||||
|
||||
### Rethinking best practices - JSConf.eu
|
||||
|
||||
<iframe width="650" height="366" src="https://www.youtube-nocookie.com/embed/x7cQ3mrcKaY" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/x7cQ3mrcKaY" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
"페이스북과 인스타그램에서, 우리는 React 를 이용해 웹에서 벌어질 수 있는 한계를 뛰어넘으려 노력하고 있습니다. 저는 프레임워크에 대한 짤막한 소개로 시작해서, 논쟁이 벌어질 수 있는 다음의 세가지 주제로 넘어갈겁니다. 템플릿의 개념을 버리고 JavaScript 를 이용해 View 를 구축하기, 자료가 변할때 전체 어플리케이션을 다시 그리기(“re-rendering”), 그리고 DOM과 events의 경량화된 구현 입니다." -- [Pete Hunt](http://www.petehunt.net/)
|
||||
|
||||
@@ -23,7 +23,7 @@ next: complementary-tools-ko-KR.html
|
||||
|
||||
### Secrets of the Virtual DOM - MtnWest JS
|
||||
|
||||
<iframe width="650" height="366" src="https://www.youtube-nocookie.com/embed/h3KksH8gfcQ" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/h3KksH8gfcQ" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
"이번에는 왜 우리가 virtual DOM을 만들었는지, 이것이 다른 시스템들과는 어떻게 다른지, 그리고 브라우져 기술들의 미래와 어떻게 관련이 있는지에 대해서 이야기 해 볼 겁니다." -- [Pete Hunt](http://www.petehunt.net/)
|
||||
|
||||
@@ -101,14 +101,14 @@ JavaScript Jabber 73에서 [Pete Hunt](http://www.petehunt.net/)와 [Jordan Walk
|
||||
|
||||
### Introduction to React.js - Facebook Seattle
|
||||
|
||||
<iframe width="650" height="366" src="https://www.youtube-nocookie.com/embed/XxVg_s8xAms" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/XxVg_s8xAms" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
By [Tom Occhino](http://tomocchino.com/), [Jordan Walke](https://github.com/jordwalke)
|
||||
|
||||
* * *
|
||||
|
||||
### Backbone + React + Middleman Screencast
|
||||
<iframe width="650" height="488" src="https://www.youtube-nocookie.com/embed/iul1fWHVU6A" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="488" src="https://www.youtube-nocookie.com/embed/iul1fWHVU6A" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
Backbone은 React로 REST API를 제공하기 위한 아주 좋은 방법입니다. 이 화면중개는 [Backbone-React-Component](https://github.com/magalhas/backbone-react-component)을 이용해서 어떻게 이 두가지를 연동하는지 보여줍니다. Middleman은 이 예제에서 사용되는 프레임워크이지만, 쉽게 다른 프레임워크로 대체하실 수 있습니다. 지원되는 템플릿은 [이곳](https://github.com/jbhatab/middleman-backbone-react-template)에서 찾으실 수 있습니다. -- [열린 마음의 혁명들](http://www.openmindedinnovations.com/)
|
||||
|
||||
@@ -116,7 +116,7 @@ Backbone은 React로 REST API를 제공하기 위한 아주 좋은 방법입니
|
||||
|
||||
### Developing User Interfaces With React - Super VanJS
|
||||
|
||||
<iframe width="650" height="366" src="https://www.youtube-nocookie.com/embed/1OeXsL5mr4g" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/1OeXsL5mr4g" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
By [Steven Luscher](https://github.com/steveluscher)
|
||||
|
||||
@@ -124,7 +124,7 @@ By [Steven Luscher](https://github.com/steveluscher)
|
||||
|
||||
### Introduction to React - LAWebSpeed meetup
|
||||
|
||||
<iframe width="650" height="366" src="https://www.youtube-nocookie.com/embed/SMMRJif5QW0" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/SMMRJif5QW0" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
by [Stoyan Stefanov](http://www.phpied.com/)
|
||||
|
||||
@@ -132,7 +132,7 @@ by [Stoyan Stefanov](http://www.phpied.com/)
|
||||
|
||||
### React, or how to make life simpler - FrontEnd Dev Conf '14
|
||||
|
||||
<iframe width="560" height="366" src="https://www.youtube-nocookie.com/embed/YJNUK0EA_Jo" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/YJNUK0EA_Jo" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
**러시아어** by [Alexander Solovyov](http://solovyov.net/)
|
||||
|
||||
@@ -140,19 +140,19 @@ by [Stoyan Stefanov](http://www.phpied.com/)
|
||||
|
||||
### "Functional DOM programming" - Meteor DevShop 11
|
||||
|
||||
<iframe width="650" height="366" src="https://www.youtube-nocookie.com/embed/qqVbr_LaCIo" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/qqVbr_LaCIo" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
* * *
|
||||
|
||||
### "Rethinking Web App Development at Facebook" - Facebook F8 Conference 2014
|
||||
|
||||
<iframe width="650" height="366" src="https://www.youtube-nocookie.com/embed/nYkdrAPrdcw" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/nYkdrAPrdcw" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
* * *
|
||||
|
||||
### React and Flux: Building Applications with a Unidirectional Data Flow - Forward JS 2014
|
||||
|
||||
<iframe width="650" height="366" src="https://www.youtube-nocookie.com/embed/i__969noyAM" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/i__969noyAM" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
Facebook 개발자 [Bill Fisher](https://twitter.com/fisherwebdev)와 [Jing Chen](https://twitter.com/jingc)가 Flux 와 React 에 대해서 이야기합니다. 그리고 어떻게 단일 방향의 자료흐름을 사용하는 어플리케이션 구조가 방대한 코드를 정리하는지에 대해서 이야기합니다."
|
||||
|
||||
@@ -160,7 +160,7 @@ Facebook 개발자 [Bill Fisher](https://twitter.com/fisherwebdev)와 [Jing Chen
|
||||
|
||||
### Server-Side Rendering of Isomorphic Apps at SoundCloud
|
||||
|
||||
<iframe src="https://player.vimeo.com/video/108488724" width="650" height="365" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe src="https://player.vimeo.com/video/108488724" width="100%" height="365" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
Server-side rendering을 위해 [SoundCloud](https://developers.soundcloud.com/blog/)가 React 와 Flux를 사용하는지 by [Andres Suarez](https://github.com/zertosh)
|
||||
[발표 자료와 예제 코드](https://github.com/zertosh/ssr-demo-kit)
|
||||
@@ -169,6 +169,6 @@ Server-side rendering을 위해 [SoundCloud](https://developers.soundcloud.com/b
|
||||
|
||||
### Introducing React Native (+Playlist) - React.js Conf 2015
|
||||
|
||||
<iframe width="650" height="366" src="https://www.youtube-nocookie.com/v/KVZ-P-ZI6W4&index=1&list=PLb0IAmt7-GS1cbw4qonlQztYV1TAW0sCr" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/v/KVZ-P-ZI6W4&index=1&list=PLb0IAmt7-GS1cbw4qonlQztYV1TAW0sCr" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
2015년에 [Tom Occhino](https://twitter.com/tomocchino)님이 React의 과거와 현재를 리뷰하고 나아갈 방향을 제시했습니다.
|
||||
180
docs/community/videos.md
Normal file
180
docs/community/videos.md
Normal file
@@ -0,0 +1,180 @@
|
||||
---
|
||||
id: videos
|
||||
title: Videos
|
||||
layout: community
|
||||
sectionid: community
|
||||
permalink: community/videos.html
|
||||
redirect_from: "docs/videos.html"
|
||||
---
|
||||
|
||||
### Introduction to React
|
||||
|
||||
[Tom Occhino](http://tomocchino.com/) and [Jordan Walke](https://github.com/jordwalke) introduce React at Facebook Seattle.
|
||||
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/XxVg_s8xAms" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
### Introducing React Native
|
||||
|
||||
[Tom Occhino](https://twitter.com/tomocchino) reviews the past and present of React in 2015, and teases where it's going next.
|
||||
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/KVZ-P-ZI6W4?list=PLb0IAmt7-GS1cbw4qonlQztYV1TAW0sCr" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
### Rethinking Web App Development at Facebook
|
||||
|
||||
Delivering reliable, high-performance web experiences at Facebook's scale has required us to challenge some long-held assumptions about software development. Watch this Facebook F8 2014 talk to learn how we abandoned the traditional MVC paradigm in favor of a more functional application architecture.
|
||||
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/nYkdrAPrdcw" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
### Secrets of the Virtual DOM
|
||||
|
||||
[Pete Hunt](http://www.petehunt.net/) at Mountain West JavaScript 2014 discusses why a virtual DOM was built for React, how it compares to other systems, and its relevance to the future of browser technologies.
|
||||
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/h3KksH8gfcQ" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
### Rethinking Best Practices
|
||||
|
||||
[Pete Hunt](http://www.petehunt.net/)'s talk at JSConf EU 2013 covers three topics: throwing out the notion of templates and building views with JavaScript, “re-rendering” your entire application when your data changes, and a lightweight implementation of the DOM and events.
|
||||
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/x7cQ3mrcKaY" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
|
||||
### High performance functional DOM programming
|
||||
|
||||
Tech Talk by [Pete Hunt](http://www.petehunt.net/) at Meteor DevShop 11.
|
||||
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/qqVbr_LaCIo" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
|
||||
### Developing User Interfaces With React
|
||||
|
||||
[Steven Luscher](https://github.com/steveluscher) at Super VanJS 2013.
|
||||
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/1OeXsL5mr4g" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
|
||||
### Introduction to React
|
||||
|
||||
[Stoyan Stefanov](http://www.phpied.com/) at LAWebSpeed meetup.
|
||||
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/SMMRJif5QW0" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
### Going big with React
|
||||
|
||||
Areeb Malik investigates how React performs in a high stress situation, and how it helped his team build safe code on a massive scale.
|
||||
|
||||
[](https://skillsmatter.com/skillscasts/5429-going-big-with-react#video)
|
||||
|
||||
### Backbone + React + Middleman Screencast
|
||||
|
||||
This screencast shows how to integrate Backbone with React using [Backbone-React-Component](https://github.com/magalhas/backbone-react-component).
|
||||
|
||||
<iframe width="100%" height="488" src="https://www.youtube-nocookie.com/embed/iul1fWHVU6A" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
### React, or how to make life simpler
|
||||
|
||||
Tech talk by [Alexander Solovyov](http://solovyov.net/) at FrontEnd Dev Conf '14 (Russian).
|
||||
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/YJNUK0EA_Jo" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
|
||||
### React and Flux: Building Applications with a Unidirectional Data Flow
|
||||
|
||||
Facebook engineers [Bill Fisher](https://twitter.com/fisherwebdev) and [Jing Chen](https://twitter.com/jingc) talk about Flux and React at Forward JS 2014, and how using an application architecture with a unidirectional data flow cleans up a lot of their code.
|
||||
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/i__969noyAM" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
### Server-Side Rendering of Isomorphic Apps at SoundCloud
|
||||
|
||||
Walk-through by [Andres Suarez](https://github.com/zertosh) on how [SoundCloud](https://developers.soundcloud.com/blog/) is using React and Flux for server-side rendering.
|
||||
|
||||
<iframe src="https://player.vimeo.com/video/108488724" width="100%" height="365" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
|
||||
|
||||
> [Slides and sample code](https://github.com/zertosh/ssr-demo-kit)
|
||||
|
||||
### CodeWinds Podcast
|
||||
|
||||
[Pete Hunt](http://www.petehunt.net/) talked with [Jeff Barczewski](http://jeff.barczewski.com/) about React in [CodeWinds Episode 4](http://codewinds.com/podcast/004.html).
|
||||
<figure>[](http://codewinds.com/4)</figure>
|
||||
|
||||
<table width="100%">
|
||||
<tr>
|
||||
<th>02:08</th><td>What is React and why use it?</td>
|
||||
<th>27:17</th><td>Rendering HTML on the server with Node.js. Rendering backends</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>03:08</th><td>The symbiotic relationship of ClojureScript and React</td>
|
||||
<th>29:20</th><td>React evolved through survival of the fittest at Facebook</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>04:54</th><td>The history of React and why it was created</td>
|
||||
<th>30:15</th><td>Ideas for having state on server and client, using web sockets.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>09:43</th><td>Updating web page with React without using data binding</td>
|
||||
<th>32:05</th><td>React-multiuser - distributed shared mutable state using Firebase</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>13:11</th><td>Using the virtual DOM to change the browser DOM</td>
|
||||
<th>33:03</th><td>Better debugging with React using the state transitions, replaying events</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>13:57</th><td>Programming with React, render targets HTML, canvas, other</td>
|
||||
<th>34:08</th><td>Differences from Web Components</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>16:45</th><td>Working with designers. Contrasted with Ember and AngularJS</td>
|
||||
<th>34:25</th><td>Notable companies using React</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>21:45</th><td>JSX Compiler bridging HTML and React javascript</td>
|
||||
<th>35:16</th><td>Could a React backend plugin be created to target PDF?</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>23:50</th><td>Autobuilding JSX and in browser tools for React</td>
|
||||
<th>36:30</th><td>Future of React, what's next?</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>24:50</th><td>Tips and tricks to working with React, getting started</td>
|
||||
<th>39:38</th><td>Contributing and getting help</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
### JavaScript Jabber Podcast
|
||||
|
||||
[Pete Hunt](http://www.petehunt.net/) and [Jordan Walke](https://github.com/jordwalke) talked about React in [JavaScript Jabber 73](https://devchat.tv/js-jabber/073-jsj-react-with-pete-hunt-and-jordan-walke).
|
||||
<figure>[](http://javascriptjabber.com/073-jsj-react-with-pete-hunt-and-jordan-walke/#content)</figure>
|
||||
|
||||
<table width="100%">
|
||||
<tr>
|
||||
<th>01:34</th><td>Pete Hunt Introduction</td>
|
||||
<th>23:06</th><td>Supporting Node.js</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>02:45</th><td>Jordan Walke Introduction</td>
|
||||
<th>24:03</th><td>rendr</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>04:15</th><td>React</td>
|
||||
<th>26:02</th><td>JSX</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>06:38</th><td>60 Frames Per Second</td>
|
||||
<th>30:31</th><td>requestAnimationFrame</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>09:34</th><td>Data Binding</td>
|
||||
<th>34:15</th><td>React and Applications</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>12:31</th><td>Performance</td>
|
||||
<th>38:12</th><td>React Users Khan Academy</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>17:39</th><td>Diffing Algorithm</td>
|
||||
<th>39:53</th><td>Making it work</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>19:36</th><td>DOM Manipulation</td>
|
||||
<th></th><td></td>
|
||||
</tr>
|
||||
</table>
|
||||
@@ -1,14 +1,14 @@
|
||||
---
|
||||
id: videos-zh-CN
|
||||
title: 视频
|
||||
permalink: videos-zh-CN.html
|
||||
permalink: docs/videos-zh-CN.html
|
||||
prev: conferences-zh-CN.html
|
||||
next: complementary-tools-zh-CN.html
|
||||
---
|
||||
|
||||
### Rethinking best practices - JSConf.eu
|
||||
|
||||
<iframe width="650" height="366" src="https://www.youtube-nocookie.com/embed/x7cQ3mrcKaY" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/x7cQ3mrcKaY" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
"在 Facebook 和 Instagram, 我们正在努力挑战React在web上能达到的极限。我的讲话会从对框架的简单介绍开始,然后深入三个有争议的话题:扔掉模板的概念并用JavaScript构建views, 当数据改变 “re-rendering” 你的整个应用,以及一个DOM和events的轻量级实现。" -- [Pete Hunt](http://www.petehunt.net/)
|
||||
|
||||
@@ -23,7 +23,7 @@ next: complementary-tools-zh-CN.html
|
||||
|
||||
### Secrets of the Virtual DOM - MtnWest JS
|
||||
|
||||
<iframe width="650" height="366" src="https://www.youtube-nocookie.com/embed/h3KksH8gfcQ" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/h3KksH8gfcQ" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
"在这次讲座里,我会讨论为什么我们构建了一个虚拟 DOM,它比起其他系统如何,以及它与未来浏览器技术的关系。" -- [Pete Hunt](http://www.petehunt.net/)
|
||||
|
||||
@@ -99,14 +99,14 @@ next: complementary-tools-zh-CN.html
|
||||
|
||||
### Introduction to React.js - Facebook Seattle
|
||||
|
||||
<iframe width="650" height="366" src="https://www.youtube-nocookie.com/embed/XxVg_s8xAms" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/XxVg_s8xAms" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
由 [Tom Occhino](http://tomocchino.com/) 和 [Jordan Walke](https://github.com/jordwalke)
|
||||
|
||||
* * *
|
||||
|
||||
### Backbone + React + Middleman Screencast
|
||||
<iframe width="650" height="488" src="https://www.youtube-nocookie.com/embed/iul1fWHVU6A" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="488" src="https://www.youtube-nocookie.com/embed/iul1fWHVU6A" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
Backbone 是一个在用React实现 REST API 接口的极好方法。这个屏博展示了用 [Backbone-React-Component](https://github.com/magalhas/backbone-react-component)如何整合两者. Middleman 是在本例中使用的框架但很容易被替换成其他框架。对此可支持的template可以在[这里](https://github.com/jbhatab/middleman-backbone-react-template) 找到. -- [Open Minded Innovations](http://www.openmindedinnovations.com/)
|
||||
|
||||
@@ -114,7 +114,7 @@ Backbone 是一个在用React实现 REST API 接口的极好方法。这个屏
|
||||
|
||||
### Developing User Interfaces With React - Super VanJS
|
||||
|
||||
<iframe width="650" height="366" src="https://www.youtube-nocookie.com/embed/1OeXsL5mr4g" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/1OeXsL5mr4g" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
来自 [Steven Luscher](https://github.com/steveluscher)
|
||||
|
||||
@@ -122,7 +122,7 @@ Backbone 是一个在用React实现 REST API 接口的极好方法。这个屏
|
||||
|
||||
### Introduction to React - LAWebSpeed meetup
|
||||
|
||||
<iframe width="650" height="366" src="https://www.youtube-nocookie.com/embed/SMMRJif5QW0" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/SMMRJif5QW0" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
来自 [Stoyan Stefanov](http://www.phpied.com/)
|
||||
|
||||
@@ -130,7 +130,7 @@ Backbone 是一个在用React实现 REST API 接口的极好方法。这个屏
|
||||
|
||||
### React, or how to make life simpler - FrontEnd Dev Conf '14
|
||||
|
||||
<iframe width="650" height="366" src="https://www.youtube-nocookie.com/embed/YJNUK0EA_Jo" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/YJNUK0EA_Jo" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
**俄语** by [Alexander Solovyov](http://solovyov.net/)
|
||||
|
||||
@@ -138,19 +138,19 @@ Backbone 是一个在用React实现 REST API 接口的极好方法。这个屏
|
||||
|
||||
### "Functional DOM programming" - Meteor DevShop 11
|
||||
|
||||
<iframe width="650" height="366" src="https://www.youtube-nocookie.com/embed/qqVbr_LaCIo" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/qqVbr_LaCIo" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
* * *
|
||||
|
||||
### "Rethinking Web App Development at Facebook" - Facebook F8 Conference 2014
|
||||
|
||||
<iframe width="650" height="366" src="https://www.youtube-nocookie.com/embed/nYkdrAPrdcw" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/nYkdrAPrdcw" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
* * *
|
||||
|
||||
### React and Flux: Building Applications with a Unidirectional Data Flow - Forward JS 2014
|
||||
|
||||
<iframe width="650" height="366" src="https://www.youtube-nocookie.com/embed/i__969noyAM" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/i__969noyAM" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
Facebook 工程师 [Bill Fisher](https://twitter.com/fisherwebdev) 和 [Jing Chen](https://twitter.com/jingc) 谈论 Flux 和 React, 以及如何使用单向数据流的程序架构清理他们的代码 .
|
||||
|
||||
@@ -158,7 +158,7 @@ Facebook 工程师 [Bill Fisher](https://twitter.com/fisherwebdev) 和 [Jing Che
|
||||
|
||||
### Server-Side Rendering of Isomorphic Apps at SoundCloud
|
||||
|
||||
<iframe src="https://player.vimeo.com/video/108488724" width="650" height="365" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
|
||||
<iframe src="https://player.vimeo.com/video/108488724" width="100%" height="365" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
|
||||
|
||||
来自 [Andres Suarez](https://github.com/zertosh) 的演练,关于 [SoundCloud](https://developers.soundcloud.com/blog/) 如何使用 React 和 Flux 在服务器端渲染.
|
||||
|
||||
@@ -168,6 +168,6 @@ Facebook 工程师 [Bill Fisher](https://twitter.com/fisherwebdev) 和 [Jing Che
|
||||
|
||||
### Introducing React Native (+Playlist) - React.js Conf 2015
|
||||
|
||||
<iframe width="650" height="366" src="https://www.youtube-nocookie.com/embed/KVZ-P-ZI6W4?list=PLb0IAmt7-GS1cbw4qonlQztYV1TAW0sCr" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/KVZ-P-ZI6W4?list=PLb0IAmt7-GS1cbw4qonlQztYV1TAW0sCr" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
[Tom Occhino](https://twitter.com/tomocchino) 回顾了React的过去和现在,在2015年。梳理了下一步要做什么。
|
||||
412
docs/contributing/codebase-overview.md
Normal file
412
docs/contributing/codebase-overview.md
Normal file
@@ -0,0 +1,412 @@
|
||||
---
|
||||
id: codebase-overview
|
||||
title: Codebase Overview
|
||||
layout: contributing
|
||||
permalink: contributing/codebase-overview.html
|
||||
prev: how-to-contribute.html
|
||||
next: implementation-notes.html
|
||||
---
|
||||
|
||||
This section will give you an overview of the React codebase organization, its conventions, and the implementation.
|
||||
|
||||
If you want to [contribute to React](/react/contributing/how-to-contribute.html) we hope that this guide will help you feel more comfortable making changes.
|
||||
|
||||
We don't necessarily recommend any of these conventions in React apps. Many of them exist for historical reasons and might change with time.
|
||||
|
||||
### Custom Module System
|
||||
|
||||
At Facebook, internally we use a custom module system called "Haste". It is similar to [CommonJS](https://nodejs.org/docs/latest/api/modules.html) and also uses `require()` but has a few important differences that often confuse outside contributors.
|
||||
|
||||
In CommonJS, when you import a module, you need to specify its relative path:
|
||||
|
||||
```js
|
||||
// Importing from the same folder:
|
||||
var setInnerHTML = require('./setInnerHTML');
|
||||
|
||||
// Importing from a different folder:
|
||||
var setInnerHTML = require('../utils/setInnerHTML');
|
||||
|
||||
// Importing from a deeply nested folder:
|
||||
var setInnerHTML = require('../client/utils/setInnerHTML');
|
||||
```
|
||||
|
||||
However, with Haste **all filenames are globally unique.** In the React codebase, you can import any module from any other module by its name alone:
|
||||
|
||||
```js
|
||||
var setInnerHTML = require('setInnerHTML');
|
||||
```
|
||||
|
||||
Haste was originally developed for giant apps like Facebook. It's easy to move files to different folders and import them without worrying about relative paths. The fuzzy file search in any editor always takes you to the correct place thanks to globally unique names.
|
||||
|
||||
React itself was extracted from the Facebook codebase and uses Haste for historical reasons. In the future, we will probably [migrate React to use CommonJS or ES Modules](https://github.com/facebook/react/issues/6336) to be more aligned with the community. However, this requires changes in Facebook internal infrastructure so it is unlikely to happen very soon.
|
||||
|
||||
**Haste will make more sense to you if you remember a few rules:**
|
||||
|
||||
* All filenames in the React source code are unique. This is why they're sometimes verbose.
|
||||
* When you add a new file, make sure you include a [license header](https://github.com/facebook/react/blob/87724bd87506325fcaf2648c70fc1f43411a87be/src/renderers/dom/client/utils/setInnerHTML.js#L1-L10). You can copy it from any existing file. A license header always includes [a line like this](https://github.com/facebook/react/blob/87724bd87506325fcaf2648c70fc1f43411a87be/src/renderers/dom/client/utils/setInnerHTML.js#L9). Change it to match the name of the file you created.
|
||||
* Don’t use relative paths when importing. Instead of `require('./setInnerHTML')`, write `require('setInnerHTML')`.
|
||||
|
||||
When we compile React for npm, a script copies all the modules into [a single flat directory called `lib`](https://unpkg.com/react@15/lib/) and prepends all `require()` paths with `./`. This way Node, Browserify, Webpack, and other tools can understand React build output without being aware of Haste.
|
||||
|
||||
**If you're reading React source on GitHub and want to jump to a file, press "t".**
|
||||
|
||||
This is a GitHub shortcut for searching the current repo for fuzzy filename matches. Start typing the name of the file you are looking for, and it will show up as the first match.
|
||||
|
||||
### External Dependencies
|
||||
|
||||
React has almost no external dependencies. Usually, a `require()` points to a file in React's own codebase. However, there are a few relatively rare exceptions.
|
||||
|
||||
If you see a `require()` that does not correspond to a file in the React repository, you can look in a special repository called [fbjs](https://github.com/facebook/fbjs). For example, `require('warning')` will resolve to the [`warning` module from fbjs](https://github.com/facebook/fbjs/blob/df9047fec0bbd1e64635ae369c045975777cba7c/packages/fbjs/src/__forks__/warning.js).
|
||||
|
||||
The [fbjs repository](https://github.com/facebook/fbjs) exists because React shares some small utilities with libraries like [Relay](https://github.com/facebook/relay), and we keep them in sync. We don't depend on equivalent small modules in the Node ecosystem because we want Facebook engineers to be able to make changes to them whenever necessary. None of the utilities inside fbjs are considered to be public API, and they are only intended for use by Facebook projects such as React.
|
||||
|
||||
### Top-Level Folders
|
||||
|
||||
After cloning the [React repository](https://github.com/facebook/react), you will see a few top-level folders in it:
|
||||
|
||||
* [`src`](https://github.com/facebook/react/tree/master/src) is the source code of React. **If your change is related to the code, `src` is where you'll spend most of your time.**
|
||||
* [`docs`](https://github.com/facebook/react/tree/master/docs) is the React documentation website. When you change APIs, make sure to update the relevant Markdown files.
|
||||
* [`examples`](https://github.com/facebook/react/tree/master/examples) contains a few small React demos with different build setups.
|
||||
* [`packages`](https://github.com/facebook/react/tree/master/packages) contains metadata (such as `package.json`) for all packages in the React repository. Nevertheless, their source code is still located inside [`src`](https://github.com/facebook/react/tree/master/src).
|
||||
* `build` is the build output of React. It is not in the repository but it will appear in your React clone after you [build it](/react/contributing/how-to-contribute.html#development-workflow) for the first time.
|
||||
|
||||
There are a few other top-level folders but they are mostly used for the tooling and you likely won't ever encounter them when contributing.
|
||||
|
||||
### Colocated Tests
|
||||
|
||||
We don't have a top-level directory for unit tests. Instead, we put them into a directory called `__tests__` relative to the files that they test.
|
||||
|
||||
For example, a test for [`setInnerHTML.js`](https://github.com/facebook/react/blob/87724bd87506325fcaf2648c70fc1f43411a87be/src/renderers/dom/client/utils/setInnerHTML.js) is located in [`__tests__/setInnerHTML-test.js`](https://github.com/facebook/react/blob/87724bd87506325fcaf2648c70fc1f43411a87be/src/renderers/dom/client/utils/__tests__/setInnerHTML-test.js) right next to it.
|
||||
|
||||
### Shared Code
|
||||
|
||||
Even though Haste allows us to import any module from anywhere in the repository, we follow a convention to avoid cyclic dependencies and other unpleasant surprises. By convention, a file may only import files in the same folder or in subfolders below.
|
||||
|
||||
For example, files inside [`src/renderers/dom/client`](https://github.com/facebook/react/tree/master/src/renderers/dom/client) may import other files in the same folder or any folder below.
|
||||
|
||||
However they can't import modules from [`src/renderers/dom/server`](https://github.com/facebook/react/tree/master/src/renderers/dom/server) because it is not a child directory of [`src/renderers/dom/client`](https://github.com/facebook/react/tree/master/src/renderers/dom/client).
|
||||
|
||||
There is an exception to this rule. Sometimes we *do* need to share functionality between two groups of modules. In this case, we hoist the shared module up to a folder called `shared` inside the closest common ancestor folder of the modules that need to rely on it.
|
||||
|
||||
For example, code shared between [`src/renderers/dom/client`](https://github.com/facebook/react/tree/master/src/renderers/dom/client) and [`src/renderers/dom/server`](https://github.com/facebook/react/tree/master/src/renderers/dom/server) lives in [`src/renderers/dom/shared`](https://github.com/facebook/react/tree/master/src/renderers/dom/shared).
|
||||
|
||||
By the same logic, if [`src/renderers/dom/client`](https://github.com/facebook/react/tree/master/src/renderers/dom/client) needs to share a utility with something in [`src/renderers/native`](https://github.com/facebook/react/tree/master/src/renderers/native), this utility would be in [`src/renderers/shared`](https://github.com/facebook/react/tree/master/src/renderers/shared).
|
||||
|
||||
This convention is not enforced but we check for it during a pull request review.
|
||||
|
||||
### Warnings and Invariants
|
||||
|
||||
The React codebase uses the `warning` module to display warnings:
|
||||
|
||||
```js
|
||||
var warning = require('warning');
|
||||
|
||||
warning(
|
||||
2 + 2 === 4,
|
||||
'Math is not working today.'
|
||||
);
|
||||
```
|
||||
|
||||
**The warning is shown when the `warning` condition is `false`.**
|
||||
|
||||
One way to think about it is that the condition should reflect the normal situation rather than the exceptional one.
|
||||
|
||||
It is a good idea to avoid spamming the console with duplicate warnings:
|
||||
|
||||
````js
|
||||
var warning = require('warning');
|
||||
|
||||
var didWarnAboutMath = false;
|
||||
if (!didWarnAboutMath) {
|
||||
warning(
|
||||
2 + 2 === 4,
|
||||
'Math is not working today.'
|
||||
);
|
||||
didWarnAboutMath = true;
|
||||
}
|
||||
```
|
||||
|
||||
Warnings are only enabled in development. In production, they are completely stripped out. If you need to forbid some code path from executing, use `invariant` module instead:
|
||||
|
||||
```js
|
||||
var invariant = require('invariant');
|
||||
|
||||
invariant(
|
||||
2 + 2 === 4,
|
||||
'You shall not pass!'
|
||||
);
|
||||
```
|
||||
|
||||
**The invariant is thrown when the `invariant` condition is `false`.**
|
||||
|
||||
"Invariant" is just a way of saying "this condition always holds true". You can think about it as making an assertion.
|
||||
|
||||
It is important to keep development and production behavior similar, so `invariant` throws both in development and in production. The error messages are automatically replaced with error codes in production to avoid negatively affecting the byte size.
|
||||
|
||||
### Development and Production
|
||||
|
||||
You can use `__DEV__` pseudo-global variable in the codebase to guard development-only blocks of code.
|
||||
|
||||
It is inlined during the compile step, and turns into `process.env.NODE_ENV !== 'production'` checks in the CommonJS builds.
|
||||
|
||||
For standalone builds, it becomes `true` in the unminified build, and gets completely stripped out with the `if` blocks it guards in the minified build.
|
||||
|
||||
```js
|
||||
if (__DEV__) {
|
||||
// This code will only run in development.
|
||||
}
|
||||
```
|
||||
|
||||
### JSDoc
|
||||
|
||||
Some of the internal and public methods are annotated with [JSDoc annotations](http://usejsdoc.org/):
|
||||
|
||||
```js
|
||||
/**
|
||||
* Updates this component by updating the text content.
|
||||
*
|
||||
* @param {ReactText} nextText The next text content
|
||||
* @param {ReactReconcileTransaction} transaction
|
||||
* @internal
|
||||
*/
|
||||
receiveComponent: function(nextText, transaction) {
|
||||
// ...
|
||||
},
|
||||
```
|
||||
|
||||
We try to keep existing annotations up-to-date but we don't enforce them. We don't use JSDoc in the newly written code, and instead use Flow to document and enforce types.
|
||||
|
||||
### Flow
|
||||
|
||||
We recently started introducing [Flow](https://flowtype.org/) checks to the codebase. Files marked with the `@flow` annotation in the license header comment are being typechecked.
|
||||
|
||||
We accept pull requests [adding Flow annotations to existing code](https://github.com/facebook/react/pull/7600/files). Flow annotations look like this:
|
||||
|
||||
```js
|
||||
ReactRef.detachRefs = function(
|
||||
instance: ReactInstance,
|
||||
element: ReactElement | string | number | null | false,
|
||||
): void {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
When possible, new code should use Flow annotations.
|
||||
You can run `npm run flow` locally to check your code with Flow.
|
||||
|
||||
### Classes and Mixins
|
||||
|
||||
React was originally written in ES5. We have since enabled ES6 features with [Babel](http://babeljs.io/), including classes. However, most of React code is still written in ES5.
|
||||
|
||||
In particular, you might see the following pattern quite often:
|
||||
|
||||
```js
|
||||
// Constructor
|
||||
function ReactDOMComponent(element) {
|
||||
this._currentElement = element;
|
||||
}
|
||||
|
||||
// Methods
|
||||
ReactDOMComponent.Mixin = {
|
||||
mountComponent: function() {
|
||||
// ...
|
||||
}
|
||||
};
|
||||
|
||||
// Put methods on the prototype
|
||||
Object.assign(
|
||||
ReactDOMComponent.prototype,
|
||||
ReactDOMComponent.Mixin
|
||||
);
|
||||
|
||||
module.exports = ReactDOMComponent;
|
||||
```
|
||||
|
||||
The `Mixin` in this code has no relation to React `mixins` feature. It is just a way of grouping a few methods under an object. Those methods may later get attached to some other class. We use this pattern in a few places although we try to avoid it in the new code.
|
||||
|
||||
Equivalent code in ES6 would like this:
|
||||
|
||||
```js
|
||||
class ReactDOMComponent {
|
||||
constructor(element) {
|
||||
this._currentElement = element;
|
||||
}
|
||||
|
||||
mountComponent() {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ReactDOMComponent;
|
||||
```
|
||||
|
||||
Sometimes we [convert old code to ES6 classes](https://github.com/facebook/react/pull/7647/files). However, this is not very important to us because there is an [ongoing effort](#fiber-reconciler) to replace the React reconciler implementation with a less object-oriented approach which wouldn't use classes at all.
|
||||
|
||||
### Dynamic Injection
|
||||
|
||||
React uses dynamic injection in some modules. While it is always explicit, it is still unfortunate because it hinders understanding of the code. The main reason it exists is because React originally only supported DOM as a target. React Native started as a React fork. We had to add dynamic injection to let React Native override some behaviors.
|
||||
|
||||
You may see modules declaring their dynamic dependencies like this:
|
||||
|
||||
```js
|
||||
// Dynamically injected
|
||||
var textComponentClass = null;
|
||||
|
||||
// Relies on dynamically injected value
|
||||
function createInstanceForText(text) {
|
||||
return new textComponentClass(text);
|
||||
}
|
||||
|
||||
var ReactHostComponent = {
|
||||
createInstanceForText,
|
||||
|
||||
// Provides an opportunity for dynamic injection
|
||||
injection: {
|
||||
injectTextComponentClass: function(componentClass) {
|
||||
textComponentClass = componentClass;
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = ReactHostComponent;
|
||||
```
|
||||
|
||||
The `injection` field is not handled specially in any way. But by convention, it means that this module wants to have some (presumably platform-specific) dependencies injected into it at runtime.
|
||||
|
||||
In React DOM, [`ReactDefaultInjection`](https://github.com/facebook/react/blob/4f345e021a6bd9105f09f3aee6d8762eaa9db3ec/src/renderers/dom/shared/ReactDefaultInjection.js) injects a DOM-specific implementation:
|
||||
|
||||
```js
|
||||
ReactHostComponent.injection.injectTextComponentClass(ReactDOMTextComponent);
|
||||
```
|
||||
|
||||
In React Native, [`ReactNativeDefaultInjection`](https://github.com/facebook/react/blob/4f345e021a6bd9105f09f3aee6d8762eaa9db3ec/src/renderers/native/ReactNativeDefaultInjection.js) injects its own implementation:
|
||||
|
||||
```js
|
||||
ReactHostComponent.injection.injectTextComponentClass(ReactNativeTextComponent);
|
||||
```
|
||||
|
||||
There are multiple injection points in the codebase. In the future, we intend to get rid of the dynamic injection mechanism and wire up all the pieces statically during the build.
|
||||
|
||||
### Multiple Packages
|
||||
|
||||
React is a [monorepo](http://danluu.com/monorepo/). Its repository contains multiple separate packages so that their changes can be coordinated together, and documentation and issues live in one place.
|
||||
|
||||
The npm metadata such as `package.json` files is located in the [`packages`](https://github.com/facebook/react/tree/master/packages) top-level folder. However, there is almost no real code in it.
|
||||
|
||||
For example, [`packages/react/react.js`](https://github.com/facebook/react/blob/87724bd87506325fcaf2648c70fc1f43411a87be/packages/react/react.js) re-exports [`src/isomorphic/React.js`](https://github.com/facebook/react/blob/87724bd87506325fcaf2648c70fc1f43411a87be/src/isomorphic/React.js), the real npm entry point. Other packages mostly repeat this pattern. All the important code lives in [`src`](https://github.com/facebook/react/tree/master/src).
|
||||
|
||||
While the code is separated in the source tree, the exact package boundaries are slightly different for npm packages and standalone browser builds.
|
||||
|
||||
### React Core
|
||||
|
||||
The "core" of React includes all the [top-level `React` APIs](/react/docs/top-level-api.html#react), for example:
|
||||
|
||||
* `React.createElement()`
|
||||
* `React.createClass()`
|
||||
* `React.Component`
|
||||
* `React.Children`
|
||||
* `React.PropTypes`
|
||||
|
||||
**React core only includes the APIs necessary to define components.** It does not include the [reconciliation](/react/docs/reconciliation.html) algorithm or any platform-specific code. It is used both by React DOM and React Native components.
|
||||
|
||||
The code for React core is located in [`src/isomorphic`](https://github.com/facebook/react/tree/master/src/isomorphic) in the source tree. It is available on npm as the [`react`](https://www.npmjs.com/package/react) package. The corresponding standalone browser build is called `react.js`, and it exports a global called `React`.
|
||||
|
||||
>**Note:**
|
||||
>
|
||||
>Until very recently, `react` npm package and `react.js` standalone build contained all React code (including React DOM) rather than just the core. This was done for backward compatibility and historical reasons. Since React 15.4.0, the core is better separated in the build output.
|
||||
>
|
||||
>There is also an additional standalone browser build called `react-with-addons.js` which we will consider separately further below.
|
||||
|
||||
### Renderers
|
||||
|
||||
React was originally created for the DOM but it was later adapted to also support native platforms with [React Native](http://facebook.github.io/react-native/). This introduced the concept of "renderers" to React internals.
|
||||
|
||||
**Renderers manage how a React tree turns into the underlying platform calls.**
|
||||
|
||||
Renderers are located in [`src/renderers`](https://github.com/facebook/react/tree/master/src/renderers/):
|
||||
|
||||
* [React DOM Renderer](https://github.com/facebook/react/tree/master/src/renderers/dom) renders React components to the DOM. It implements [top-level `ReactDOM` APIs](/react/docs/top-level-api.html#reactdom) and is available as [`react-dom`](https://www.npmjs.com/package/react-dom) npm package. It can also be used as standalone browser bundle called `react-dom.js` that exports a `ReactDOM` global.
|
||||
* [React Native Renderer](https://github.com/facebook/react/tree/master/src/renderers/native) renders React components to native views. It is used internally by React Native via [`react-native-renderer`](https://www.npmjs.com/package/react-native-renderer) npm package. In the future a copy of it may get checked into the React Native [repository](https://github.com/facebook/react-native) so that React Native can update React at its own pace.
|
||||
* [React Test Renderer](https://github.com/facebook/react/tree/master/src/renderers/testing) renders React components to JSON trees. It is used by the [Snapshot Testing](https://facebook.github.io/jest/blog/2016/07/27/jest-14.html) feature of [Jest](https://facebook.github.io/jest) and is available as [react-test-renderer](https://www.npmjs.com/package/react-test-renderer) npm package.
|
||||
|
||||
The only other officially supported renderer is [`react-art`](https://github.com/reactjs/react-art). To avoid accidentally breaking it as we make changes to React, we checked it in as [`src/renderers/art`](https://github.com/facebook/react/tree/master/src/renderers/art) and run its test suite. Nevertheless, its [GitHub repository](https://github.com/reactjs/react-art) still acts as the source of truth.
|
||||
|
||||
While it is [technically possible](https://github.com/iamdustan/tiny-react-renderer) to create custom React renderer, this is currently not officially supported. There is no stable public contract for custom renderers yet which is another reason why we keep them all in a single place.
|
||||
|
||||
>**Note:**
|
||||
>
|
||||
>Technically the [`native`](https://github.com/facebook/react/tree/master/src/renderers/native) renderer is a very thin layer that teaches React to interact with React Native implementation. The real platform-specific code managing the native views lives in the [React Native repository](https://github.com/facebook/react-native) together with its components.
|
||||
|
||||
### Reconcilers
|
||||
|
||||
Even vastly different renderers like React DOM and React Native need to share a lot of logic. In particular, the [reconciliation](/react/docs/reconciliation.html) algorithm should be as similar as possible so that declarative rendering, custom components, state, lifecycle methods, and refs work consistently across platforms.
|
||||
|
||||
To solve this, different renderers share some code between them. We call this part of React a "reconciler". When an update such as `setState()` is scheduled, the reconciler calls `render()` on components in the tree and mounts, updates, or unmounts them.
|
||||
|
||||
Reconcilers are not packaged separately because they currently have no public API. Instead, they are exclusively used by renderers such as React DOM and React Native.
|
||||
|
||||
### Stack Reconciler
|
||||
|
||||
The "stack" reconciler is the one powering all React production code today. It is located in [`src/renderers/shared/stack/reconciler`](https://github.com/facebook/react/tree/master/src/renderers/shared/stack) and is used by both React DOM and React Native.
|
||||
|
||||
It is written in an [object-oriented way](https://en.wikipedia.org/wiki/Composite_pattern) and maintains a separate tree of "internal instances" for all React components. The internal instances exist both for user-defined ("composite") and platform-specific ("host") components. The internal instances are inaccessible directly to the user, and their tree is never exposed.
|
||||
|
||||
When a component mounts, updates, or unmounts, the stack reconciler calls a method on that internal instance. The methods are called `mountComponent(element)`, `receiveComponent(nextElement)`, and `unmountComponent(element)`.
|
||||
|
||||
#### Host Components
|
||||
|
||||
Platform-specific ("host") components, such as `<div>` or a `<View>`, run platform-specific code. For example, React DOM instructs the stack reconciler to use [`ReactDOMComponent`](https://github.com/facebook/react/blob/87724bd87506325fcaf2648c70fc1f43411a87be/src/renderers/dom/shared/ReactDOMComponent.js) to handle [mounting](https://github.com/facebook/react/blob/87724bd87506325fcaf2648c70fc1f43411a87be/src/renderers/dom/shared/ReactDOMComponent.js#L517), [updates](https://github.com/facebook/react/blob/87724bd87506325fcaf2648c70fc1f43411a87be/src/renderers/dom/shared/ReactDOMComponent.js#L865), and [unmounting](https://github.com/facebook/react/blob/87724bd87506325fcaf2648c70fc1f43411a87be/src/renderers/dom/shared/ReactDOMComponent.js#L1140) of DOM components.
|
||||
|
||||
Regardless of the platform, both `<div>` and `<View>` handle managing multiple children in a similar way. For convenience, the stack reconciler provides a helper called [`ReactMultiChild`](https://github.com/facebook/react/blob/87724bd87506325fcaf2648c70fc1f43411a87be/src/renderers/shared/stack/reconciler/ReactMultiChild.js) that both DOM and Native renderers [use](https://github.com/facebook/react/blob/87724bd87506325fcaf2648c70fc1f43411a87be/src/renderers/dom/shared/ReactDOMComponent.js#L1203).
|
||||
|
||||
#### Composite Components
|
||||
|
||||
User-defined ("composite") components should behave the same way with all renderers. This is why the stack reconciler provides a shared implementation in [`ReactCompositeComponent`](https://github.com/facebook/react/blob/87724bd87506325fcaf2648c70fc1f43411a87be/src/renderers/shared/stack/reconciler/ReactCompositeComponent.js). It is always the same regardless of the renderer.
|
||||
|
||||
Composite components also implement [mounting](https://github.com/facebook/react/blob/87724bd87506325fcaf2648c70fc1f43411a87be/src/renderers/shared/stack/reconciler/ReactCompositeComponent.js#L181), [updating](https://github.com/facebook/react/blob/87724bd87506325fcaf2648c70fc1f43411a87be/src/renderers/shared/stack/reconciler/ReactCompositeComponent.js#L703), and [unmounting](https://github.com/facebook/react/blob/87724bd87506325fcaf2648c70fc1f43411a87be/src/renderers/shared/stack/reconciler/ReactCompositeComponent.js#L524). However, unlike host components, `ReactCompositeComponent` needs to behave differently depending on user's code. This is why it calls methods, such as `render()` and `componentDidMount()`, on the user-supplied class.
|
||||
|
||||
During an update, `ReactCompositeComponent` checks whether the `render()` output has a different `type` or `key` than the last time. If neither `type` nor `key` has changed, it delegates the update to the existing child internal instance. Otherwise, it unmounts the old child instance and mounts a new one. This is described in the [reconciliation algorithm](/react/docs/reconciliation.html).
|
||||
|
||||
#### Recursion
|
||||
|
||||
During an update, the stack reconciler "drills down" through composite components, runs their `render()` methods, and decides whether to update or replace their single child instance. It executes platform-specific code as it passes through the host components like `<div>` and `<View>`. Host components may have multiple children which are also processed recursively.
|
||||
|
||||
It is important to understand that the stack reconciler always processes the component tree synchronously in a single pass. While individual tree branches may [bail out of reconciliation](/react/docs/advanced-performance.html#avoiding-reconciling-the-dom), the stack reconciler can't pause, and so it is suboptimal when the updates are deep and the available CPU time is limited.
|
||||
|
||||
#### Learn More
|
||||
|
||||
**The [next section](/react/contributing/implementation-notes.html) describes the current implementation in more details.**
|
||||
|
||||
### Fiber Reconciler
|
||||
|
||||
The "fiber" reconciler is a new effort aiming to resolve the problems inherent in the stack reconciler and fix a few long-standing issues.
|
||||
|
||||
It is a complete rewrite of the reconciler and is currently [in active development](https://github.com/facebook/react/pulls?utf8=%E2%9C%93&q=is%3Apr%20is%3Aopen%20fiber).
|
||||
|
||||
Its main goals are:
|
||||
|
||||
* Ability to split interruptible work in chunks.
|
||||
* Ability to prioritize, rebase and reuse work in progress.
|
||||
* Ability to yield back and forth between parents and children to support layout in React.
|
||||
* Ability to return multiple elements from `render()`.
|
||||
* Better support for error boundaries.
|
||||
|
||||
You can read more about it in [React Fiber Architecture](https://github.com/acdlite/react-fiber-architecture). At this moment, it is still very experimental, and far from feature parity with the stack reconciler.
|
||||
|
||||
Its source code is located in [`src/renderers/shared/fiber`](https://github.com/facebook/react/tree/master/src/renderers/shared/fiber).
|
||||
|
||||
### Event System
|
||||
|
||||
React implements a synthetic event system which is agnostic of the renderers and works both with React DOM and React Native. Its source code is located in [`src/renderers/shared/shared/event`](https://github.com/facebook/react/tree/master/src/renderers/shared/shared/event).
|
||||
|
||||
There is a [video with a deep code dive into it](https://www.youtube.com/watch?v=dRo_egw7tBc) (66 mins).
|
||||
|
||||
### Add-ons
|
||||
|
||||
Each of the [React add-ons](/react/docs/addons.html) ships as a separate package on npm with a `react-addons-` prefix. Their source is located in [`src/addons`](https://github.com/facebook/react/tree/master/src/addons) with the exception of [`ReactPerf`](https://github.com/facebook/react/blob/master/src/renderers/shared/ReactPerf.js) and [`ReactTestUtils`](https://github.com/facebook/react/blob/master/src/test/ReactTestUtils.js).
|
||||
|
||||
Additionally, we provide a standalone build called `react-with-addons.js` which includes React core *and* all add-ons exposed on the `addons` field of the `React` global object.
|
||||
|
||||
### What Next?
|
||||
|
||||
Read the [next section](/react/contributing/implementation-notes.html) to learn about the current implementation of reconciler in more detail.
|
||||
161
docs/contributing/design-principles.md
Normal file
161
docs/contributing/design-principles.md
Normal file
@@ -0,0 +1,161 @@
|
||||
---
|
||||
id: design-principles
|
||||
title: Design Principles
|
||||
layout: contributing
|
||||
permalink: contributing/design-principles.html
|
||||
prev: implementation-notes.html
|
||||
---
|
||||
|
||||
We wrote this document so that you have a better idea of how we decide what React does and what React doesn't do, and what our development philosophy is like. While we are excited to see community contributions, we are not likely to choose a path that violates one or more of these principles.
|
||||
|
||||
>**Note:**
|
||||
>
|
||||
>This document assumes a strong understanding of React. It describes the design principles of *React itself*, not React components or applications.
|
||||
>
|
||||
>For an introduction to React, check out [Thinking in React](/react/docs/thinking-in-react.html) instead.
|
||||
|
||||
### Composition
|
||||
|
||||
The key feature of React is composition of components. Components written by different people should work well together. It is important to us that you can add functionality to a component without causing rippling changes throughout the codebase.
|
||||
|
||||
For example, it should be possible to introduce some local state into a component without changing any of the components using it. Similarly, it should be possible to add some initialization and teardown code to any component when necessary.
|
||||
|
||||
There is nothing "bad" about using state or lifecycle hooks in components. Like any powerful features, they should be used in moderation, but we have no intention to remove them. On the contrary, we think they are integral parts of what makes React useful. We might enable [more functional patterns](https://github.com/reactjs/react-future/tree/master/07%20-%20Returning%20State) in the future, but both local state and lifecycle hooks will be a part of that model.
|
||||
|
||||
Components are often described as "just functions" but in our view they need to be more than that to be useful. In React, components describe any composable behavior, and this includes rendering, lifecycle, and state. Some external libraries like [Relay](http://facebook.github.io/relay/) augment components with other responsibilities such as describing data dependencies. It is possible that those ideas might make it back into React too in some form.
|
||||
|
||||
### Common Abstraction
|
||||
|
||||
In general we [resist adding features](https://www.youtube.com/watch?v=4anAwXYqLG8) that can be implemented in userland. We don't want to bloat your apps with useless library code. However, there are exceptions to this.
|
||||
|
||||
For example, if React didn't provide support for local state or lifecycle hooks, people would create custom abstractions for them. When there are multiple abstractions competing, React can't enforce or take advantage of the properties of either of them. It has to work with the lowest common denominator.
|
||||
|
||||
This is why sometimes we add features to React itself. If we notice that many components implement a certain feature in incompatible or inefficient ways, we might prefer to bake it into React. We don't do it lightly. When we do it, it's because we are confident that raising the abstraction level benefits the whole ecosystem. State, lifecycle hooks, cross-browser event normalization are good examples of this.
|
||||
|
||||
We always discuss such improvement proposals with the community. You can find some of those discussions by the [“big picture”](https://github.com/facebook/react/issues?q=is%3Aopen+is%3Aissue+label%3A%22big+picture%22) label on the React issue tracker.
|
||||
|
||||
### Escape Hatches
|
||||
|
||||
React is pragmatic. It is driven by the needs of the products written at Facebook. While it is influenced by some paradigms that are not yet fully mainstream such as functional programming, staying accessible to a wide range of developers with different skills and experience levels is an explicit goal of the project.
|
||||
|
||||
If we want to deprecate a pattern that we don't like, it is our responsibility to consider all existing use cases for it and [educate the community about the alternatives](/react/blog/2016/07/13/mixins-considered-harmful.html) before we deprecate it. If some pattern that is useful for building apps is hard to express in a declarative way, we will [provide an imperative API](/react/docs/more-about-refs.html) for it. If we can't figure out a perfect API for something that we found necessary in many apps, we will [provide a temporary subpar working API](/react/docs/context.html) as long as it is possible to get rid of it later and it leaves the door open for future improvements.
|
||||
|
||||
### Stability
|
||||
|
||||
We value API stability. At Facebook, we have more than 20 thousand components using React. Many other companies, including [Twitter](https://twitter.com/) and [Airbnb](https://www.airbnb.com/), are also heavy users of React. This is why we are usually reluctant to change public APIs or behavior.
|
||||
|
||||
However we think stability in the sense of "nothing changes" is overrated. It quickly turns into stagnation. Instead, we prefer the stability in the sense of "It is heavily used in production, and when something changes, there is a clear (and preferably automated) migration path."
|
||||
|
||||
When we deprecate a pattern, we study its internal usage at Facebook and add deprecation warnings. They let us assess the impact of the change. Sometimes we back out if we see that it is too early, and we need to think more strategically about getting the codebases to the point where they are ready for this change.
|
||||
|
||||
If we are confident that the change is not too disruptive and the migration strategy is viable for all use cases, we release the deprecation warning to the open source community. We are closely in touch with many users of React outside of Facebook, and we monitor popular open source projects and guide them in fixing those deprecations.
|
||||
|
||||
Given the sheer size of the Facebook React codebase, successful internal migration is often a good indicator that other companies won't have problems either. Nevertheless sometimes people point out additional use cases we haven't thought of, and we add escape hatches for them or rethink our approach.
|
||||
|
||||
We don't deprecate anything without a good reason. We recognize that sometimes deprecations warnings cause frustration but we add them because deprecations clean up the road for the improvements and new features that we and many people in the community consider valuable.
|
||||
|
||||
For example, we added a [warning about unknown DOM props](/react/warnings/unknown-prop.html) in React 15.2.0. Many projects were affected by this. However fixing this warning is important so that we can introduce the support for [custom attributes](https://github.com/facebook/react/issues/140) to React. There is a reason like this behind every deprecation that we add.
|
||||
|
||||
When we add a deprecation warning, we keep it for the rest of the current major version, and [change the behavior in the next major version](/react/blog/2016/02/19/new-versioning-scheme.html). If there is a lot of repetitive manual work involved, we release a [codemod](https://www.youtube.com/watch?v=d0pOgY8__JM) script that automates most of the change. Codemods enable us to move forward without stagnation in a massive codebase, and we encourage you to use them as well.
|
||||
|
||||
You can find the codemods that we released in the [react-codemod](https://github.com/reactjs/react-codemod) repository.
|
||||
|
||||
### Interoperability
|
||||
|
||||
We place high value in interoperability with existing systems and gradual adoption. Facebook has a massive non-React codebase. Its website uses a mix of a server-side component system called XHP, internal UI libraries that came before React, and React itself. It is important to us that any product team can [start using React for a small feature](https://www.youtube.com/watch?v=BF58ZJ1ZQxY) rather than rewrite their code to bet on it.
|
||||
|
||||
This is why React provides escape hatches to work with mutable models, and tries to work well together with other UI libraries. You can wrap an existing imperative UI into a declarative component, and vice versa. This is crucial for gradual adoption.
|
||||
|
||||
### Scheduling
|
||||
|
||||
Even when your components are described as functions, when you use React you don't call them directly. Every component returns a [description of what needs to be rendered](/react/blog/2015/12/18/react-components-elements-and-instances.html#elements-describe-the-tree), and that description may include both user-written components like `<LikeButton>` and platform-specific components like `<div>`. It is up to React to "unroll" `<LikeButton>` at some point in the future and actually apply changes to the UI tree according to the render results of the components recursively.
|
||||
|
||||
This is a subtle distinction but a powerful one. Since you don't call that component function but let React call it, it means React has the power to delay calling it if necessary. In its current implementation React walks the tree recursively and calls render functions of the whole updated tree during a single tick. However in the future it might start [delaying some updates to avoid dropping frames](https://github.com/facebook/react/issues/6170).
|
||||
|
||||
This is a common theme in React design. Some popular libraries implement the "push" approach where computations are performed when the new data is available. React, however, sticks to the "pull" approach where computations can be delayed until necessary.
|
||||
|
||||
React is not a generic data processing library. It is a library for building user interfaces. We think that it is uniquely positioned in an app to know which computations are relevant right now and which are not.
|
||||
|
||||
If something is offscreen, we can delay any logic related to it. If data is arriving faster than the frame rate, we can coalesce and batch updates. We can prioritize work coming from user interactions (such as an animation caused by a button click) over less important background work (such as rendering new content just loaded from the network) to avoid dropping frames.
|
||||
|
||||
To be clear, we are not taking advantage of this right now. However the freedom to do something like this is why we prefer to have control over scheduling, and why `setState()` is asynchronous. Conceptually, we think of it as "scheduling an update".
|
||||
|
||||
The control over scheduling would be harder for us to gain if we let the user directly compose views with a "push" based paradigm common in some variations of [Functional Reactive Programming](https://en.wikipedia.org/wiki/Functional_reactive_programming). We want to own the "glue" code.
|
||||
|
||||
It is a key goal for React that the amount of the user code that executes before yielding back into React is minimal. This ensures that React retains the capability to schedule and split work in chunks according to what it knows about the UI.
|
||||
|
||||
There is an internal joke in the team that React should have been called "Schedule" because React does not want to be fully "reactive".
|
||||
|
||||
### Developer Experience
|
||||
|
||||
Providing a good developer experience is important to us.
|
||||
|
||||
For example, we maintain [React DevTools](https://github.com/facebook/react-devtools) which let you inspect the React component tree in Chrome and Firefox. We have heard that it brings a big productivity boost both to the Facebook engineers and to the community.
|
||||
|
||||
We also try to go an extra mile to provide helpful developer warnings. For example, React warns you in development if you nest tags in a way that the browser doesn't understand, or if you make a common typo in the API. Developer warnings and the related checks are the main reason why the development version of React is slower than the production version.
|
||||
|
||||
The usage patterns that we see internally at Facebook help us understand what the common mistakes are, and how to prevent them early. When we add new features, we try to anticipate the common mistakes and warn about them.
|
||||
|
||||
We are always looking out for ways to improve the developer experience. We love to hear your suggestions and accept your contributions to make it even better.
|
||||
|
||||
### Debugging
|
||||
|
||||
When something goes wrong, it is important that you have breadcrumbs to trace the mistake to its source in the codebase. In React, props and state are those breadcrumbs.
|
||||
|
||||
If you see something wrong on the screen, you can open React DevTools, find the component responsible for rendering, and then see if the props and state are correct. If they are, you know that the problem is in the component’s `render()` function, or some function that is called by `render()`. The problem is isolated.
|
||||
|
||||
If the state is wrong, you know that the problem is caused by one of the `setState()` calls in this file. This, too, is relatively simple to locate and fix because usually there are only a few `setState()` calls in a single file.
|
||||
|
||||
If the props are wrong, you can traverse the tree up in the inspector, looking for the component that first "poisoned the well" by passing bad props down.
|
||||
|
||||
This ability to trace any UI to the data that produced it in the form of current props and state is very important to React. It is an explicit design goal that state is not "trapped" in closures and combinators, and is available to React directly.
|
||||
|
||||
While the UI is dynamic, we believe that synchronous `render()` functions of props and state turn debugging from guesswork into a boring but finite procedure. We would like to preserve this constraint in React even though it makes some use cases, like complex animations, harder.
|
||||
|
||||
### Configuration
|
||||
|
||||
We find global runtime configuration options to be problematic.
|
||||
|
||||
For example, it is occasionally requested that we implement a function like `React.configure(options)` or `React.register(component)`. However this poses multiple problems, and we are not aware of good solutions to them.
|
||||
|
||||
What if somebody calls such a function from a third-party component library? What if one React app embeds another React app, and their desired configurations are incompatible? How can a third-party component specify that it requires a particular configuration? We think that global configuration doesn't work well with composition. Since composition is central to React, we don't provide global configuration in code.
|
||||
|
||||
We do, however, provide some global configuration on the build level. For example, we provide separate development and production builds. We may also [add a profiling build](https://github.com/facebook/react/issues/6627) in the future, and we are open to considering other build flags.
|
||||
|
||||
### Beyond the DOM
|
||||
|
||||
We see the value of React in the way it allows us to write components that have fewer bugs and compose together well. DOM is the original rendering target for React but [React Native](http://facebook.github.io/react-native/) is just as important both to Facebook and the community.
|
||||
|
||||
Being renderer-agnostic is an important design constraint of React. It adds some overhead in the internal representations. On the other hand, any improvements to the core translate across platforms.
|
||||
|
||||
Having a single programming model lets us form engineering teams around products instead of platforms. So far the tradeoff has been worth it for us.
|
||||
|
||||
### Implementation
|
||||
|
||||
We try to provide elegant APIs where possible. We are much less concerned with the implementation being elegant. The real world is far from perfect, and to a reasonable extent we prefer to put the ugly code into the library if it means the user does not have to write it. When we evaluate new code, we are looking for an implementation that is correct, performant and affords a good developer experience. Elegance is secondary.
|
||||
|
||||
We prefer boring code to clever code. Code is disposable and often changes. So it is important that it [doesn't introduce new internal abstractions unless absolutely necessary](https://youtu.be/4anAwXYqLG8?t=13m9s). Verbose code that is easy to move around, change and remove is preferred to elegant code that is prematurely abstracted and hard to change.
|
||||
|
||||
### Optimized for Tooling
|
||||
|
||||
Some commonly used APIs have verbose names. For example, we use `componentDidMount()` instead of `didMount()` or `onMount()`. This is [intentional](https://github.com/reactjs/react-future/issues/40#issuecomment-142442124). The goal is to make the points of interaction with the library highly visible.
|
||||
|
||||
In a massive codebase like Facebook, being able to search for uses of specific APIs is very important. We value distinct verbose names, and especially for the features that should be used sparingly. For example, `dangerouslySetInnerHTML` is hard to miss in a code review.
|
||||
|
||||
Optimizing for search is also important because of our reliance on [codemods](https://www.youtube.com/watch?v=d0pOgY8__JM) to make breaking changes. We want it to be easy and safe to apply vast automated changes across the codebase, and unique verbose names help us achieve this. Similarly, distinctive names make it easy to write custom [lint rules](https://github.com/yannickcr/eslint-plugin-react) about using React without worrying about potential false positives.
|
||||
|
||||
[JSX](/react/docs/displaying-data.html#jsx-syntax) plays a similar role. While it is not required with React, we use it extensively at Facebook both for aesthetic and pragmatic reasons.
|
||||
|
||||
In our codebase, JSX provides an unambigious hint to the tools that they are dealing with a React element tree. This makes it possible to add build-time optimizations such as [hoisting constant elements](http://babeljs.io/docs/plugins/transform-react-constant-elements/), safely lint and codemod internal component usage, and [include JSX source location](https://github.com/facebook/react/pull/6771) into the warnings.
|
||||
|
||||
### Dogfooding
|
||||
|
||||
We try our best to address the problems raised by the community. However we are likely to prioritize the issues that people are *also* experiencing internally at Facebook. Perhaps counter-intuitively, we think this is the main reason why the community can bet on React.
|
||||
|
||||
Heavy internal usage gives us the confidence that React won't disappear tomorrow. React was created at Facebook to solve its problems. It brings tangible business value to the company and is used in many of its products. [Dogfooding](https://en.wikipedia.org/wiki/Eating_your_own_dog_food) it means that our vision stays sharp and we have a focused direction going forward.
|
||||
|
||||
This doesn't mean that we ignore the issues raised by the community. For example, we added support for [web components](/react/docs/webcomponents.html) and [SVG](https://github.com/facebook/react/pull/6243) to React even though we don't rely on either of them internally. We are actively [listening to your pain points](https://github.com/facebook/react/issues/2686) and [address them](/react/blog/2016/07/11/introducing-reacts-error-code-system.html) to the best of our ability. The community is what makes React special to us, and we are honored to contribute back.
|
||||
|
||||
After releasing many open source projects at Facebook, we have learned that trying to make everyone happy at the same time produced projects with poor focus that didn't grow well. Instead, we found that picking a small audience and focusing on making them happy brings a positive net effect. That's exactly what we did with React, and so far solving the problems encountered by Facebook product teams has translated well to the open source community.
|
||||
|
||||
The downside of this approach is that sometimes we fail to give enough focus to the things that Facebook teams don't have to deal with, such as the "getting started" experience. We are acutely aware of this, and we are thinking of how to improve in a way that would benefit everyone in the community without making the same mistakes we did with open source projects before.
|
||||
162
docs/contributing/how-to-contribute.md
Normal file
162
docs/contributing/how-to-contribute.md
Normal file
@@ -0,0 +1,162 @@
|
||||
---
|
||||
id: how-to-contribute
|
||||
title: How to Contribute
|
||||
layout: contributing
|
||||
permalink: contributing/how-to-contribute.html
|
||||
next: codebase-overview.html
|
||||
redirect_from: "tips/introduction.html"
|
||||
---
|
||||
|
||||
React is one of Facebook's first open source projects that is both under very active development and is also being used to ship code to everybody on [facebook.com](https://www.facebook.com). We're still working out the kinks to make contributing to this project as easy and transparent as possible, but we're not quite there yet. Hopefully this document makes the process for contributing clear and answers some questions that you may have.
|
||||
|
||||
### [Code of Conduct](https://code.facebook.com/codeofconduct)
|
||||
|
||||
Facebook has adopted a Code of Conduct that we expect project participants to adhere to. Please read [the full text](https://code.facebook.com/codeofconduct) so that you can understand what actions will and will not be tolerated.
|
||||
|
||||
### Open Development
|
||||
|
||||
All work on React happens directly on [GitHub](https://github.com/facebook/react). Both core team members and external contributors send pull requests which go through the same review process.
|
||||
|
||||
### Branch Organization
|
||||
|
||||
We will do our best to keep the [`master` branch](https://github.com/facebook/react/tree/master) in good shape, with tests passing at all times. But in order to move fast, we will make API changes that your application might not be compatible with. We recommend that you use [the latest stable version of React](/react/downloads.html).
|
||||
|
||||
If you send a pull request, please do it against the `master` branch. We maintain stable branches for major versions separately but we don't accept pull requests to them directly. Instead, we cherry-pick non-breaking changes from master to the latest stable major version.
|
||||
|
||||
### Semantic Versioning
|
||||
|
||||
React follows [semantic versioning](http://semver.org/). We release patch versions for bugfixes, minor versions for new features, and major versions for any breaking changes. When we make breaking changes, we also introduce deprecation warnings in a minor version so that our users learn about the upcoming changes and migrate their code in advance.
|
||||
|
||||
We tag every pull request with a label marking whether the change should go in the next [patch](https://github.com/facebook/react/pulls?q=is%3Aopen+is%3Apr+label%3Asemver-patch), [minor](https://github.com/facebook/react/pulls?q=is%3Aopen+is%3Apr+label%3Asemver-minor), or a [major](https://github.com/facebook/react/pulls?q=is%3Aopen+is%3Apr+label%3Asemver-major) version. We release new patch versions every few weeks, minor versions every few months, and major versions one or two times a year.
|
||||
|
||||
Every significant change is documented in the [changelog file](https://github.com/facebook/react/blob/master/CHANGELOG.md).
|
||||
|
||||
### Bugs
|
||||
|
||||
#### Where to Find Known Issues
|
||||
|
||||
We are using [GitHub Issues](https://github.com/facebook/react/issues) for our public bugs. We keep a close eye on this and try to make it clear when we have an internal fix in progress. Before filing a new task, try to make sure your problem doesn't already exist.
|
||||
|
||||
#### Reporting New Issues
|
||||
|
||||
The best way to get your bug fixed is to provide a reduced test case. This [JSFiddle template](https://jsfiddle.net/reactjs/69z2wepo/) is a great starting point.
|
||||
|
||||
#### Security Bugs
|
||||
|
||||
Facebook has a [bounty program](https://www.facebook.com/whitehat/) for the safe disclosure of security bugs. With that in mind, please do not file public issues; go through the process outlined on that page.
|
||||
|
||||
### How to Get in Touch
|
||||
|
||||
* IRC: [#reactjs on freenode](https://webchat.freenode.net/?channels=reactjs)
|
||||
* Discussion forum: [discuss.reactjs.org](https://discuss.reactjs.org/)
|
||||
|
||||
There is also [an active community of React users on the Discord chat platform](http://www.reactiflux.com/) in case you need help with React.
|
||||
|
||||
### Proposing a Change
|
||||
|
||||
If you intend to change to the public API, or make any non-trivial changes to the implementation, we recommend [filing an issue](https://github.com/facebook/react/issues/new). This lets us reach an agreement on your proposal before you put significant effort into it.
|
||||
|
||||
If you're only fixing a bug, it's fine to submit a pull request right away but we still recommend to file an issue detailing what you're fixing. This is helpful in case we don't accept that specific fix but want to keep track of the issue.
|
||||
|
||||
### Your First Pull Request
|
||||
|
||||
Working on your first Pull Request? You can learn how from this free video series:
|
||||
|
||||
**[How to Contribute to an Open Source Project on GitHub](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github)**
|
||||
|
||||
To help you get your feet wet and get you familiar with our contribution process, we have a list of **[good first bugs](https://github.com/facebook/react/labels/good%20first%20bug)** that contain bugs which are fairly easy to fix. This is a great place to get started.
|
||||
|
||||
If you decide to fix an issue, please be sure to check the comment thread in case somebody is already working on a fix. If nobody is working on it at the moment, please leave a comment stating that you intend to work on it so other people don't accidentally duplicate your effort.
|
||||
|
||||
If somebody claims an issue but doesn't follow up for more than two weeks, it's fine to take over it but you should still leave a comment.
|
||||
|
||||
### Sending a Pull Request
|
||||
|
||||
The core team is monitoring for pull requests. We will review your pull request and either merge it, request changes to it, or close it with an explanation. For API changes we may need to fix our internal uses at Facebook.com, which could cause some delay. We'll do our best to provide updates and feedback throughout the process.
|
||||
|
||||
**Before submitting a pull request,** please make sure the following is done:
|
||||
|
||||
1. Fork [the repository](https://github.com/facebook/react) and create your branch from `master`.
|
||||
2. If you've added code that should be tested, add tests!
|
||||
3. If you've changed APIs, update the documentation.
|
||||
4. Ensure the test suite passes (`npm test`).
|
||||
5. Make sure your code lints (`npm run lint`).
|
||||
6. Run the [Flow](https://flowtype.org/) typechecks (`npm run flow`).
|
||||
7. If you haven't already, complete the CLA.
|
||||
|
||||
### Contributor License Agreement (CLA)
|
||||
|
||||
In order to accept your pull request, we need you to submit a CLA. You only need to do this once, so if you've done this for another Facebook open source project, you're good to go. If you are submitting a pull request for the first time, just let us know that you have completed the CLA and we can cross-check with your GitHub username.
|
||||
|
||||
**[Complete your CLA here.](https://code.facebook.com/cla)**
|
||||
|
||||
### Contribution Prerequisites
|
||||
|
||||
* You have `node` installed at v4.0.0+ and `npm` at v2.0.0+.
|
||||
* You have `gcc` installed or are comfortable installing a compiler if needed. Some of our `npm` dependencies may require a compilation step. On OS X, the Xcode Command Line Tools will cover this. On Ubuntu, `apt-get install build-essential` will install the required packages. Similar commands should work on other Linux distros. Windows will require some additional steps, see the [`node-gyp` installation instructions](https://github.com/nodejs/node-gyp#installation) for details.
|
||||
* You are familiar with `npm` and know whether or not you need to use `sudo` when installing packages globally.
|
||||
* You are familiar with `git`.
|
||||
|
||||
### Development Workflow
|
||||
|
||||
After cloning React, run `npm install` to fetch its dependencies.
|
||||
Then, you can run several commands:
|
||||
|
||||
* `npm run lint` checks the code style.
|
||||
* `npm test` runs the complete test suite.
|
||||
* `npm test -- --watch` runs an interactive test watcher.
|
||||
* `npm test <pattern>` runs tests with matching filenames.
|
||||
* `npm run flow` runs the [Flow](https://flowtype.org/) typechecks.
|
||||
* `npm run build` creates a `build` folder with all the packages.
|
||||
|
||||
We recommend running `npm test` (or its variations above) to make sure you don't introduce any regressions as you work on your change. However it can be handy to try your build of React in a real project.
|
||||
|
||||
First, run `npm run build`. This will produce pre-built bundles in `build` folder, as well as prepare npm packages inside `build/packages`.
|
||||
|
||||
The easiest way to try your changes is to open and modify `examples/basic/index.html`. This file already uses `react.js` from the `build` folder so it will pick up your changes. Please make sure to rollback any unintentional changes in `examples` before sending a pull request.
|
||||
|
||||
If you want to try your changes in your existing React project, you may copy `build/react.js`, `build/react-dom.js`, or any other build products into your app and use them instead of the stable version. If your project uses React from npm, you may delete `react` and `react-dom` in its dependencies and use `npm link` to point them to your local `build` folder:
|
||||
|
||||
```sh
|
||||
cd your_project
|
||||
npm link ~/path_to_your_react_clone/build/packages/react
|
||||
npm link ~/path_to_your_react_clone/build/packages/react-dom
|
||||
```
|
||||
|
||||
Every time you run `npm run build` in the React folder, the updated versions will appear in your project's `node_modules`. You can then rebuild your project to try your changes.
|
||||
|
||||
We still require that your pull request contains unit tests for any new functionality. This way we can ensure that we don't break your code in the future.
|
||||
|
||||
### Style Guide
|
||||
|
||||
Our linter will catch most styling issues that may exist in your code.
|
||||
You can check the status of your code styling by simply running `npm run lint`.
|
||||
|
||||
However, there are still some styles that the linter cannot pick up. If you are unsure about something, looking at [Airbnb's Style Guide](https://github.com/airbnb/javascript) will guide you in the right direction.
|
||||
|
||||
### Code Conventions
|
||||
|
||||
* Use semicolons `;`
|
||||
* Commas last `,`
|
||||
* 2 spaces for indentation (no tabs)
|
||||
* Prefer `'` over `"`
|
||||
* `'use strict';`
|
||||
* 80 character line length (**except documentation**)
|
||||
* Write "attractive" code
|
||||
* Do not use the optional parameters of `setTimeout` and `setInterval`
|
||||
|
||||
### Introductory Video
|
||||
|
||||
You may be interested in watching [this short video](https://www.youtube.com/watch?v=wUpPsEcGsg8) (26 mins) which gives an introduction on how to contribute to React.
|
||||
|
||||
### Meeting Notes
|
||||
|
||||
React team meets once a week to discuss the development of React, future plans, and priorities. You can find the meeting notes in a [dedicated repository](https://github.com/reactjs/core-notes/).
|
||||
|
||||
### License
|
||||
|
||||
By contributing to React, you agree that your contributions will be licensed under its BSD license.
|
||||
|
||||
### What Next?
|
||||
|
||||
Read the [next section](/react/contributing/codebase-overview.html) to learn how the codebase is organized.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user