Compare commits
423 Commits
16.0.0-bet
...
v15.3.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 | ||
|
|
de0b0b3705 | ||
|
|
4dec99c61e | ||
|
|
18d715b86e | ||
|
|
a157791264 | ||
|
|
590d82bc33 | ||
|
|
a210dacdf4 | ||
|
|
1dfaa528f8 | ||
|
|
8c811778d6 | ||
|
|
395ae75eb3 | ||
|
|
2606966b43 | ||
|
|
c98f0e6631 | ||
|
|
a7714585bb | ||
|
|
da6e4853be | ||
|
|
afba0f3da7 | ||
|
|
d2b947c351 | ||
|
|
d1ba51bc84 | ||
|
|
9d73b2339a | ||
|
|
e88c96b1d7 | ||
|
|
3655e30adb | ||
|
|
112a400662 | ||
|
|
33a9603e93 | ||
|
|
ae6dfa9dae | ||
|
|
c05ae26ec8 | ||
|
|
3b2f29ef69 | ||
|
|
ecb61403d7 | ||
|
|
9eb37bff49 | ||
|
|
605109021f | ||
|
|
a3b7699f42 | ||
|
|
3251460ebd | ||
|
|
ec036ed185 | ||
|
|
5922ea1a0c | ||
|
|
1fb7d64171 | ||
|
|
fd8aa077e3 | ||
|
|
3e8a2aaddb | ||
|
|
c81c29ae58 | ||
|
|
5b4b6e7999 | ||
|
|
f565c92e38 | ||
|
|
fc4bf8158a | ||
|
|
7cd3aa7a1e | ||
|
|
ab4057880e | ||
|
|
d72885b383 | ||
|
|
fd1476e3aa | ||
|
|
142e4ebb57 | ||
|
|
ca92b9104c | ||
|
|
a6179d03f3 | ||
|
|
8afaf0380f | ||
|
|
ca0c409b6f | ||
|
|
177796ff79 | ||
|
|
da3be881ba | ||
|
|
1a0ec77094 | ||
|
|
e226021c5e | ||
|
|
1942c6a035 | ||
|
|
c49166401a | ||
|
|
500c0003b2 | ||
|
|
0275d77fc0 | ||
|
|
67a4b12e27 | ||
|
|
d1c08f11d5 | ||
|
|
40c0867f63 | ||
|
|
7081a85ace |
7
.babelrc
7
.babelrc
@@ -18,8 +18,11 @@
|
||||
["transform-es2015-spread", { "loose": true }],
|
||||
"transform-es2015-parameters",
|
||||
["transform-es2015-destructuring", { "loose": true }],
|
||||
["transform-es2015-block-scoping", { "throwIfClosureRequired": true }],
|
||||
"transform-es2015-block-scoping",
|
||||
"transform-es2015-modules-commonjs",
|
||||
"transform-es3-member-expression-literals",
|
||||
"transform-es3-property-literals"
|
||||
"transform-es3-property-literals",
|
||||
"./scripts/babel/transform-object-assign-require",
|
||||
"transform-react-jsx-source"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# We can probably lint these later but not important at this point
|
||||
src/renderers/art
|
||||
src/__mocks__/vendor
|
||||
src/shared/vendor
|
||||
# But not in docs/_js/examples/*
|
||||
docs/_js/*.js
|
||||
docs/js/
|
||||
@@ -9,11 +9,9 @@ docs/_site/
|
||||
docs/vendor/bundle/
|
||||
# This should be more like examples/**/thirdparty/** but
|
||||
# we should fix https://github.com/facebook/esprima/pull/85 first
|
||||
fixtures/
|
||||
examples/
|
||||
# Ignore built files.
|
||||
build/
|
||||
coverage/
|
||||
scripts/bench/benchmarks/**/*.js
|
||||
scripts/bench/remote-repo/
|
||||
scripts/bench/bench-*.js
|
||||
vendor/*
|
||||
**/node_modules
|
||||
|
||||
46
.eslintrc.js
46
.eslintrc.js
@@ -1,30 +1,34 @@
|
||||
'use strict';
|
||||
|
||||
const OFF = 0;
|
||||
const WARNING = 1;
|
||||
const ERROR = 2;
|
||||
|
||||
module.exports = {
|
||||
extends: 'fbjs',
|
||||
parser: 'babel-eslint',
|
||||
|
||||
extends: './node_modules/fbjs-scripts/eslint/.eslintrc.js',
|
||||
|
||||
plugins: [
|
||||
'react',
|
||||
'react-internal',
|
||||
],
|
||||
|
||||
ecmaFeatures: {
|
||||
modules: false
|
||||
},
|
||||
|
||||
// We're stricter than the default config, mostly. We'll override a few rules
|
||||
// and then enable some React specific ones.
|
||||
rules: {
|
||||
'accessor-pairs': OFF,
|
||||
'brace-style': [ERROR, '1tbs'],
|
||||
'comma-dangle': [ERROR, 'always-multiline'],
|
||||
'consistent-return': OFF,
|
||||
'consistent-return': ERROR,
|
||||
'dot-location': [ERROR, 'property'],
|
||||
'dot-notation': ERROR,
|
||||
'eol-last': ERROR,
|
||||
'eqeqeq': [ERROR, 'allow-null'],
|
||||
'indent': OFF,
|
||||
'indent': [ERROR, 2, {SwitchCase: 1}],
|
||||
'jsx-quotes': [ERROR, 'prefer-double'],
|
||||
'keyword-spacing': [ERROR, {after: true, before: true}],
|
||||
'no-bitwise': OFF,
|
||||
'no-inner-declarations': [ERROR, 'functions'],
|
||||
'no-multi-spaces': ERROR,
|
||||
@@ -32,33 +36,39 @@ module.exports = {
|
||||
'no-shadow': ERROR,
|
||||
'no-unused-expressions': ERROR,
|
||||
'no-unused-vars': [ERROR, {args: 'none'}],
|
||||
'no-useless-concat': OFF,
|
||||
'quotes': [ERROR, 'single', {avoidEscape: true, allowTemplateLiterals: true }],
|
||||
'quotes': [ERROR, 'single', 'avoid-escape'],
|
||||
'space-after-keywords': ERROR,
|
||||
'space-before-blocks': ERROR,
|
||||
'space-before-function-paren': OFF,
|
||||
'space-before-function-paren': [ERROR, {anonymous: 'never', named: 'never'}],
|
||||
'space-before-keywords': ERROR,
|
||||
'strict': [ERROR, 'global'],
|
||||
|
||||
// React & JSX
|
||||
// Our transforms set this automatically
|
||||
'react/display-name': OFF,
|
||||
'react/jsx-boolean-value': [ERROR, 'always'],
|
||||
'react/jsx-no-undef': ERROR,
|
||||
// We don't care to do this
|
||||
'react/jsx-sort-prop-types': OFF,
|
||||
'react/jsx-space-before-closing': ERROR,
|
||||
'react/jsx-sort-props': OFF,
|
||||
'react/jsx-uses-react': ERROR,
|
||||
'react/no-is-mounted': OFF,
|
||||
'react/jsx-uses-vars': ERROR,
|
||||
// It's easier to test some things this way
|
||||
'react/no-did-mount-set-state': OFF,
|
||||
'react/no-did-update-set-state': OFF,
|
||||
// We define multiple components in test files
|
||||
'react/no-multi-comp': OFF,
|
||||
'react/no-unknown-property': OFF,
|
||||
// This isn't useful in our test code
|
||||
'react/prop-types': OFF,
|
||||
'react/react-in-jsx-scope': ERROR,
|
||||
'react/self-closing-comp': ERROR,
|
||||
// We don't care to do this
|
||||
'react/jsx-wrap-multilines': [ERROR, {declaration: false, assignment: false}],
|
||||
'react/sort-comp': OFF,
|
||||
'react/wrap-multilines': [ERROR, {declaration: false, assignment: false}],
|
||||
|
||||
// CUSTOM RULES
|
||||
// the second argument of warning/invariant should be a literal string
|
||||
'react-internal/warning-and-invariant-args': ERROR,
|
||||
'react-internal/no-primitive-constructors': ERROR,
|
||||
},
|
||||
|
||||
globals: {
|
||||
expectDev: true,
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
28
.flowconfig
28
.flowconfig
@@ -1,22 +1,18 @@
|
||||
[ignore]
|
||||
|
||||
<PROJECT_ROOT>/fixtures/.*
|
||||
<PROJECT_ROOT>/build/.*
|
||||
<PROJECT_ROOT>/scripts/.*
|
||||
<PROJECT_ROOT>/.*/node_modules/y18n/.*
|
||||
<PROJECT_ROOT>/node_modules/chrome-devtools-frontend/.*
|
||||
<PROJECT_ROOT>/node_modules/devtools-timeline-model/.*
|
||||
<PROJECT_ROOT>/.*/__mocks__/.*
|
||||
<PROJECT_ROOT>/.*/__tests__/.*
|
||||
.*/examples/.*
|
||||
.*/build/.*
|
||||
.*/node_modules/y18n/.*
|
||||
.*/__mocks__/.*
|
||||
.*/__tests__/.*
|
||||
|
||||
# Ignore Docs
|
||||
<PROJECT_ROOT>/docs/.*
|
||||
<PROJECT_ROOT>/.*/docs/.*
|
||||
.*/docs/.*
|
||||
|
||||
[include]
|
||||
|
||||
[libs]
|
||||
./node_modules/fbjs/flow/lib/dev.js
|
||||
./node_modules/fbjs/flow/lib
|
||||
./flow
|
||||
|
||||
[options]
|
||||
@@ -25,17 +21,17 @@ module.system=haste
|
||||
esproposal.class_static_fields=enable
|
||||
esproposal.class_instance_fields=enable
|
||||
|
||||
experimental.strict_type_args=true
|
||||
|
||||
munge_underscores=false
|
||||
|
||||
suppress_type=$FlowIssue
|
||||
suppress_type=$FlowFixMe
|
||||
suppress_type=$FixMe
|
||||
suppress_type=$FlowExpectedError
|
||||
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(3[0-3]\\|[1-2][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*www[a-z,_]*\\)?)\\)
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(3[0-3]\\|[1-2][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*www[a-z,_]*\\)?)\\)?:? #[0-9]+
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(2[0-4]\\|1[0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*\\)?)\\)
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(2[0-4]\\|1[0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*\\)?)\\)? #[0-9]+
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError
|
||||
|
||||
[version]
|
||||
^0.50.0
|
||||
^0.27.0
|
||||
|
||||
9
.github/ISSUE_TEMPLATE.md
vendored
9
.github/ISSUE_TEMPLATE.md
vendored
@@ -1,9 +0,0 @@
|
||||
**Do you want to request a *feature* or report a *bug*?**
|
||||
|
||||
**What is the current behavior?**
|
||||
|
||||
**If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem via https://jsfiddle.net or similar (template: https://jsfiddle.net/84v837e9/).**
|
||||
|
||||
**What is the expected behavior?**
|
||||
|
||||
**Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?**
|
||||
10
.github/PULL_REQUEST_TEMPLATE.md
vendored
10
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -1,10 +0,0 @@
|
||||
**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. Format your code with [prettier](https://github.com/prettier/prettier) (`npm run prettier`).
|
||||
6. Make sure your code lints (`npm run lint`).
|
||||
7. Run the [Flow](https://flowtype.org/) typechecks (`npm run flow`).
|
||||
8. If you haven't already, complete the CLA.
|
||||
10
.gitignore
vendored
10
.gitignore
vendored
@@ -7,7 +7,6 @@ static
|
||||
_SpecRunner.html
|
||||
__benchmarks__
|
||||
build/
|
||||
remote-repo/
|
||||
coverage/
|
||||
.module-cache
|
||||
*.gem
|
||||
@@ -16,10 +15,9 @@ docs/code
|
||||
docs/_site
|
||||
docs/.sass-cache
|
||||
docs/js/*
|
||||
docs/downloads/*.zip
|
||||
docs/downloads
|
||||
docs/vendor/bundle
|
||||
fixtures/dom/public/react-dom.js
|
||||
fixtures/dom/public/react.js
|
||||
examples/shared/*.js
|
||||
test/the-files-to-test.generated.js
|
||||
*.log*
|
||||
chrome-user-data
|
||||
@@ -28,7 +26,3 @@ chrome-user-data
|
||||
.idea
|
||||
*.iml
|
||||
.vscode
|
||||
*.swp
|
||||
*.swo
|
||||
*react*min*.js
|
||||
!src/node_modules
|
||||
|
||||
114
.travis.yml
Normal file
114
.travis.yml
Normal file
@@ -0,0 +1,114 @@
|
||||
---
|
||||
sudo: required
|
||||
dist: trusty
|
||||
language: node_js
|
||||
node_js:
|
||||
- 4
|
||||
rvm:
|
||||
- 2.2.3
|
||||
cache:
|
||||
directories:
|
||||
- docs/vendor/bundle
|
||||
- node_modules
|
||||
before_install:
|
||||
- |
|
||||
if [ "$TEST_TYPE" != build_website ] && \
|
||||
! git diff --name-only $TRAVIS_COMMIT_RANGE | grep -qvE '(\.md$)|(^(docs|examples))/'
|
||||
then
|
||||
echo "Only docs were updated, stopping build process."
|
||||
exit
|
||||
fi
|
||||
npm install -g npm@latest-2
|
||||
npm --version
|
||||
script:
|
||||
- |
|
||||
if [ "$TEST_TYPE" = build_website ]; then
|
||||
if [ "$TRAVIS_BRANCH" = "$REACT_WEBSITE_BRANCH" ] && [ "$TRAVIS_PULL_REQUEST" = false ]; then
|
||||
set -e
|
||||
|
||||
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 clone --branch gh-pages --depth=50 \
|
||||
https://reactjs-bot@github.com/facebook/react.git \
|
||||
$GH_PAGES_DIR
|
||||
pushd docs
|
||||
bundle install --jobs=3 --retry=3 --path=vendor/bundle
|
||||
bundle exec rake release
|
||||
cd $GH_PAGES_DIR
|
||||
git status
|
||||
if ! git diff-index --quiet HEAD --; then
|
||||
git add -A .
|
||||
git commit -m "Rebuild website"
|
||||
git push origin gh-pages
|
||||
fi
|
||||
popd
|
||||
fi
|
||||
elif [ "$TEST_TYPE" = build ]; then
|
||||
if [ "$SERVER" ]; then
|
||||
set -e
|
||||
./node_modules/.bin/grunt build
|
||||
curl \
|
||||
-F "react=@build/react.js" \
|
||||
-F "react.min=@build/react.min.js" \
|
||||
-F "react-with-addons=@build/react-with-addons.js" \
|
||||
-F "react-with-addons.min=@build/react-with-addons.min.js" \
|
||||
-F "react-dom=@build/react-dom.js" \
|
||||
-F "react-dom.min=@build/react-dom.min.js" \
|
||||
-F "react-dom-server=@build/react-dom-server.js" \
|
||||
-F "react-dom-server.min=@build/react-dom-server.min.js" \
|
||||
-F "npm-react=@build/packages/react.tgz" \
|
||||
-F "npm-react-dom=@build/packages/react-dom.tgz" \
|
||||
-F "npm-react-native=@build/packages/react-native-renderer.tgz" \
|
||||
-F "commit=$TRAVIS_COMMIT" \
|
||||
-F "date=`git log --format='%ct' -1`" \
|
||||
-F "pull_request=$TRAVIS_PULL_REQUEST" \
|
||||
-F "token=$SECRET_TOKEN" \
|
||||
-F "branch=$TRAVIS_BRANCH" \
|
||||
$SERVER
|
||||
fi
|
||||
elif [ "$TEST_TYPE" = test ]; then
|
||||
set -e
|
||||
# Disabling coverage because it's broken:
|
||||
# https://travis-ci.org/facebook/react/jobs/128163922
|
||||
if false; then
|
||||
./node_modules/.bin/grunt jest:coverage
|
||||
cat ./coverage/lcov.info | ./node_modules/.bin/coveralls
|
||||
else
|
||||
./node_modules/.bin/grunt jest:normal
|
||||
fi
|
||||
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
|
||||
./node_modules/.bin/gulp react:extract-errors
|
||||
else
|
||||
./node_modules/.bin/grunt $TEST_TYPE
|
||||
fi
|
||||
env:
|
||||
matrix:
|
||||
- TEST_TYPE=build
|
||||
- TEST_TYPE=test
|
||||
- TEST_TYPE=lint
|
||||
- TEST_TYPE=flow
|
||||
- TEST_TYPE=build_website
|
||||
global:
|
||||
# SERVER
|
||||
- secure: qPvsJ46XzGrdIuPA70b55xQNGF8jcK7N1LN5CCQYYocXLa+fBrl+fTE77QvehOPhqwJXcj6kOxI+sY0KrVwV7gmq2XY2HZGWUSCxTN0SZlNIzqPA80Y7G/yOjA4PUt8LKgP+8tptyhTAY56qf+hgW8BoLiKOdztYF2p+3zXOLuA=
|
||||
# SECRET_TOKEN
|
||||
- secure: dkpPW+VnoqC/okhRdV90m36NcyBFhcwEKL3bNFExAwi0dXnFao8RoFlvnwiPlA23h2faROkMIetXlti6Aju08BgUFV+f9aL6vLyU7gUent4Nd3413zf2fwDtXIWIETg6uLnOpSykGKgCAT/hY3Q2oPLqOoY0OxfgnbqwxkxljrE=
|
||||
# GITHUB_TOKEN
|
||||
- secure: EHCyCSKMwKlLHNtcj9nmkRzmiiPE3aDGlPcnEyrDJeRI0SeN/iCXHXfFivR0vFq3vr+9naMBczAR2AEidtps5KbJrKqdZnjPFRbmfVtzWr/LlvVCub3u13Pub6TdKIVBTny1PuZ5X8GvdxMNVig89jGjvzhhWuQRaz3VhJnTra4=
|
||||
# COVERALLS_TOKEN
|
||||
- secure: h/cUq+TrUMZOQmkFD7CvuwX0uAwmjIfKZ4qSUzY+QzUtDzOzA0L/XF84xTBq1Q5YYsEiaoF6GxxGCdrLQiBA/ZTd+88UHgeZPMRvi0xG9Q+PeePVOsZMTxy4/WWFgOfSQCk49Mj9zizGgO78i6vxq+SDXMtFHnZ+TpPJIEW6/m0=
|
||||
notifications:
|
||||
irc:
|
||||
use_notice: true
|
||||
skip_join: true
|
||||
on_success: change
|
||||
on_failure: change
|
||||
channels:
|
||||
- chat.freenode.net#reactjs
|
||||
177
CHANGELOG.md
177
CHANGELOG.md
@@ -1,174 +1,3 @@
|
||||
## 15.6.1 (June 14, 2017)
|
||||
|
||||
### React DOM
|
||||
|
||||
* Fix a crash on iOS Safari. ([@jquense](https://github.com/jquense) in [#9960](https://github.com/facebook/react/pull/9960))
|
||||
* Don't add `px` to custom CSS property values. ([@TrySound](https://github.com/TrySound) in [#9966](https://github.com/facebook/react/pull/9966))
|
||||
|
||||
## 15.6.0 (June 13, 2017)
|
||||
|
||||
### React
|
||||
|
||||
* Downgrade deprecation warnings to use `console.warn` instead of `console.error`. ([@flarnie](https://github.com/flarnie) in [#9753](https://github.com/facebook/react/pull/9753))
|
||||
* Add a deprecation warning for `React.createClass`. Points users to `create-react-class` instead. ([@flarnie](https://github.com/flarnie) in [#9771](https://github.com/facebook/react/pull/9771))
|
||||
* Add deprecation warnings and separate module for `React.DOM` factory helpers. ([@nhunzaker](https://github.com/nhunzaker) in [#8356](https://github.com/facebook/react/pull/8356))
|
||||
* Warn for deprecation of `React.createMixin` helper, which was never used. ([@aweary](https://github.com/aweary) in [#8853](https://github.com/facebook/react/pull/8853))
|
||||
|
||||
### React DOM
|
||||
|
||||
* Add support for CSS variables in `style` attribute. ([@aweary](https://github.com/aweary) in [#9302](https://github.com/facebook/react/pull/9302))
|
||||
* Add support for CSS Grid style properties. ([@ericsakmar](https://github.com/ericsakmar) in [#9185](https://github.com/facebook/react/pull/9185))
|
||||
* Fix bug where inputs mutated value on type conversion. ([@nhunzaker](https://github.com/mhunzaker) in [#9806](https://github.com/facebook/react/pull/9806))
|
||||
* Fix issues with `onChange` not firing properly for some inputs. ([@jquense](https://github.com/jquense) in [#8575](https://github.com/facebook/react/pull/8575))
|
||||
* Fix bug where controlled number input mistakenly allowed period. ([@nhunzaker](https://github.com/nhunzaker) in [#9584](https://github.com/facebook/react/pull/9584))
|
||||
* Fix bug where performance entries were being cleared. ([@chrisui](https://github.com/chrisui) in [#9451](https://github.com/facebook/react/pull/9451))
|
||||
|
||||
### React Addons
|
||||
|
||||
* Fix AMD support for addons depending on `react`. ([@flarnie](https://github.com/flarnie) in [#9919](https://github.com/facebook/react/issues/9919))
|
||||
* Fix `isMounted()` to return `true` in `componentWillUnmount`. ([@mridgway](https://github.com/mridgway) in [#9638](https://github.com/facebook/react/issues/9638))
|
||||
* Fix `react-addons-update` to not depend on native `Object.assign`. ([@gaearon](https://github.com/gaearon) in [#9937](https://github.com/facebook/react/pull/9937))
|
||||
* Remove broken Google Closure Compiler annotation from `create-react-class`. ([@gaearon](https://github.com/gaearon) in [#9933](https://github.com/facebook/react/pull/9933))
|
||||
* Remove unnecessary dependency from `react-linked-input`. ([@gaearon](https://github.com/gaearon) in [#9766](https://github.com/facebook/react/pull/9766))
|
||||
* Point `react-addons-(css-)transition-group` to the new package. ([@gaearon](https://github.com/gaearon) in [#9937](https://github.com/facebook/react/pull/9937))
|
||||
|
||||
## 15.5.4 (April 11, 2017)
|
||||
|
||||
### React Addons
|
||||
* **Critical Bugfix:** Update the version of `prop-types` to fix critical bug. ([@gaearon](https://github.com/gaearon) in [545c87f](https://github.com/facebook/react/commit/545c87fdc348f82eb0c3830bef715ed180785390))
|
||||
* Fix `react-addons-create-fragment` package to include `loose-envify` transform for Browserify users. ([@mridgway](https://github.com/mridgway) in [#9642](https://github.com/facebook/react/pull/9642))
|
||||
|
||||
### React Test Renderer
|
||||
* Fix compatibility with Enzyme by exposing `batchedUpdates` on shallow renderer. ([@gaearon](https://github.com/gaearon) in [9382](https://github.com/facebook/react/commit/69933e25c37cf5453a9ef132177241203ee8d2fd))
|
||||
|
||||
## 15.5.3 (April 7, 2017)
|
||||
|
||||
**Note: this release has a critical issue and was deprecated. Please update to 15.5.4 or higher.**
|
||||
|
||||
### React Addons
|
||||
* Fix `react-addons-create-fragment` package to export correct thing. ([@gaearon](https://github.com/gaearon) in [#9385](https://github.com/facebook/react/pull/9383))
|
||||
* Fix `create-react-class` package to include `loose-envify` transform for Browserify users. ([@mridgway](https://github.com/mridgway) in [#9642](https://github.com/facebook/react/pull/9642))
|
||||
|
||||
## 15.5.2 (April 7, 2017)
|
||||
|
||||
**Note: this release has a critical issue and was deprecated. Please update to 15.5.4 or higher.**
|
||||
|
||||
### React Addons
|
||||
* Fix the production single-file builds to not include the development code. ([@gaearon](https://github.com/gaearon) in [#9385](https://github.com/facebook/react/pull/9383))
|
||||
* Apply better minification to production single-file builds. ([@gaearon](https://github.com/gaearon) in [#9385](https://github.com/facebook/react/pull/9383))
|
||||
* Add missing and remove unnecessary dependencies to packages. ([@gaearon](https://github.com/gaearon) in [#9385](https://github.com/facebook/react/pull/9383))
|
||||
|
||||
## 15.5.1 (April 7, 2017)
|
||||
|
||||
**Note: this release has a critical issue and was deprecated. Please update to 15.5.4 or higher.**
|
||||
|
||||
### React
|
||||
* Fix erroneous PropTypes access warning. ([@acdlite](https://github.com/acdlite) in ([ec97ebb](https://github.com/facebook/react/commit/ec97ebbe7f15b58ae2f1323df39d06f119873344))
|
||||
|
||||
## 15.5.0 (April 7, 2017)
|
||||
|
||||
**Note: this release has a critical issue and was deprecated. Please update to 15.5.4 or higher.**
|
||||
|
||||
### React
|
||||
* <s>Added a deprecation warning for `React.createClass`. Points users to create-react-class instead. ([@acdlite](https://github.com/acdlite) in [#d9a4fa4](https://github.com/facebook/react/commit/d9a4fa4f51c6da895e1655f32255cf72c0fe620e))</s>
|
||||
* Added a deprecation warning for `React.PropTypes`. Points users to prop-types instead. ([@acdlite](https://github.com/acdlite) in [#043845c](https://github.com/facebook/react/commit/043845ce75ea0812286bbbd9d34994bb7e01eb28))
|
||||
* Fixed an issue when using `ReactDOM` together with `ReactDOMServer`. ([@wacii](https://github.com/wacii) in [#9005](https://github.com/facebook/react/pull/9005))
|
||||
* Fixed issue with Closure Compiler. ([@anmonteiro](https://github.com/anmonteiro) in [#8895](https://github.com/facebook/react/pull/8895))
|
||||
* Another fix for Closure Compiler. ([@Shastel](https://github.com/Shastel) in [#8882](https://github.com/facebook/react/pull/8882))
|
||||
* Added component stack info to invalid element type warning. ([@n3tr](https://github.com/n3tr) in [#8495](https://github.com/facebook/react/pull/8495))
|
||||
|
||||
### React DOM
|
||||
* Fixed Chrome bug when backspacing in number inputs. ([@nhunzaker](https://github.com/nhunzaker) in [#7359](https://github.com/facebook/react/pull/7359))
|
||||
* Added `react-dom/test-utils`, which exports the React Test Utils. ([@bvaughn](https://github.com/bvaughn))
|
||||
|
||||
### React Test Renderer
|
||||
* Fixed bug where `componentWillUnmount` was not called for children. ([@gre](https://github.com/gre) in [#8512](https://github.com/facebook/react/pull/8512))
|
||||
* Added `react-test-renderer/shallow`, which exports the shallow renderer. ([@bvaughn](https://github.com/bvaughn))
|
||||
|
||||
### React Addons
|
||||
* Last release for addons; they will no longer be actively maintained.
|
||||
* Removed `peerDependencies` so that addons continue to work indefinitely. ([@acdlite](https://github.com/acdlite) and [@bvaughn](https://github.com/bvaughn) in [8a06cd7](https://github.com/facebook/react/commit/8a06cd7a786822fce229197cac8125a551e8abfa) and [67a8db3](https://github.com/facebook/react/commit/67a8db3650d724a51e70be130e9008806402678a))
|
||||
* Updated to remove references to `React.createClass` and `React.PropTypes` ([@acdlite](https://github.com/acdlite) in [12a96b9](https://github.com/facebook/react/commit/12a96b94823d6b6de6b1ac13bd576864abd50175))
|
||||
* `react-addons-test-utils` is deprecated. Use `react-dom/test-utils` and `react-test-renderer/shallow` instead. ([@bvaughn](https://github.com/bvaughn))
|
||||
|
||||
## 15.4.2 (January 6, 2017)
|
||||
|
||||
### React
|
||||
* Fixed build issues with the Brunch bundler. ([@gaearon](https://github.com/gaearon) in [#8686](https://github.com/facebook/react/pull/8686))
|
||||
* Improved error messages for invalid element types. ([@spicyj](https://github.com/spicyj) in [#8612](https://github.com/facebook/react/pull/8612))
|
||||
* Removed a warning about `getInitialState` when `this.state` is set. ([@bvaughn](https://github.com/bvaughn) in [#8594](https://github.com/facebook/react/pull/8594))
|
||||
* Removed some dead code. ([@diegomura](https://github.com/diegomura) in [#8050](https://github.com/facebook/react/pull/8050), [@dfrownfelter](https://github.com/dfrownfelter) in [#8597](https://github.com/facebook/react/pull/8597))
|
||||
|
||||
### React DOM
|
||||
* Fixed a decimal point issue on uncontrolled number inputs. ([@nhunzaker](https://github.com/nhunzaker) in [#7750](https://github.com/facebook/react/pull/7750))
|
||||
* Fixed rendering of textarea placeholder in IE11. ([@aweary](https://github.com/aweary) in [#8020](https://github.com/facebook/react/pull/8020))
|
||||
* Worked around a script engine bug in IE9. ([@eoin](https://github.com/eoin) in [#8018](https://github.com/facebook/react/pull/8018))
|
||||
|
||||
### React Addons
|
||||
* Fixed build issues in RequireJS and SystemJS environments. ([@gaearon](https://github.com/gaearon) in [#8686](https://github.com/facebook/react/pull/8686))
|
||||
* Added missing package dependencies. ([@kweiberth](https://github.com/kweiberth) in [#8467](https://github.com/facebook/react/pull/8467))
|
||||
|
||||
## 15.4.1 (November 22, 2016)
|
||||
|
||||
### React
|
||||
* Restructure variable assignment to work around a Rollup bug ([@gaearon](https://github.com/gaearon) in [#8384](https://github.com/facebook/react/pull/8384))
|
||||
|
||||
### React DOM
|
||||
* Fixed event handling on disabled button elements ([@spicyj](https://github.com/spicyj) in [#8387](https://github.com/facebook/react/pull/8387))
|
||||
* Fixed compatibility of browser build with AMD environments ([@zpao](https://github.com/zpao) in [#8374](https://github.com/facebook/react/pull/8374))
|
||||
|
||||
## 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
|
||||
@@ -358,7 +187,7 @@
|
||||
- **Initial render now uses `document.createElement` instead of generating HTML.** Previously we would generate a large string of HTML and then set `node.innerHTML`. At the time, this was decided to be faster than using `document.createElement` for the majority of cases and browsers that we supported. Browsers have continued to improve and so overwhelmingly this is no longer true. By using `createElement` we can make other parts of React faster. ([@spicyj](https://github.com/spicyj) in [#5205](https://github.com/facebook/react/pull/5205))
|
||||
- **`data-reactid` is no longer on every node.** As a result of using `document.createElement`, we can prime the node cache as we create DOM nodes, allowing us to skip a potential lookup (which used the `data-reactid` attribute). Root nodes will have a `data-reactroot` attribute and server generated markup will still contain `data-reactid`. ([@spicyj](https://github.com/spicyj) in [#5205](https://github.com/facebook/react/pull/5205))
|
||||
- **No more extra `<span>`s.** ReactDOM will now render plain text nodes interspersed with comment nodes that are used for demarcation. This gives us the same ability to update individual pieces of text, without creating extra nested nodes. If you were targeting these `<span>`s in your CSS, you will need to adjust accordingly. You can always render them explicitly in your components. ([@mwiencek](https://github.com/mwiencek) in [#5753](https://github.com/facebook/react/pull/5753))
|
||||
- **Rendering `null` now uses comment nodes.** Previously `null` would render to `<noscript>` elements. We now use comment nodes. This may cause issues if making use of `:nth-child` CSS selectors. While we consider this rendering behavior an implementation detail of React, it's worth noting the potential problem. ([@spicyj](https://github.com/spicyj) in [#5451](https://github.com/facebook/react/pull/5451))
|
||||
- **Rendering `null` now uses comment nodes.** Previously `null` would render to `<noscript>` elements. We now use comment nodes. This may cause issues if making use of `:nth-child` CSS selectors. While we consider this rendering behavior an implementation detail of React, it's worth noting the potential problem. ()[@spicyj](https://github.com/spicyj) in [#5451](https://github.com/facebook/react/pull/5451))
|
||||
- **Functional components can now return `null`.** We added support for [defining stateless components as functions](/react/blog/2015/09/10/react-v0.14-rc1.html#stateless-function-components) in React 0.14. However, React 0.14 still allowed you to define a class component without extending `React.Component` or using `React.createClass()`, so [we couldn’t reliably tell if your component is a function or a class](https://github.com/facebook/react/issues/5355), and did not allow returning `null` from it. This issue is solved in React 15, and you can now return `null` from any component, whether it is a class or a function. ([@jimfb](https://github.com/jimfb) in [#5884](https://github.com/facebook/react/pull/5884))
|
||||
- **Improved SVG support.** All SVG tags are now fully supported. (Uncommon SVG tags are not present on the `React.DOM` element helper, but JSX and `React.createElement` work on all tag names.) All SVG attributes that are implemented by the browsers should be supported too. If you find any attributes that we have missed, please [let us know in this issue](https://github.com/facebook/react/issues/1657). ([@zpao](https://github.com/zpao) in [#6243](https://github.com/facebook/react/pull/6243))
|
||||
|
||||
@@ -534,7 +363,7 @@ Each of these changes will continue to work as before with a new warning until t
|
||||
|
||||
- `React.initializeTouchEvents` is no longer necessary and has been removed completely. Touch events now work automatically.
|
||||
- Add-Ons: Due to the DOM node refs change mentioned above, `TestUtils.findAllInRenderedTree` and related helpers are no longer able to take a DOM component, only a custom component.
|
||||
- The `props` object is now frozen, so mutating props after creating a component element is no longer supported. In most cases, [`React.cloneElement`](https://facebook.github.io/react/docs/react-api.html#cloneelement) should be used instead. This change makes your components easier to reason about and enables the compiler optimizations mentioned above.
|
||||
- The `props` object is now frozen, so mutating props after creating a component element is no longer supported. In most cases, [`React.cloneElement`](https://facebook.github.io/react/docs/top-level-api.html#react.cloneelement) should be used instead. This change makes your components easier to reason about and enables the compiler optimizations mentioned above.
|
||||
- Plain objects are no longer supported as React children; arrays should be used instead. You can use the [`createFragment`](https://facebook.github.io/react/docs/create-fragment.html) helper to migrate, which now returns an array.
|
||||
- Add-Ons: `classSet` has been removed. Use [classnames](https://github.com/JedWatson/classnames) instead.
|
||||
- Web components (custom elements) now use native property names. Eg: `class` instead of `className`.
|
||||
@@ -545,7 +374,7 @@ Each of these changes will continue to work as before with a new warning until t
|
||||
- `setProps` and `replaceProps` are now deprecated. Instead, call ReactDOM.render again at the top level with the new props.
|
||||
- ES6 component classes must now extend `React.Component` in order to enable stateless function components. The [ES3 module pattern](https://facebook.github.io/react/blog/2015/01/27/react-v0.13.0-beta-1.html#other-languages) will continue to work.
|
||||
- Reusing and mutating a `style` object between renders has been deprecated. This mirrors our change to freeze the `props` object.
|
||||
- Add-Ons: `cloneWithProps` is now deprecated. Use [`React.cloneElement`](https://facebook.github.io/react/docs/react-api.html#cloneelement) instead (unlike `cloneWithProps`, `cloneElement` does not merge `className` or `style` automatically; you can merge them manually if needed).
|
||||
- Add-Ons: `cloneWithProps` is now deprecated. Use [`React.cloneElement`](https://facebook.github.io/react/docs/top-level-api.html#react.cloneelement) instead (unlike `cloneWithProps`, `cloneElement` does not merge `className` or `style` automatically; you can merge them manually if needed).
|
||||
- Add-Ons: To improve reliability, `CSSTransitionGroup` will no longer listen to transition events. Instead, you should specify transition durations manually using props such as `transitionEnterTimeout={500}`.
|
||||
|
||||
### Notable enhancements
|
||||
|
||||
101
CONTRIBUTING.md
101
CONTRIBUTING.md
@@ -1,5 +1,102 @@
|
||||
# Contributing to React
|
||||
|
||||
Want to contribute to React? There are a few things you need to know.
|
||||
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.
|
||||
|
||||
We wrote a **[contribution guide](https://facebook.github.io/react/contributing/how-to-contribute.html)** to help you get started.
|
||||
## [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)
|
||||
|
||||
You may also 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 the React JS project.
|
||||
|
||||
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.
|
||||
|
||||
183
Gruntfile.js
Normal file
183
Gruntfile.js
Normal file
@@ -0,0 +1,183 @@
|
||||
'use strict';
|
||||
|
||||
var path = require('path');
|
||||
|
||||
var GULP_EXE = 'gulp';
|
||||
if (process.platform === 'win32') {
|
||||
GULP_EXE += '.cmd';
|
||||
}
|
||||
|
||||
module.exports = function(grunt) {
|
||||
|
||||
grunt.initConfig({
|
||||
pkg: grunt.file.readJSON('package.json'),
|
||||
browserify: require('./grunt/config/browserify'),
|
||||
npm: require('./grunt/config/npm'),
|
||||
clean: [
|
||||
'./build',
|
||||
'./*.gem',
|
||||
'./docs/_site',
|
||||
'./examples/shared/*.js',
|
||||
'.module-cache',
|
||||
],
|
||||
'compare_size': require('./grunt/config/compare_size'),
|
||||
});
|
||||
|
||||
grunt.config.set('compress', require('./grunt/config/compress'));
|
||||
|
||||
function spawnGulp(args, opts, done) {
|
||||
|
||||
grunt.util.spawn({
|
||||
// This could be more flexible (require.resolve & lookup bin in package)
|
||||
// but if it breaks we'll fix it then.
|
||||
cmd: path.join('node_modules', '.bin', GULP_EXE),
|
||||
args: args,
|
||||
opts: Object.assign({stdio: 'inherit'}, opts),
|
||||
}, function(err, result, code) {
|
||||
if (err) {
|
||||
grunt.fail.fatal('Something went wrong running gulp: ', result);
|
||||
}
|
||||
done(code === 0);
|
||||
});
|
||||
}
|
||||
|
||||
Object.keys(grunt.file.readJSON('package.json').devDependencies)
|
||||
.filter(function(npmTaskName) {
|
||||
return npmTaskName.indexOf('grunt-') === 0;
|
||||
})
|
||||
.filter(function(npmTaskName) {
|
||||
return npmTaskName !== 'grunt-cli';
|
||||
})
|
||||
.forEach(function(npmTaskName) {
|
||||
grunt.loadNpmTasks(npmTaskName);
|
||||
});
|
||||
|
||||
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());
|
||||
});
|
||||
|
||||
// Our own browserify-based tasks to build a single JS file build.
|
||||
grunt.registerMultiTask('browserify', require('./grunt/tasks/browserify'));
|
||||
|
||||
grunt.registerMultiTask('npm', require('./grunt/tasks/npm'));
|
||||
|
||||
var npmReactTasks = require('./grunt/tasks/npm-react');
|
||||
grunt.registerTask('npm-react:release', npmReactTasks.buildRelease);
|
||||
grunt.registerTask('npm-react:pack', npmReactTasks.packRelease);
|
||||
|
||||
var npmReactDOMTasks = require('./grunt/tasks/npm-react-dom');
|
||||
grunt.registerTask('npm-react-dom:release', npmReactDOMTasks.buildRelease);
|
||||
grunt.registerTask('npm-react-dom:pack', npmReactDOMTasks.packRelease);
|
||||
|
||||
var npmReactNativeTasks = require('./grunt/tasks/npm-react-native');
|
||||
grunt.registerTask('npm-react-native:release', npmReactNativeTasks.buildRelease);
|
||||
grunt.registerTask('npm-react-native:pack', npmReactNativeTasks.packRelease);
|
||||
|
||||
var npmReactAddonsTasks = require('./grunt/tasks/npm-react-addons');
|
||||
grunt.registerTask('npm-react-addons:release', npmReactAddonsTasks.buildReleases);
|
||||
grunt.registerTask('npm-react-addons:pack', npmReactAddonsTasks.packReleases);
|
||||
|
||||
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',
|
||||
'version-check',
|
||||
'browserify:basic',
|
||||
]);
|
||||
grunt.registerTask('build:addons', [
|
||||
'build-modules',
|
||||
'browserify:addons',
|
||||
]);
|
||||
grunt.registerTask('build:min', [
|
||||
'build-modules',
|
||||
'version-check',
|
||||
'browserify:min',
|
||||
]);
|
||||
grunt.registerTask('build:addons-min', [
|
||||
'build-modules',
|
||||
'browserify:addonsMin',
|
||||
]);
|
||||
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);
|
||||
grunt.registerTask('jest:coverage', jestTasks.coverage);
|
||||
|
||||
grunt.registerTask('test', ['jest:normal']);
|
||||
grunt.registerTask('npm:test', ['build', 'npm:pack']);
|
||||
|
||||
// Optimized build task that does all of our builds. The subtasks will be run
|
||||
// in order so we can take advantage of that and only run build-modules once.
|
||||
grunt.registerTask('build', [
|
||||
'delete-build-modules',
|
||||
'build-modules',
|
||||
'version-check',
|
||||
'browserify:basic',
|
||||
'browserify:addons',
|
||||
'browserify:min',
|
||||
'browserify:addonsMin',
|
||||
'build:react-dom',
|
||||
'npm-react:release',
|
||||
'npm-react:pack',
|
||||
'npm-react-dom:release',
|
||||
'npm-react-dom:pack',
|
||||
'npm-react-native:release',
|
||||
'npm-react-native:pack',
|
||||
'npm-react-addons:release',
|
||||
'npm-react-addons:pack',
|
||||
'npm-react-test:release',
|
||||
'npm-react-test:pack',
|
||||
'compare_size',
|
||||
]);
|
||||
|
||||
// Automate the release!
|
||||
var releaseTasks = require('./grunt/tasks/release');
|
||||
grunt.registerTask('release:setup', releaseTasks.setup);
|
||||
grunt.registerTask('release:bower', releaseTasks.bower);
|
||||
grunt.registerTask('release:docs', releaseTasks.docs);
|
||||
grunt.registerTask('release:msg', releaseTasks.msg);
|
||||
grunt.registerTask('release:starter', releaseTasks.starter);
|
||||
|
||||
grunt.registerTask('release', [
|
||||
'release:setup',
|
||||
'clean',
|
||||
'build',
|
||||
'release:bower',
|
||||
'release:starter',
|
||||
'compress',
|
||||
'release:docs',
|
||||
'release:msg',
|
||||
]);
|
||||
|
||||
grunt.registerTask('build-modules', function() {
|
||||
spawnGulp(['react:modules'], null, this.async());
|
||||
});
|
||||
|
||||
// The default task - build - to keep setup easy.
|
||||
grunt.registerTask('default', ['build']);
|
||||
};
|
||||
89
README.md
89
README.md
@@ -1,4 +1,4 @@
|
||||
# [React](https://facebook.github.io/react/) · [](https://circleci.com/gh/facebook/react) [](https://coveralls.io/github/facebook/react?branch=master) [](https://www.npmjs.com/package/react) [](CONTRIBUTING.md#pull-requests)
|
||||
# [React](https://facebook.github.io/react/) [](https://travis-ci.org/facebook/react) [](https://coveralls.io/github/facebook/react?branch=master) [](https://www.npmjs.com/package/react) [](CONTRIBUTING.md#pull-requests)
|
||||
|
||||
React is a JavaScript library for building user interfaces.
|
||||
|
||||
@@ -12,12 +12,12 @@ 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:
|
||||
|
||||
```jsx
|
||||
class HelloMessage extends React.Component {
|
||||
render() {
|
||||
```js
|
||||
var HelloMessage = React.createClass({
|
||||
render: function() {
|
||||
return <div>Hello {this.props.name}</div>;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ReactDOM.render(
|
||||
<HelloMessage name="John" />,
|
||||
@@ -27,35 +27,77 @@ ReactDOM.render(
|
||||
|
||||
This example will render "Hello John" into a container on the page.
|
||||
|
||||
You'll notice that we used an HTML-like syntax; [we call it JSX](https://facebook.github.io/react/docs/introducing-jsx.html). JSX is not required to use React, but it makes code more readable, and writing it feels like writing HTML. We recommend using [Babel](https://babeljs.io/) with a [React preset](https://babeljs.io/docs/plugins/preset-react/) to convert JSX into native JavaScript for browsers to digest.
|
||||
You'll notice that we used an HTML-like syntax; [we call it JSX](https://facebook.github.io/react/docs/jsx-in-depth.html). JSX is not required to use React, but it makes code more readable, and writing it feels like writing HTML. A simple transform is included with React that allows converting JSX into native JavaScript for browsers to digest.
|
||||
|
||||
## Installation
|
||||
|
||||
React is available as the `react` package on [npm](https://www.npmjs.com/). It is also available on a [CDN](https://facebook.github.io/react/docs/installation.html#using-a-cdn).
|
||||
The fastest way to get started is to serve JavaScript from a CDN. We're using [npmcdn](https://npmcdn.com/) below but React is also available on [cdnjs](https://cdnjs.com/libraries/react) and [jsdelivr](https://www.jsdelivr.com/projects/react):
|
||||
|
||||
React is flexible and can be used in a variety of projects. You can create new apps with it, but you can also gradually introduce it into an existing codebase without doing a rewrite.
|
||||
```html
|
||||
<!-- The core React library -->
|
||||
<script src="https://npmcdn.com/react@15.3.1/dist/react.js"></script>
|
||||
<!-- The ReactDOM Library -->
|
||||
<script src="https://npmcdn.com/react-dom@15.3.1/dist/react-dom.js"></script>
|
||||
```
|
||||
|
||||
The recommended way to install React depends on your project. Here you can find short guides for the most common scenarios:
|
||||
We've also built a [starter kit](https://facebook.github.io/react/downloads/react-15.3.1.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.
|
||||
|
||||
* [Trying Out React](https://facebook.github.io/react/docs/installation.html#trying-out-react)
|
||||
* [Creating a New Application](https://facebook.github.io/react/docs/installation.html#creating-a-new-application)
|
||||
* [Adding React to an Existing Application](https://facebook.github.io/react/docs/installation.html#adding-react-to-an-existing-application)
|
||||
If you'd like to use [bower](http://bower.io), it's as easy as:
|
||||
|
||||
## Contributing
|
||||
```sh
|
||||
bower install --save react
|
||||
```
|
||||
|
||||
The main purpose of this repository is to continue to evolve React core, making it faster and easier to use. Development of React happens in the open on GitHub, and we are grateful to the community for contributing bugfixes and improvements. Read below to learn how you can take part in improving React.
|
||||
And it's just as easy with [npm](http://npmjs.com):
|
||||
|
||||
### [Code of Conduct](https://code.facebook.com/codeofconduct)
|
||||
```sh
|
||||
npm i --save react
|
||||
```
|
||||
|
||||
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.
|
||||
## Contribute
|
||||
|
||||
### Contributing Guide
|
||||
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.
|
||||
|
||||
Read our [contributing guide](https://facebook.github.io/react/contributing/how-to-contribute.html) to learn about our development process, how to propose bugfixes and improvements, and how to build and test your changes to React.
|
||||
### Building Your Copy of React
|
||||
|
||||
### Beginner Friendly Bugs
|
||||
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 have `gcc` installed or are comfortable installing a compiler if needed. Some of our `npm` dependencies may require a compliation 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`.
|
||||
|
||||
#### 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
|
||||
```
|
||||
|
||||
### 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 [beginner friendly bugs](https://github.com/facebook/react/labels/Difficulty%3A%20beginner) that contain bugs which are fairly easy to fix. This is a great place to get started.
|
||||
|
||||
### License
|
||||
|
||||
@@ -64,3 +106,10 @@ React is [BSD licensed](./LICENSE). We also provide an additional [patent grant]
|
||||
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)
|
||||
|
||||
45
circle.yml
45
circle.yml
@@ -1,45 +0,0 @@
|
||||
---
|
||||
machine:
|
||||
timezone: America/Los_Angeles
|
||||
node:
|
||||
version: 6
|
||||
ruby:
|
||||
version: 2.2.3
|
||||
environment:
|
||||
TRAVIS_REPO_SLUG: facebook/react
|
||||
YARN_VERSION: 0.17.8
|
||||
PATH: "${PATH}:${HOME}/.yarn/bin"
|
||||
|
||||
dependencies:
|
||||
pre:
|
||||
# This is equivalent to $TRAVIS_COMMIT_RANGE
|
||||
# Need to figure out how to bail early if this is a "docs only" build
|
||||
- echo $CIRCLE_COMPARE_URL | cut -d/ -f7
|
||||
# install yarn if it's not already installed
|
||||
- |
|
||||
if [[ ! -e ~/.yarn/bin/yarn || $(yarn --version) != "${YARN_VERSION}" ]]; then
|
||||
curl -o- -L https://yarnpkg.com/install.sh | bash -s -- --version $YARN_VERSION
|
||||
fi
|
||||
override:
|
||||
- bundle install --gemfile=docs/Gemfile --deployment --path=vendor/bundle --jobs=3 --retry=3
|
||||
- yarn install
|
||||
- scripts/circleci/set_up_github_keys.sh
|
||||
post:
|
||||
# - npm ls --depth=0
|
||||
cache_directories:
|
||||
- docs/vendor/bundle
|
||||
- ~/react-gh-pages # docs checkout
|
||||
- ~/.yarn
|
||||
- ~/.yarn-cache
|
||||
|
||||
test:
|
||||
override:
|
||||
- ./scripts/circleci/test_entry_point.sh:
|
||||
parallel: true
|
||||
|
||||
deployment:
|
||||
staging:
|
||||
branch: /.*/
|
||||
commands:
|
||||
- ./scripts/circleci/upload_build.sh
|
||||
- ./scripts/circleci/build_gh_pages.sh
|
||||
@@ -65,3 +65,6 @@ DEPENDENCIES
|
||||
rb-fsevent
|
||||
redcarpet
|
||||
sanitize (~> 2.0)
|
||||
|
||||
BUNDLED WITH
|
||||
1.11.2
|
||||
|
||||
@@ -1,32 +1,21 @@
|
||||
# React Documentation & Website
|
||||
|
||||
## [Read the React Documentation](https://facebook.github.io/react/)
|
||||
|
||||
This folder is not the right place to *read* the documentation.
|
||||
|
||||
Instead, head over [to the React website](https://facebook.github.io/react/) to read it.
|
||||
|
||||
This folder only contains the source code for the website.
|
||||
We use [Jekyll](http://jekyllrb.com/) to build the site using ([mostly](http://zpao.com/posts/adding-line-highlights-to-markdown-code-fences/)) Markdown, and we host it by pushing HTML to [GitHub Pages](http://pages.github.com/).
|
||||
|
||||
## Installation
|
||||
|
||||
If you are working on the site, you will want to install and run a local copy of it.
|
||||
|
||||
We use [Jekyll](http://jekyllrb.com/) to build the site using ([mostly](http://zpao.com/posts/adding-line-highlights-to-markdown-code-fences/)) Markdown, and we host it by pushing HTML to [GitHub Pages](http://pages.github.com/).
|
||||
|
||||
### Dependencies
|
||||
|
||||
In order to use Jekyll, you will need to have Ruby installed. macOS comes pre-installed with Ruby, but you may need to update RubyGems (via `gem update --system`).
|
||||
Otherwise, [RVM](https://rvm.io/) and [rbenv](https://github.com/sstephenson/rbenv) are popular ways to install Ruby.
|
||||
In order to use Jekyll, you will need to have Ruby installed.
|
||||
|
||||
- [Ruby](http://www.ruby-lang.org/) (version >= 1.8.7)
|
||||
- [RubyGems](http://rubygems.org/) (version >= 1.3.7)
|
||||
- [Bundler](http://gembundler.com/)
|
||||
|
||||
The version of the Pygment syntax highlighter used by Jekyll requires Python 2.7.x (not 3.x). macOS comes pre-installed with Python 2.7, but you may need to install it on other OSs.
|
||||
|
||||
- [Python](https://www.python.org) (version 2.7.x)
|
||||
|
||||
Mac OS X comes pre-installed with Ruby, but you may need to update RubyGems (via `gem update --system`).
|
||||
Otherwise, [RVM](https://rvm.io/) and [rbenv](https://github.com/sstephenson/rbenv) are popular ways to install Ruby.
|
||||
Once you have RubyGems and installed Bundler (via `gem install bundler`), use it to install the dependencies:
|
||||
|
||||
```sh
|
||||
@@ -37,16 +26,15 @@ $ npm install
|
||||
|
||||
### Instructions
|
||||
|
||||
The site requires React, so first make sure you've built the project (via [`grunt`](http://gruntjs.com/getting-started)).
|
||||
The site requires React, so first make sure you've built the project (via `grunt`).
|
||||
|
||||
Use Jekyll to serve the website locally (by default, at `http://localhost:4000`):
|
||||
|
||||
```sh
|
||||
$ cd react/docs
|
||||
$ bundle exec rake
|
||||
$ bundle exec rake fetch_remotes
|
||||
$ bundle exec jekyll serve -w
|
||||
$ open http://localhost:4000/react/index.html
|
||||
$ open http://localhost:4000/react/
|
||||
```
|
||||
|
||||
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://unpkg.com/babel-standalone@6.15.0/babel.min.js'),
|
||||
'js/babel.min.js'
|
||||
open('https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.34/browser.min.js'),
|
||||
'js/babel-browser.min.js'
|
||||
)
|
||||
end
|
||||
|
||||
@@ -37,6 +37,8 @@ task :update_hashes do
|
||||
map = {
|
||||
'react.js' => 'dev',
|
||||
'react.min.js' => 'prod',
|
||||
'react-with-addons.js' => 'addons_dev',
|
||||
'react-with-addons.min.js' => 'addons_prod',
|
||||
'react-dom.js' => 'dom_dev',
|
||||
'react-dom.min.js' => 'dom_prod',
|
||||
'react-dom-server.js' => 'dom_server_dev',
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
name: React
|
||||
description: A JavaScript library for building user interfaces
|
||||
url: https://facebook.github.io
|
||||
baseurl: /react
|
||||
permalink: /blog/:year/:month/:day/:title.html
|
||||
paginate_path: /blog/page:num/
|
||||
baseurl: "/react"
|
||||
permalink: "/blog/:year/:month/:day/:title.html"
|
||||
paginate_path: "/blog/page:num/"
|
||||
paginate: 5
|
||||
timezone: America/Los_Angeles
|
||||
highlighter: pygments
|
||||
@@ -20,12 +20,6 @@ defaults:
|
||||
type: pages
|
||||
values:
|
||||
sectionid: blog
|
||||
- scope:
|
||||
path: tutorial
|
||||
type: pages
|
||||
values:
|
||||
layout: tutorial
|
||||
sectionid: tutorial
|
||||
- scope:
|
||||
path: docs
|
||||
type: pages
|
||||
@@ -33,16 +27,15 @@ defaults:
|
||||
layout: docs
|
||||
sectionid: docs
|
||||
- scope:
|
||||
path: contributing
|
||||
path: tips
|
||||
type: pages
|
||||
values:
|
||||
sectionid: docs
|
||||
- scope:
|
||||
path: community
|
||||
path: contributing
|
||||
type: pages
|
||||
values:
|
||||
layout: community
|
||||
sectionid: community
|
||||
sectionid: docs
|
||||
exclude:
|
||||
- Gemfile
|
||||
- Gemfile.lock
|
||||
@@ -60,13 +53,13 @@ sass:
|
||||
gems:
|
||||
- jekyll-redirect-from
|
||||
- jekyll-paginate
|
||||
react_version: 15.4.0
|
||||
react_version: 15.3.0
|
||||
react_hashes:
|
||||
dev: buVLzxzBI8Ps3svVMSUurNdb5dozNidH5Ow4H0YgZeia3t6Oeui2VLpvtAq1fwtK
|
||||
prod: nCjsa0kjNQPQdxWm12/ReVJzfBJaVubEwwDswyQDGMKYJmeWv3qShMuETfU5fisu
|
||||
addons_dev: /u97pKzBwasbC1yj8gSIq1z30o4ZTUX9j1Mv/hyAjmG41ydTNHw9JFOhwFbDgxmR
|
||||
addons_prod: /p86n4b5VTlWoA/INEHQZ+zjx9g1pJduoFmTEJ6fSzFTq1mBaXaBcWVGtZJXD68L
|
||||
dom_dev: lUxkeWjg3I3lXmxcM1gvgo0yvm2w9alc1osa4L8yWZFO6l/vg9h5hSlHPFioltrm
|
||||
dom_prod: u8x1yIGN9IjGNYbBaDMsp1D4MK3sCmMU13mcBX+bm+aMo5+gaT8HIwIj39GlXaRS
|
||||
dom_server_dev: Okj1hVX1VF+oZSkPcJQ/YcnW6bsIpeni222ylwUaMnSmdCe0zWKmMwpFMVqzy4Ws
|
||||
dom_server_prod: wiA4u+G5fEfF4xzhhVnNWeSifVyttoEIpgc3APaMKQgw5A4wHbEMihf63tk1qoyt
|
||||
dev: R8v794QN9hrNjnivoQ3Mf7nMGVwFIHBkUmBanB40ZBIMttZbBEUatXNosjytvPUC
|
||||
prod: asiNTW+3f/iCKtm+05EX+4V4n6R5R1fyAY9M8Md0DLHodFResXMSBlt8ns9iJaPK
|
||||
addons_dev: iR3HmJX+5siYwRvy6ZXWWN/dNP4IuItUsfk0JJmwxaBIYtWHZhK/2N7wrAcxmpS8
|
||||
addons_prod: A/63GcxBS05SAxTWB0+wQKyQl8RVEH3nOuBuxwg/WV6yI5qpfEy4ksn90bqJdFJY
|
||||
dom_dev: PKr8yTHUBD0chzmoJ6ZYtB1nB87GTEWPmuDlDV7iARDrYGki2fmVB0ae3vf3LX0O
|
||||
dom_prod: TBEslZF7tpwiuBgt/ajgWUKvDGuCExkmEoWygscHE/OOajWS24BLAaf2/z7lj/9n
|
||||
dom_server_dev: UxEqwIE5+BLQKOqKHnPfJBOrSDo7HyocIl6sTb6taLayrVmDuhQ5VM4iauS54BbK
|
||||
dom_server_prod: hOLRkO2HGPRi0d73qKZWueHZyDD/6BID0CJax9kNUNaAvMR4atbNIcYfk2BoM8T3
|
||||
|
||||
@@ -112,6 +112,8 @@ li {
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
a {
|
||||
color: $linkColor;
|
||||
text-decoration: none;
|
||||
@@ -129,7 +131,3 @@ a {
|
||||
.center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
input {
|
||||
font-family: inherit;
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
$side: nth($pos, 2);
|
||||
|
||||
@if $length == 2 { // eg. to top
|
||||
// Swap for backwards compatibility
|
||||
// Swap for backwards compatability
|
||||
$degree: _position-flipper(nth($pos, 2));
|
||||
}
|
||||
@else if $length == 3 { // eg. to top left
|
||||
@@ -38,7 +38,7 @@
|
||||
$spec: to $side $corner;
|
||||
}
|
||||
@else if $length == 1 {
|
||||
// Swap for backwards compatibility
|
||||
// Swap for backwards compatability
|
||||
@if $type == string {
|
||||
$degree: $pos;
|
||||
$spec: to _position-flipper($pos);
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
# Map of short name to more information. `name` will be used but if you don't
|
||||
# want to use your real name, just use whatever. If url is included, your name
|
||||
# will be a link to the provided url.
|
||||
acdlite:
|
||||
name: Andrew Clark
|
||||
url: https://twitter.com/acdlite
|
||||
benigeri:
|
||||
name: Paul Benigeri
|
||||
url: https://github.com/benigeri
|
||||
@@ -16,9 +13,6 @@ Daniel15:
|
||||
fisherwebdev:
|
||||
name: Bill Fisher
|
||||
url: https://twitter.com/fisherwebdev
|
||||
flarnie:
|
||||
name: Flarnie Marchan
|
||||
url: https://twitter.com/ProbablyFlarnie
|
||||
gaearon:
|
||||
name: Dan Abramov
|
||||
url: https://twitter.com/dan_abramov
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
- 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
|
||||
@@ -1,10 +1,4 @@
|
||||
- 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,77 +1,104 @@
|
||||
- title: Quick Start
|
||||
items:
|
||||
- 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
|
||||
- id: getting-started
|
||||
title: Getting Started
|
||||
- id: tutorial
|
||||
title: Tutorial
|
||||
- id: thinking-in-react
|
||||
title: Thinking in React
|
||||
- title: Community Resources
|
||||
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: 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
|
||||
- id: higher-order-components
|
||||
title: Higher-Order Components
|
||||
- id: integrating-with-other-libraries
|
||||
title: Integrating with Other Libraries
|
||||
- id: accessibility
|
||||
title: Accessibility
|
||||
- title: Reference
|
||||
items:
|
||||
- id: react-api
|
||||
title: React
|
||||
subitems:
|
||||
- id: react-component
|
||||
title: React.Component
|
||||
- id: react-dom
|
||||
title: ReactDOM
|
||||
- id: react-dom-server
|
||||
title: ReactDOMServer
|
||||
- id: react-dom-node-stream
|
||||
title: ReactDOMNodeStream
|
||||
- id: dom-elements
|
||||
title: DOM Elements
|
||||
- id: events
|
||||
title: SyntheticEvent
|
||||
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: shallow-renderer
|
||||
title: Shallow Renderer
|
||||
- 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: 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
|
||||
|
||||
38
docs/_data/nav_tips.yml
Normal file
38
docs/_data/nav_tips.yml
Normal file
@@ -0,0 +1,38 @@
|
||||
- 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
|
||||
@@ -1,88 +0,0 @@
|
||||
- title: Tutorial
|
||||
items:
|
||||
- id: tutorial
|
||||
title: Before We Start
|
||||
subitems:
|
||||
- id: what-were-building
|
||||
title: What We're Building
|
||||
href: /react/tutorial/tutorial.html#what-were-building
|
||||
forceInternal: true
|
||||
- id: prerequisites
|
||||
title: Prerequisites
|
||||
href: /react/tutorial/tutorial.html#prerequisites
|
||||
forceInternal: true
|
||||
- id: how-to-follow-along
|
||||
title: How to Follow Along
|
||||
href: /react/tutorial/tutorial.html#how-to-follow-along
|
||||
forceInternal: true
|
||||
- id: help-im-stuck
|
||||
title: Help, I'm Stuck!
|
||||
href: /react/tutorial/tutorial.html#help-im-stuck
|
||||
forceInternal: true
|
||||
- id: overview
|
||||
title: Overview
|
||||
href: /react/tutorial/tutorial.html#overview
|
||||
forceInternal: true
|
||||
subitems:
|
||||
- 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
|
||||
@@ -1,41 +0,0 @@
|
||||
<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>
|
||||
@@ -1,13 +0,0 @@
|
||||
<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>
|
||||
@@ -1,24 +0,0 @@
|
||||
<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 | docs_sidebar_link}}
|
||||
{{ item | sidebar_item_link}}
|
||||
{% if item.subitems %}
|
||||
<ul>
|
||||
{% for subitem in item.subitems %}
|
||||
<li>
|
||||
{{ subitem | docs_sidebar_link }}
|
||||
{{ subitem | sidebar_item_link}}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
@@ -22,6 +22,20 @@
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
<!-- Tips Nav -->
|
||||
{% for section in site.data.nav_tips %}
|
||||
<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>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
<!-- Contributing Nav -->
|
||||
{% for section in site.data.nav_contributing %}
|
||||
<div class="nav-docs-section">
|
||||
@@ -35,5 +49,4 @@
|
||||
</ul>
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
</div>
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
<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>
|
||||
@@ -1,23 +0,0 @@
|
||||
<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://github.com/facebook/react/releases">v{{site.react_version}}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,30 +0,0 @@
|
||||
// Add anchors to headings client-side, which prevents them from showing up
|
||||
// in RSS feeds. See https://github.com/facebook/react/issues/4124.
|
||||
(function() {
|
||||
var selector = '.inner-content h2, .inner-content h3, .inner-content h4';
|
||||
var elements = document.querySelectorAll(selector);
|
||||
for (var i = 0; i < elements.length; i++) {
|
||||
var textMethod = document.body.textContent ? "textContent" : "innerText";
|
||||
var roughText = elements[i][textMethod];
|
||||
|
||||
// Regex rule for making the title URL-friendly.
|
||||
var urlFriendlyText = roughText.trim()
|
||||
.toLowerCase()
|
||||
.replace(/\s+/g, '-')
|
||||
.replace(/[^A-Za-z0-9\-_.\p{Cyrillic}\p{Hangul}\p{Hiragana}\p{Katakana}\p{Han}]/g, '');
|
||||
|
||||
// Create the anchor we'll jump to.
|
||||
var anchor = document.createElement('a');
|
||||
anchor.className = 'anchor';
|
||||
anchor.name = urlFriendlyText;
|
||||
elements[i].insertBefore(anchor, elements[i].firstChild);
|
||||
|
||||
// Create the clickable "#" icon.
|
||||
var hashLink = document.createElement('a');
|
||||
var icon = document.createTextNode("#");
|
||||
hashLink.appendChild(icon);
|
||||
hashLink.className = 'hash-link';
|
||||
hashLink.href = '#' + urlFriendlyText;
|
||||
elements[i].appendChild(hashLink);
|
||||
}
|
||||
}());
|
||||
@@ -1,13 +1,12 @@
|
||||
var name = Math.random() > 0.5 ? 'Jane' : 'John';
|
||||
var HELLO_COMPONENT = `
|
||||
class HelloMessage extends React.Component {
|
||||
render() {
|
||||
var HelloMessage = React.createClass({
|
||||
render: function() {
|
||||
return <div>Hello {this.props.name}</div>;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ReactDOM.render(<HelloMessage name="${name}" />, mountNode);
|
||||
`.trim();
|
||||
ReactDOM.render(<HelloMessage name="John" />, mountNode);
|
||||
`;
|
||||
|
||||
ReactDOM.render(
|
||||
<ReactPlayground codeText={HELLO_COMPONENT} />,
|
||||
|
||||
@@ -1,40 +1,35 @@
|
||||
var MARKDOWN_COMPONENT = `
|
||||
class MarkdownEditor extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.handleChange = this.handleChange.bind(this);
|
||||
this.state = {value: 'Type some *markdown* here!'};
|
||||
}
|
||||
|
||||
handleChange(e) {
|
||||
this.setState({value: e.target.value});
|
||||
}
|
||||
|
||||
getRawMarkup() {
|
||||
var MarkdownEditor = React.createClass({
|
||||
getInitialState: function() {
|
||||
return {value: 'Type some *markdown* here!'};
|
||||
},
|
||||
handleChange: function() {
|
||||
this.setState({value: this.refs.textarea.value});
|
||||
},
|
||||
rawMarkup: function() {
|
||||
var md = new Remarkable();
|
||||
return { __html: md.render(this.state.value) };
|
||||
}
|
||||
|
||||
render() {
|
||||
},
|
||||
render: function() {
|
||||
return (
|
||||
<div className="MarkdownEditor">
|
||||
<h3>Input</h3>
|
||||
<textarea
|
||||
onChange={this.handleChange}
|
||||
defaultValue={this.state.value}
|
||||
/>
|
||||
ref="textarea"
|
||||
defaultValue={this.state.value} />
|
||||
<h3>Output</h3>
|
||||
<div
|
||||
className="content"
|
||||
dangerouslySetInnerHTML={this.getRawMarkup()}
|
||||
dangerouslySetInnerHTML={this.rawMarkup()}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ReactDOM.render(<MarkdownEditor />, mountNode);
|
||||
`.trim();
|
||||
`;
|
||||
|
||||
ReactDOM.render(
|
||||
<ReactPlayground codeText={MARKDOWN_COMPONENT} />,
|
||||
|
||||
@@ -1,33 +1,26 @@
|
||||
var TIMER_COMPONENT = `
|
||||
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() {
|
||||
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() {
|
||||
clearInterval(this.interval);
|
||||
}
|
||||
|
||||
render() {
|
||||
},
|
||||
render: function() {
|
||||
return (
|
||||
<div>Seconds Elapsed: {this.state.secondsElapsed}</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ReactDOM.render(<Timer />, mountNode);
|
||||
`.trim();
|
||||
`;
|
||||
|
||||
ReactDOM.render(
|
||||
<ReactPlayground codeText={TIMER_COMPONENT} />,
|
||||
|
||||
@@ -1,56 +1,41 @@
|
||||
var TODO_COMPONENT = `
|
||||
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 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>;
|
||||
}
|
||||
|
||||
render() {
|
||||
});
|
||||
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() {
|
||||
return (
|
||||
<div>
|
||||
<h3>TODO</h3>
|
||||
<TodoList items={this.state.items} />
|
||||
<form onSubmit={this.handleSubmit}>
|
||||
<input onChange={this.handleChange} value={this.state.text} />
|
||||
<input onChange={this.onChange} 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,4 +1,4 @@
|
||||
// Ideally it would be nice to just redirect, but GitHub Pages is very basic and
|
||||
// Ideally it would be nice to just redirect, but Github Pages is very basic and
|
||||
// lacks that functionality.
|
||||
console.warn(
|
||||
'html-jsx-lib.js has moved to http://reactjs.github.io/react-magic/' +
|
||||
|
||||
@@ -21,7 +21,7 @@ var CodeMirrorEditor = React.createClass({
|
||||
componentDidMount: function() {
|
||||
if (IS_MOBILE) return;
|
||||
|
||||
this.editor = CodeMirror.fromTextArea(this.refs.editor, {
|
||||
this.editor = CodeMirror.fromTextArea(ReactDOM.findDOMNode(this.refs.editor), {
|
||||
mode: 'jsx',
|
||||
lineNumbers: this.props.lineNumbers,
|
||||
lineWrapping: true,
|
||||
@@ -90,14 +90,8 @@ var ReactPlayground = React.createClass({
|
||||
|
||||
getDefaultProps: function() {
|
||||
return {
|
||||
transformer: function(code, options) {
|
||||
var presets = ['react'];
|
||||
if (!options || !options.skipES2015Transform) {
|
||||
presets.push('es2015');
|
||||
}
|
||||
return Babel.transform(code, {
|
||||
presets
|
||||
}).code;
|
||||
transformer: function(code) {
|
||||
return babel.transform(code).code;
|
||||
},
|
||||
editorTabTitle: 'Live JSX Editor',
|
||||
showCompiledJSTab: true,
|
||||
@@ -121,15 +115,15 @@ var ReactPlayground = React.createClass({
|
||||
this.setState({mode: mode});
|
||||
},
|
||||
|
||||
compileCode: function(options) {
|
||||
return this.props.transformer(this.state.code, options);
|
||||
compileCode: function() {
|
||||
return this.props.transformer(this.state.code);
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var isJS = this.state.mode === this.MODES.JS;
|
||||
var compiledCode = '';
|
||||
try {
|
||||
compiledCode = this.compileCode({skipES2015Transform: true});
|
||||
compiledCode = this.compileCode();
|
||||
} catch (err) {}
|
||||
|
||||
var JSContent =
|
||||
@@ -200,32 +194,26 @@ var ReactPlayground = React.createClass({
|
||||
},
|
||||
|
||||
executeCode: function() {
|
||||
var mountNode = this.refs.mount;
|
||||
var mountNode = ReactDOM.findDOMNode(this.refs.mount);
|
||||
|
||||
try {
|
||||
ReactDOM.unmountComponentAtNode(mountNode);
|
||||
} catch (e) { }
|
||||
|
||||
try {
|
||||
var compiledCode;
|
||||
var compiledCode = this.compileCode();
|
||||
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) {
|
||||
// Babel errors are preformatted, runtime errors are not.
|
||||
const errorMessage = err._babel ?
|
||||
<pre style={{overflowX: 'auto'}} className="playgroundError">{err.toString()}</pre> :
|
||||
<div className="playgroundError">{err.toString()}</div>;
|
||||
this.setTimeout(function() {
|
||||
ReactDOM.render(
|
||||
errorMessage,
|
||||
<div className="playgroundError">{err.toString()}</div>,
|
||||
mountNode
|
||||
);
|
||||
}, 500);
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
---
|
||||
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>
|
||||
@@ -4,6 +4,8 @@ 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>
|
||||
@@ -18,6 +20,4 @@ sectionid: contributing
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% include nav_docs.html %}
|
||||
</section>
|
||||
|
||||
@@ -1,30 +1,16 @@
|
||||
{% if page.excerpt %}
|
||||
{% assign type = 'article' %}
|
||||
{% assign sectionTitle = 'React Blog' %}
|
||||
{% assign description = page.excerpt | strip_html %}
|
||||
{% else %}
|
||||
{% assign type = 'website' %}
|
||||
{% assign sectionTitle = 'React' %}
|
||||
{% assign description = 'A JavaScript library for building user interfaces' %}
|
||||
{% endif %}
|
||||
{% if page.id == 'home' %}
|
||||
{% assign title = sectionTitle | append: ' - ' | append: page.title %}
|
||||
{% else %}
|
||||
{% assign title = page.title | append: ' - ' | append: sectionTitle %}
|
||||
{% endif %}
|
||||
<!DOCTYPE html>
|
||||
<!--[if IE]><![endif]-->
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<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 }}">
|
||||
<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">
|
||||
<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="{{ description }}">
|
||||
<meta property="og:description" content="A JavaScript library for building user interfaces">
|
||||
<meta property="fb:app_id" content="623268441017527">
|
||||
|
||||
<link rel="shortcut icon" href="/react/favicon.ico">
|
||||
@@ -39,33 +25,78 @@
|
||||
<script>try{Typekit.load();}catch(e){}</script>
|
||||
|
||||
<!--[if lte IE 8]>
|
||||
<script src="https://unpkg.com/html5shiv@3.7.3/dist/html5shiv.min.js"></script>
|
||||
<script src="https://unpkg.com/es5-shim@4.5.9/es5-shim.min.js"></script>
|
||||
<script src="https://unpkg.com/es5-shim@4.5.9/es5-sham.min.js"></script>
|
||||
<script src="/react/js/html5shiv.min.js"></script>
|
||||
<script src="/react/js/es5-shim.min.js"></script>
|
||||
<script src="/react/js/es5-sham.min.js"></script>
|
||||
<![endif]-->
|
||||
<script src="https://unpkg.com/docsearch.js@1.5.0/dist/cdn/docsearch.min.js"></script>
|
||||
<script src="https://unpkg.com/codemirror@5.15.2"></script>
|
||||
<script src="https://unpkg.com/codemirror@5.15.2/mode/javascript/javascript.js"></script>
|
||||
<script src="https://unpkg.com/codemirror@5.15.2/mode/xml/xml.js"></script>
|
||||
<script src="https://unpkg.com/codemirror@5.15.2/mode/jsx/jsx.js"></script>
|
||||
<script src="https://unpkg.com/react/dist/react.min.js"></script>
|
||||
<script src="https://unpkg.com/react-dom/dist/react-dom.min.js"></script>
|
||||
<script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
|
||||
<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/live_editor.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="container">
|
||||
|
||||
{% include navigation.html %}
|
||||
<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' or page.sectionid == 'contributing' %} 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 %}
|
||||
|
||||
{{ content }}
|
||||
|
||||
{% include footer.html %}
|
||||
<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>
|
||||
</div>
|
||||
|
||||
<div id="fb-root"></div>
|
||||
<script src="/react/js/anchor-links.js"></script>
|
||||
|
||||
<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),
|
||||
|
||||
@@ -4,6 +4,8 @@ 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>
|
||||
@@ -22,6 +24,4 @@ sectionid: docs
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% include nav_docs.html %}
|
||||
</section>
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
---
|
||||
|
||||
{% if page.id == 'home' %}
|
||||
{% include hero.html %}
|
||||
{% endif %}
|
||||
|
||||
<section class="content wrap">
|
||||
{{ content }}
|
||||
</section>
|
||||
@@ -4,9 +4,8 @@ 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>
|
||||
|
||||
23
docs/_layouts/tips.html
Normal file
23
docs/_layouts/tips.html
Normal file
@@ -0,0 +1,23 @@
|
||||
---
|
||||
layout: default
|
||||
sectionid: tips
|
||||
---
|
||||
|
||||
<section class="content wrap documentationContent">
|
||||
{% include nav_docs.html %}
|
||||
|
||||
<div class="inner-content">
|
||||
<h1>{{ page.title }}</h1>
|
||||
<div class="subHeader">{{ page.description }}</div>
|
||||
{{ content }}
|
||||
|
||||
<div class="docs-prevnext">
|
||||
{% if page.prev %}
|
||||
<a class="docs-prev" href="/react/tips/{{ page.prev }}">← Prev</a>
|
||||
{% endif %}
|
||||
{% if page.next %}
|
||||
<a class="docs-next" href="/react/tips/{{ page.next }}">Next →</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -1,29 +0,0 @@
|
||||
---
|
||||
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>
|
||||
20
docs/_plugins/header_links.rb
Normal file
20
docs/_plugins/header_links.rb
Normal file
@@ -0,0 +1,20 @@
|
||||
require 'redcarpet'
|
||||
require 'sanitize'
|
||||
|
||||
# Simple converter that is probably better than RedCarpet's built in TOC id
|
||||
# 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\-_.\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
|
||||
end
|
||||
|
||||
@@ -1,39 +1,20 @@
|
||||
module Jekyll
|
||||
module SidebarItemFilter
|
||||
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"]
|
||||
|
||||
def sidebar_item_link(item)
|
||||
pageID = @context.registers[:page]["id"]
|
||||
itemID = item["id"]
|
||||
href = item["href"] || "/react/#{group}/#{itemID}.html"
|
||||
href = item["href"] || "/react/docs/#{itemID}.html"
|
||||
classes = []
|
||||
if pageID == itemID
|
||||
classes.push("active")
|
||||
end
|
||||
if item["href"] && (forceInternal == nil)
|
||||
if item["href"]
|
||||
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/2h6th4ju/) to see an example of
|
||||
[this jsFiddle](http://jsfiddle.net/fv6RD/3/) to see an example of
|
||||
reconciliation in action.
|
||||
|
||||
Because this re-render is so fast (around 1ms for TodoMVC), the developer
|
||||
|
||||
@@ -32,7 +32,7 @@ It looks like [Ben Alpert](http://benalpert.com/) is the first person outside of
|
||||
|
||||
[Mario Mueller](http://blog.xenji.com/) wrote a menu component in React and was able to easily integrate it with require.js, EventEmitter2 and bower.
|
||||
|
||||
> I recently stumbled upon facebook's React library, which is a JavaScript library for building reusable frontend components. Even if this lib is only at version 0.3.x it behaves very stable, it is fast and is fun to code. I'm a big fan of require.js, so I tried to use React within the require.js eco system. It was not as hard as expected and here are some examples and some thoughts about it.
|
||||
> I recently stumbled upon facebook's React library, which is a Javascript library for building reusable frontend components. Even if this lib is only at version 0.3.x it behaves very stable, it is fast and is fun to code. I'm a big fan of require.js, so I tried to use React within the require.js eco system. It was not as hard as expected and here are some examples and some thoughts about it.
|
||||
>
|
||||
> [Read the full post...](http://blog.xenji.com/2013/06/facebooks-react-require-js.html)
|
||||
|
||||
@@ -40,7 +40,7 @@ It looks like [Ben Alpert](http://benalpert.com/) is the first person outside of
|
||||
|
||||
[Pete Hunt](http://www.petehunt.net/blog/) explained what differentiates React from other JavaScript libraries in [a previous blog post](/react/blog/2013/06/05/why-react.html). [Lee Byron](http://leebyron.com/) gives another perspective on Quora:
|
||||
|
||||
> React isn't quite like any other popular JavaScript libraries, and it solves a very specific problem: complex UI rendering. It's also intended to be used along side many other popular libraries. For example, React works well with Backbone.js, amongst many others.
|
||||
> React isn't quite like any other popular Javascript libraries, and it solves a very specific problem: complex UI rendering. It's also intended to be used along side many other popular libraries. For example, React works well with Backbone.js, amongst many others.
|
||||
>
|
||||
> React was born out of frustrations with the common pattern of writing two-way data bindings in complex MVC apps. React is an implementation of one-way data bindings.
|
||||
>
|
||||
|
||||
@@ -9,7 +9,7 @@ Since the launch we have received a lot of feedback and are actively working on
|
||||
|
||||
[Andrew Greig](http://www.andrewgreig.com/) made a blog post that gives a high level description of what React is.
|
||||
|
||||
> I have been using Facebooks recently released JavaScript framework called React.js for the last few days and have managed to obtain a rather high level understanding of how it works and formed a good perspective on how it fits in to the entire javascript framework ecosystem.
|
||||
> I have been using Facebooks recently released Javascript framework called React.js for the last few days and have managed to obtain a rather high level understanding of how it works and formed a good perspective on how it fits in to the entire javascript framework ecosystem.
|
||||
>
|
||||
> Basically, React is not an MVC framework. It is not a replacement for Backbone or Knockout or Angular, instead it is designed to work with existing frameworks and help extend their functionality.
|
||||
>
|
||||
|
||||
@@ -19,7 +19,7 @@ The highlight of this week is that an interaction-heavy app has been ported to R
|
||||
|
||||
## Grunt Task for JSX
|
||||
|
||||
[Eric Clemmons](https://ericclemmons.github.io/) wrote a task for [Grunt](http://gruntjs.com/) that applies the JSX transformation to your JavaScript files. It also works with [Browserify](http://browserify.org/) if you want all your files to be concatenated and minified together.
|
||||
[Eric Clemmons](https://ericclemmons.github.io/) wrote a task for [Grunt](http://gruntjs.com/) that applies the JSX transformation to your Javascript files. It also works with [Browserify](http://browserify.org/) if you want all your files to be concatenated and minified together.
|
||||
|
||||
> Grunt task for compiling Facebook React's .jsx templates into .js
|
||||
>
|
||||
@@ -81,9 +81,9 @@ browserify: {
|
||||
>
|
||||
> [Read the full post...](http://blog.vjeux.com/2013/javascript/react-coffeescript.html)
|
||||
|
||||
## Tutorial in Plain JavaScript
|
||||
## Tutorial in Plain Javascript
|
||||
|
||||
We've seen a lot of people comparing React with various frameworks. [Ricardo Tomasi](http://ricardo.cc/) decided to re-implement the tutorial without any framework, just plain JavaScript.
|
||||
We've seen a lot of people comparing React with various frameworks. [Ricardo Tomasi](http://ricardo.cc/) decided to re-implement the tutorial without any framework, just plain Javascript.
|
||||
|
||||
> Facebook & Instagram launched the React framework and an accompanying tutorial. Developer Vlad Yazhbin decided to rewrite that using AngularJS. The end result is pretty neat, but if you're like me you will not actually appreciate the HTML speaking for itself and doing all the hard work. So let's see what that looks like in plain javascript.
|
||||
>
|
||||
|
||||
@@ -47,11 +47,11 @@ 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="100%" height="340" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe></figure>
|
||||
<figure><iframe src="https://player.vimeo.com/video/67248575" width="500" height="340" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe></figure>
|
||||
|
||||
## Snake in React
|
||||
|
||||
[Tom Occhino](http://tomocchino.com/) implemented Snake in 150 lines with React.
|
||||
|
||||
> [Check the source on GitHub](https://github.com/tomocchino/react-snake/blob/master/src/snake.js)
|
||||
> [Check the source on Github](https://github.com/tomocchino/react-snake/blob/master/src/snake.js)
|
||||
> <figure>[](https://tomocchino.github.io/react-snake/)</figure>
|
||||
|
||||
@@ -18,7 +18,7 @@ We launched the [React Facebook Page](https://www.facebook.com/react) along with
|
||||
|
||||
## React Samples
|
||||
|
||||
Learning a new library is always easier when you have working examples you can play with. [jwh](https://github.com/jhw) put many of them on his [react-samples GitHub repo](https://github.com/jhw/react-samples).
|
||||
Learning a new library is always easier when you have working examples you can play with. [jwh](https://github.com/jhw) put many of them on his [react-samples Github repo](https://github.com/jhw/react-samples).
|
||||
|
||||
> Some simple examples with Facebook's React framework
|
||||
>
|
||||
@@ -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="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>
|
||||
<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>
|
||||
|
||||
|
||||
## 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="100%" height="400" src="//www.youtube-nocookie.com/embed/XxVg_s8xAms" frameborder="0" allowfullscreen></iframe></figure>
|
||||
<figure><iframe width="650" height="400" src="//www.youtube-nocookie.com/embed/XxVg_s8xAms" frameborder="0" allowfullscreen></iframe></figure>
|
||||
|
||||
|
||||
## Docs
|
||||
|
||||
@@ -23,7 +23,7 @@ This is the first Community Round-up where none of the items are from Facebook/I
|
||||
>
|
||||
> `reactify` transform activates for files with either `.jsx` extension or `/** @jsx React.DOM */` pragma as a first line for any `.js` file.
|
||||
>
|
||||
> [Check it out on GitHub...](https://github.com/andreypopp/reactify)
|
||||
> [Check it out on Github...](https://github.com/andreypopp/reactify)
|
||||
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ este.demos.react.todoApp = este.react.create (`/** @lends {React.ReactComponent.
|
||||
]
|
||||
```
|
||||
|
||||
[Check it out on GitHub...](https://github.com/steida/este-library/blob/master/este/demos/thirdparty/react/start.coffee)
|
||||
[Check it out on Github...](https://github.com/steida/este-library/blob/master/este/demos/thirdparty/react/start.coffee)
|
||||
|
||||
|
||||
## React Stylus Boilerplate
|
||||
@@ -64,7 +64,7 @@ este.demos.react.todoApp = este.react.create (`/** @lends {React.ReactComponent.
|
||||
> - `grunt build` to compile JSX and Stylus into a development build
|
||||
> - `grunt dist` to minify and optimize the development build for production
|
||||
>
|
||||
> [Check it out on GitHub...](https://github.com/zaim/react-stylus-boilerplate)
|
||||
> [Check it out on Github...](https://github.com/zaim/react-stylus-boilerplate)
|
||||
|
||||
|
||||
## WebFUI
|
||||
|
||||
@@ -8,7 +8,7 @@ It's been three months since we open sourced React and it is going well. Some st
|
||||
* 114 285 unique visitors on this website
|
||||
* [1933 stars](https://github.com/facebook/react/stargazers) and [210 forks](https://github.com/facebook/react/network/members)
|
||||
* [226 posts on Google Group](https://groups.google.com/forum/#!forum/reactjs)
|
||||
* [76 GitHub projects using React](https://gist.github.com/vjeux/6335762)
|
||||
* [76 Github projects using React](https://gist.github.com/vjeux/6335762)
|
||||
* [30 contributors](https://github.com/facebook/react/graphs/contributors)
|
||||
* [15 blog posts](/react/blog/)
|
||||
* 2 early adopters: [Khan Academy](http://benalpert.com/2013/06/09/using-react-to-speed-up-khan-academy.html) and [Propeller](http://usepropeller.com/blog/posts/from-backbone-to-react/)
|
||||
|
||||
@@ -9,9 +9,9 @@ First, we are organizing a [React Hackathon](http://reactjshack-a-thon.splashtha
|
||||
|
||||
We've also reached a point where there are too many questions for us to handle directly. We're encouraging people to ask questions on [StackOverflow](http://stackoverflow.com/questions/tagged/reactjs) using the tag [[reactjs]](http://stackoverflow.com/questions/tagged/reactjs). Many members of the team and community have subscribed to the tag, so feel free to ask questions there. We think these will be more discoverable than Google Groups archives or IRC logs.
|
||||
|
||||
## JavaScript Jabber
|
||||
## Javascript Jabber
|
||||
|
||||
[Pete Hunt](http://www.petehunt.net/) and [Jordan Walke](https://github.com/jordwalke) were interviewed on [JavaScript Jabber](http://javascriptjabber.com/073-jsj-react-with-pete-hunt-and-jordan-walke/) for an hour. They go over many aspects of React such as 60 FPS, Data binding, Performance, Diffing Algorithm, DOM Manipulation, Node.js support, server-side rendering, JSX, requestAnimationFrame and the community. This is a gold mine of information about React.
|
||||
[Pete Hunt](http://www.petehunt.net/) and [Jordan Walke](https://github.com/jordwalke) were interviewed on [Javascript Jabber](http://javascriptjabber.com/073-jsj-react-with-pete-hunt-and-jordan-walke/) for an hour. They go over many aspects of React such as 60 FPS, Data binding, Performance, Diffing Algorithm, DOM Manipulation, Node.js support, server-side rendering, JSX, requestAnimationFrame and the community. This is a gold mine of information about React.
|
||||
|
||||
> **PETE:** So React was designed all around that. Conceptually, how you build a React app is that every time your data changes, it's like hitting the refresh button in a server-rendered app. What we do is we conceptually throw out all of the markup and event handlers that you've registered and we reset the whole page and then we redraw the entire page. If you're writing a server-rendered app, handling updates is really easy because you hit the refresh button and you're pretty much guaranteed to get what you expect.
|
||||
>
|
||||
@@ -53,7 +53,7 @@ While this is not going to work for all the attributes since they are camelCased
|
||||
|
||||
## Markdown in React
|
||||
|
||||
[Ben Alpert](http://benalpert.com/) converted [marked](https://github.com/chjj/marked), a Markdown JavaScript implementation, in React: [marked-react](https://github.com/spicyj/marked-react). Even without using JSX, the HTML generation is now a lot cleaner. It is also safer as forgetting a call to `escape` will not introduce an XSS vulnerability.
|
||||
[Ben Alpert](http://benalpert.com/) converted [marked](https://github.com/chjj/marked), a Markdown Javascript implementation, in React: [marked-react](https://github.com/spicyj/marked-react). Even without using JSX, the HTML generation is now a lot cleaner. It is also safer as forgetting a call to `escape` will not introduce an XSS vulnerability.
|
||||
<figure>[](https://github.com/spicyj/marked-react/commit/cb70c9df6542c7c34ede9efe16f9b6580692a457)</figure>
|
||||
|
||||
|
||||
|
||||
@@ -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="100%" 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="550" height="450" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" allowfullscreen></iframe></figure>
|
||||
|
||||
|
||||
## Pump - Clojure bindings for React
|
||||
@@ -96,3 +96,4 @@ 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="100%" height="370" src="//www.youtube-nocookie.com/embed/x7cQ3mrcKaY" frameborder="0" allowfullscreen></iframe></figure>
|
||||
<figure><iframe width="600" 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="100%" height="338" src="//www.youtube-nocookie.com/embed/1OeXsL5mr4g" frameborder="0" allowfullscreen></iframe></figure>
|
||||
<figure><iframe width="600" 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="100%" 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="600" height="468" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"> </iframe></figure>
|
||||
|
||||
|
||||
## JSX
|
||||
|
||||
@@ -5,7 +5,7 @@ author: vjeux
|
||||
|
||||
React got featured on the front-page of Hacker News thanks to the Om library. If you try it out for the first time, take a look at the [docs](/react/docs/getting-started.html) and do not hesitate to ask questions on the [Google Group](https://groups.google.com/group/reactjs), [IRC](irc://chat.freenode.net/reactjs) or [Stack Overflow](http://stackoverflow.com/questions/tagged/reactjs). We are trying our best to help you out!
|
||||
|
||||
## The Future of JavaScript MVC
|
||||
## The Future of Javascript MVC
|
||||
|
||||
[David Nolen](https://swannodette.github.io/) announced Om, a thin wrapper on-top of React in ClojureScript. It stands out by only using immutable data structures. This unlocks the ability to write a very efficient [shouldComponentUpdate](/react/docs/component-specs.html#updating-shouldcomponentupdate) and get huge performance improvements on some tasks.
|
||||
|
||||
|
||||
@@ -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="100%" height="400" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe></figure>
|
||||
<figure><iframe src="//player.vimeo.com/video/79659941" width="220" height="400" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe></figure>
|
||||
|
||||
[Try out the demos!](https://petehunt.github.io/react-touch/)
|
||||
|
||||
@@ -19,18 +19,18 @@ 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="100%" height="315" src="//www.youtube-nocookie.com/embed/SMMRJif5QW0" frameborder="0" allowfullscreen></iframe></figure>
|
||||
<figure><iframe width="560" height="315" src="//www.youtube-nocookie.com/embed/SMMRJif5QW0" frameborder="0" allowfullscreen></iframe></figure>
|
||||
|
||||
|
||||
## JSX: E4X The Good Parts
|
||||
|
||||
JSX is often compared to the now defunct E4X, [Vjeux](http://blog.vjeux.com/) went over all the E4X features and explained how JSX is different and hopefully doesn't repeat the same mistakes.
|
||||
|
||||
> E4X (ECMAScript for XML) is a JavaScript syntax extension and a runtime to manipulate XML. It was promoted by Mozilla but failed to become mainstream and is now deprecated. JSX was inspired by E4X. In this article, I'm going to go over all the features of E4X and explain the design decisions behind JSX.
|
||||
> E4X (ECMAScript for XML) is a Javascript syntax extension and a runtime to manipulate XML. It was promoted by Mozilla but failed to become mainstream and is now deprecated. JSX was inspired by E4X. In this article, I'm going to go over all the features of E4X and explain the design decisions behind JSX.
|
||||
>
|
||||
> **Historical Context**
|
||||
>
|
||||
> E4X has been created in 2002 by John Schneider. This was the golden age of XML where it was being used for everything: data, configuration files, code, interfaces (DOM) ... E4X was first implemented inside of Rhino, a JavaScript implementation from Mozilla written in Java.
|
||||
> E4X has been created in 2002 by John Schneider. This was the golden age of XML where it was being used for everything: data, configuration files, code, interfaces (DOM) ... E4X was first implemented inside of Rhino, a Javascript implementation from Mozilla written in Java.
|
||||
>
|
||||
> [Continue reading ...](http://blog.vjeux.com/2013/javascript/jsx-e4x-the-good-parts.html)
|
||||
|
||||
@@ -115,3 +115,4 @@ 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="100%" height="315" src="//www.youtube-nocookie.com/embed/Cey7BS6dE0M" frameborder="0" allowfullscreen></iframe></figure>
|
||||
<figure><iframe width="560" 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,3 +15,4 @@ 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/tutorial/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/docs/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
|
||||
|
||||
@@ -3,7 +3,7 @@ title: "Community Round-up #15"
|
||||
author: jgebhardt
|
||||
---
|
||||
|
||||
Interest in React seems to have surged ever since David Nolen ([@swannodette](https://twitter.com/swannodette))'s introduction of [Om](https://github.com/swannodette/om) in his post ["The Future of JavaScript MVC Frameworks"](https://swannodette.github.io/2013/12/17/the-future-of-javascript-mvcs/).
|
||||
Interest in React seems to have surged ever since David Nolen ([@swannodette](https://twitter.com/swannodette))'s introduction of [Om](https://github.com/swannodette/om) in his post ["The Future of Javascript MVC Frameworks"](https://swannodette.github.io/2013/12/17/the-future-of-javascript-mvcs/).
|
||||
|
||||
In this React Community Round-up, we are taking a closer look at React from a functional programming perspective.
|
||||
|
||||
@@ -21,7 +21,7 @@ Dan Holmsand ([@holmsand](https://twitter.com/holmsand)) created [Reagent](https
|
||||
>
|
||||
> The goal of Reagent is to make it possible to define arbitrarily complex UIs using just a couple of basic concepts, and to be fast enough by default that you rarely have to care about performance.
|
||||
>
|
||||
> [Check it out on GitHub...](https://holmsand.github.io/reagent/)
|
||||
> [Check it out on Github...](https://holmsand.github.io/reagent/)
|
||||
|
||||
|
||||
## Functional DOM programming
|
||||
@@ -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="100%" height="315" src="//www.youtube-nocookie.com/embed/Lqcs6hPOcFw?start=2963" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="560" 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="100%" height="420" scrolling="no" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
|
||||
<iframe src="//slid.es/johnlynch/reactjs/embed" width="576" height="420" scrolling="no" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
|
||||
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ Joe Maddalone ([@joemaddalone](https://twitter.com/joemaddalone)) of [egghead.io
|
||||
|
||||
Eric Florenzano ([@ericflo](https://twitter.com/ericflo)) sheds some light on what makes React perfect for server rendering:
|
||||
|
||||
> [...] the ideal solution would fully render the markup on the server, deliver it to the client so that it can be shown to the user instantly. Then it would asynchronously load some JavaScript that would attach to the rendered markup, and invisibly promote the page into a full app that can render its own markup. [...]
|
||||
> [...] the ideal solution would fully render the markup on the server, deliver it to the client so that it can be shown to the user instantly. Then it would asynchronously load some Javascript that would attach to the rendered markup, and invisibly promote the page into a full app that can render its own markup. [...]
|
||||
|
||||
> What I've discovered is that enough of the pieces have come together, that this futuristic-sounding web environment is actually surprisingly easy to do now with React.js.
|
||||
|
||||
|
||||
@@ -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="100%" height="315" src="//www.youtube-nocookie.com/embed/jYcpaemt90M" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="560" 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="100%" height="315" src="//www.youtube-nocookie.com/embed/srt3OBP2kGc?start=113" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="560" 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="100%" height="315" src="//www.youtube-nocookie.com/embed/nYkdrAPrdcw?list=PLb0IAmt7-GS188xDYE-u1ShQmFFGbrk0v&start=621" frameborder="0" allowfullscreen></iframe></figure>
|
||||
<figure><iframe width="560" 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.
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ author: chenglou
|
||||
|
||||
Today marks the one-year open-source anniversary of React.
|
||||
|
||||
It’s been a crazy ride. 2.3k commits and 1.5k issues and pull requests later, we’re approaching version 1.0 and nearing 7k GitHub stars, with big names such as Khan Academy, New York Times, and Airbnb (and naturally, Facebook and Instagram) using React in production, and many more developers blogging their success stories with it. The [roadmap](/react/blog/2014/03/28/the-road-to-1.0.html) gives a glimpse into the future of the library; exciting stuff lies ahead!
|
||||
It’s been a crazy ride. 2.3k commits and 1.5k issues and pull requests later, we’re approaching version 1.0 and nearing 7k Github stars, with big names such as Khan Academy, New York Times, and Airbnb (and naturally, Facebook and Instagram) using React in production, and many more developers blogging their success stories with it. The [roadmap](/react/blog/2014/03/28/the-road-to-1.0.html) gives a glimpse into the future of the library; exciting stuff lies ahead!
|
||||
|
||||
Every success has its story. React was born out of our frustration at existing solutions for building UIs. When it was first suggested at Facebook, few people thought that functionally re-rendering everything and diffing the results could ever perform well. However, support grew after we built the first implementation and people wrote their first components. When we open-sourced React, the initial reception was [similarly skeptical](https://www.reddit.com/r/programming/comments/1fak87/react_facebooks_latest_javascript_client_library/). It challenges many pre-established conventions and received mostly disapproving first-impressions, intermingled with positive ones that often were votes of confidence in Facebook’s engineering capabilities. On an open, competitive platform such as the web, it's been hard to convince people to try React. [JSX](/react/docs/jsx-in-depth.html), in particular, filtered out a huge chunk of potential early adopters.
|
||||
|
||||
|
||||
@@ -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="100%" height="315" src="//www.youtube-nocookie.com/embed/KZjFVdU8VLI" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="560" 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="100%" height="315" src="//www.youtube-nocookie.com/embed/D-ioDiacTm8" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="650" 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="100%" height="315" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
|
||||
<iframe src="//player.vimeo.com/video/100010922" width="650" 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="100%" height="315" src="//www.youtube-nocookie.com/embed/CP3lvm5Ppqo" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="650" 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.
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ React.renderComponent((
|
||||
|
||||
## Going Big with React
|
||||
|
||||
Areeb Malik, from Facebook, talks about his experience using React. "On paper, all those JS frameworks look promising: clean implementations, quick code design, flawless execution. But what happens when you stress test JavaScript? What happens when you throw 6 megabytes of code at it? In this talk, we'll investigate how React performs in a high stress situation, and how it has helped our team build safe code on a massive scale"
|
||||
Areeb Malik, from Facebook, talks about his experience using React. "On paper, all those JS frameworks look promising: clean implementations, quick code design, flawless execution. But what happens when you stress test Javascript? What happens when you throw 6 megabytes of code at it? In this talk, we'll investigate how React performs in a high stress situation, and how it has helped our team build safe code on a massive scale"
|
||||
|
||||
[](https://skillsmatter.com/skillscasts/5429-going-big-with-react)
|
||||
|
||||
@@ -32,7 +32,7 @@ Areeb Malik, from Facebook, talks about his experience using React. "On paper, a
|
||||
|
||||
## What is React?
|
||||
|
||||
[Craig McKeachie](http://www.funnyant.com/author/admin/) author of [JavaScript Framework Guide](http://www.funnyant.com/javascript-framework-guide/) wrote an excellent news named ["What is React.js? Another Template Library?](http://www.funnyant.com/reactjs-what-is-it/)
|
||||
[Craig McKeachie](http://www.funnyant.com/author/admin/) author of [Javascript Framework Guide](http://www.funnyant.com/javascript-framework-guide/) wrote an excellent news named ["What is React.js? Another Template Library?](http://www.funnyant.com/reactjs-what-is-it/)
|
||||
|
||||
- Is React a template library?
|
||||
- Is React similar to Web Components?
|
||||
@@ -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="100%" height="315" src="//www.youtube-nocookie.com/embed/lAn7GVoGlKU" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="650" 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="100%" height="315" src="//www.youtube-nocookie.com/embed/eCf5CquV_Bw" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="650" 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="100%" height="200" src="//www.youtube-nocookie.com/embed/rFvZydtmsxM" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="650" 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="100%" height="315" src="//www.youtube-nocookie.com/embed/i__969noyAM" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="650" 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="100%" height="315" scrolling="no" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
|
||||
<iframe src="//slides.com/danabramov/components-react-flux-wip/embed" width="650" 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="100%" height="315" src="//www.youtube-nocookie.com/embed/XhXC4SKOGfQ" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="650" 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="100%" height="315" src="//www.youtube-nocookie.com/embed/rI0GQc__0SM" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="560" 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="100%" height="315" src="//www.youtube-nocookie.com/embed/m2fuO2wl_3c" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="560" 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="100%" height="315" src="//www.youtube-nocookie.com/embed/uZgAq1CZ1N8" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="420" 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="100%" height="315" src="//www.youtube-nocookie.com/embed/5yHFTN-_mOo" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="420" 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="100%" height="171" src="https://www.youtube-nocookie.com/embed/KVZ-P-ZI6W4" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="305" height="171" src="https://www.youtube-nocookie.com/embed/KVZ-P-ZI6W4" frameborder="0" allowfullscreen></iframe>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -24,11 +24,11 @@ It was a privilege to welcome the React community to Facebook HQ on January 28
|
||||
<div class="skinny-col">
|
||||
<h3 style="margin-top:0"><a class="anchor" name="talk-tweak"></a>Tweaking in real time <a class="hash-link" href="#talk-tweak">#</a></h3>
|
||||
<p>
|
||||
<strong>Brenton Simpson</strong> showed us how eBay brings Bret Victor’s feedback loop to your favorite editor using webpack, react-hot-loader, and <a href="https://github.com/appsforartists/ambidex">Ambidex</a>.
|
||||
<strong>Brenton Simpson</strong> showed us how eBay brings Bret Victor’s feedback loop to your favorite editor using Webpack, react-hot-loader, and <a href="https://github.com/appsforartists/ambidex">Ambidex</a>.
|
||||
</p>
|
||||
</div>
|
||||
<div class="skinny-col">
|
||||
<iframe width="100%" height="171" src="https://www.youtube-nocookie.com/embed/yaymfLj5tjA" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="305" 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="100%" height="171" src="https://www.youtube-nocookie.com/embed/OZGgVxFxSIs" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="305" 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="100%" height="171" src="https://www.youtube-nocookie.com/embed/9sc8Pyc51uU" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="305" 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="100%" height="171" src="https://www.youtube-nocookie.com/embed/W2DgDNQZOwo" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="305" 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="100%" height="171" src="https://www.youtube-nocookie.com/embed/XZfvW1a8Xac" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="305" 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="100%" height="171" src="https://www.youtube-nocookie.com/embed/KtmjkCuV-EU" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="305" 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="100%" height="171" src="https://www.youtube-nocookie.com/embed/KYzlpRvWZ6c" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="305" 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="100%" height="171" src="https://www.youtube-nocookie.com/embed/Sla-DkvmIHY" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="305" 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="100%" height="171" src="https://www.youtube-nocookie.com/embed/z5e7kWSHWTg" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="305" 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="100%" height="171" src="https://www.youtube-nocookie.com/embed/7rDsRXj9-cU" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="305" 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="100%" height="171" src="https://www.youtube-nocookie.com/embed/g0TD0efcwVg" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="305" height="171" src="https://www.youtube-nocookie.com/embed/g0TD0efcwVg" frameborder="0" allowfullscreen></iframe>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -156,11 +156,11 @@ It was a privilege to welcome the React community to Facebook HQ on January 28
|
||||
<div class="skinny-col">
|
||||
<h3 style="margin-top:0"><a class="anchor" name="talk-immutable"></a>Immutability <a class="hash-link" href="#talk-immutable">#</a></h3>
|
||||
<p>
|
||||
<strong>Lee Byron</strong> led a master-class on persistent immutable data structures, showing us the world of possibility that they can unlock for your software, and perhaps JavaScript in general.
|
||||
<strong>Lee Byron</strong> led a master-class on persistent immutable data structures, showing us the world of possibility that they can unlock for your software, and perhaps Javascript in general.
|
||||
</p>
|
||||
</div>
|
||||
<div class="skinny-col">
|
||||
<iframe width="100%" height="171" src="https://www.youtube-nocookie.com/embed/I7IdS-PbEgI" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="305" 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="100%" height="171" src="https://www.youtube-nocookie.com/embed/eNC0mRYGWgc" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="305" 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="100%" height="171" src="https://www.youtube-nocookie.com/embed/2ii1lEkIv1s" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="305" 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="100%" height="171" src="https://www.youtube-nocookie.com/embed/5hGHdETNteE" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="305" 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="100%" height="171" src="https://www.youtube-nocookie.com/embed/LTj4O7WJJ98" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="305" 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="100%" height="171" src="https://www.youtube-nocookie.com/embed/ZM6wXoFTY3o" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="305" 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="100%" height="171" src="https://www.youtube-nocookie.com/embed/9PTa9-PPVAc" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="305" 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="100%" height="171" src="https://www.youtube-nocookie.com/embed/EPpkboSKvPI" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="305" height="171" src="https://www.youtube-nocookie.com/embed/EPpkboSKvPI" frameborder="0" allowfullscreen></iframe>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -245,7 +245,7 @@ It was a privilege to welcome the React community to Facebook HQ on January 28
|
||||
|
||||
The conference is over, but the conversation has just begun.
|
||||
|
||||
**Mihai Parparita** detailed his efforts to [hack his way to a React.js Conf ticket](http://blog.persistent.info/2014/12/html-munging-my-way-to-reactjs-conf.html); **James Long** blogged about [his first encounter with React Native](http://jlongster.com/First-Impressions-using-React-Native); **Eric Florenzano** talked about how he perceives the [impact of Relay, GraphQL, and React Native](https://medium.com/@ericflo/facebook-just-taught-us-all-how-to-build-websites-51f1e7e996f2) on software development; **Margaret Staples** blogged about her experience of [being on-campus at Facebook HQ](http://deadlugosi.blogspot.com/2015/02/facebook-gave-me-ice-cream.html); **Jeff Barczewski** tied his experience of attending the conference up with a bow in this [blog post filled with photos, videos, and links](http://codewinds.com/blog/2015-02-04-reactjs-conf.html); **Kevin Old** left us with [his takeaways](http://kevinold.com/2015/01/31/takeaways-from-reactjs-conf-2015.html); **Paul Wittmann** found React Native [freshly on his radar](http://www.railslove.com/stories/fresh-on-our-radar-react-native); and finally, undeterred by not being able to attend the conference in person, **Justin Ball** [summarized it from afar](http://www.justinball.com/2015/02/02/i-didn't-attend-react.js-conf.html).
|
||||
**Mihai Parparita** detailed his efforts to [hack his way to a React.js Conf ticket](http://blog.persistent.info/2014/12/html-munging-my-way-to-reactjs-conf.html); **James Long** blogged about [his first encounter with React Native](http://jlongster.com/First-Impressions-using-React-Native); **Eric Florenzano** talked about how he perceives the [impact of Relay, GraphQL, and React Native](https://medium.com/@ericflo/facebook-just-taught-us-all-how-to-build-websites-51f1e7e996f2) on software development; **Margaret Staples** blogged about her experience of [being on-campus at Facebook HQ](http://deadlugosi.blogspot.com/2015/02/facebook-gave-me-ice-cream.html); **Jeff Barczewski** tied his experience of attending the conference up with a bow in this [blog post filled with photos, videos, and links](http://codewinds.com/blog/2015-02-04-reactjs-conf.html); **Kevin Old** left us with [his takeaways](http://kevinold.com/2015/01/31/takeaways-from-reactjs-conf-2015.html); **Paul Wittmann** found React Native [freshly on his radar](http://www.railslove.com/stories/fresh-on-our-radar-react-native); and finally, undeterred by not being able to attend the conference in person, **Justin Ball** [summarized it from afar](http://www.justinball.com/2015/02/03/i-didn't-attend-react.js-conf/).
|
||||
|
||||
And, in case you missed a session, you can borrow **Michael Chan’s** [drawings](http://chantastic.io/2015-reactjs-conf/), **Mihai Parparita’s** [summary](https://quip.com/uJQeABv7nkFN), or **Shaohua Zhou’s** [day 1](http://getshao.com/2015/01/29/react-js-conf-notes-day1/) / [day 2](http://getshao.com/2015/01/29/react-js-conf-notes-day-2/) notes.
|
||||
|
||||
@@ -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="100%" height="171" src="https://www.youtube-nocookie.com/embed/FC5FbmsH4fw" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="305" 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="100%" height="315" src="https://www.youtube-nocookie.com/embed/9sc8Pyc51uU" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="560" 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="100%" height="300" src="//www.youtube-nocookie.com/embed/Pd6Ub7Ju2RM" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="650" 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="100%" 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="650" 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="100%" height="315" src="https://www.youtube-nocookie.com/embed/X6YbAKiLCLU?start=2220" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/X6YbAKiLCLU?start=2220" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
|
||||
## Ray Wenderlich - Property Finder
|
||||
@@ -75,11 +75,11 @@ Jay Garcia spent a lot of time during the beta working on a NES music player wit
|
||||
</center>
|
||||
|
||||
|
||||
## React Native with Babel and webpack
|
||||
## React Native with Babel and Webpack
|
||||
|
||||
React Native ships with a custom packager and custom ES6 transforms instead of using what the open source community settled on such as webpack and Babel. The main reason for this is performance – we couldn't get those tools to have sub-second reload time on a large codebase.
|
||||
React Native ships with a custom packager and custom ES6 transforms instead of using what the open source community settled on such as Webpack and Babel. The main reason for this is performance – we couldn't get those tools to have sub-second reload time on a large codebase.
|
||||
|
||||
Roman Liutikov found a way to [use webpack and Babel to run on React Native](https://github.com/roman01la/react-native-babel)! In the future, we want to work with those projects to provide cleaner extension mechanisms.
|
||||
Roman Liutikov found a way to [use Webpack and Babel to run on React Native](https://github.com/roman01la/react-native-babel)! In the future, we want to work with those projects to provide cleaner extension mechanisms.
|
||||
|
||||
|
||||
## A Dynamic, Crazy, Native Mobile Future—Powered by JavaScript
|
||||
@@ -92,3 +92,4 @@ 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="100%" height="300" src="https://www.youtube.com/embed/mOyoTUETmSM" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="650" height="300" src="https://www.youtube.com/embed/mOyoTUETmSM" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
@@ -8,46 +8,46 @@ 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="100%" height="366" src="//www.youtube.com/embed/PAA9O4E1IM4" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="650" 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="100%" height="366" src="//www.youtube.com/embed/xDlfrcM6YBk" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="650" 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="100%" height="366" src="//www.youtube.com/embed/WQLzZf34FJ8" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="650" 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="100%" height="366" src="//www.youtube.com/embed/IrgHurBjQbg" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="650" 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="100%" height="366" src="//www.youtube.com/embed/gY48GW87Feo" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="650" 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="100%" height="366" src="//www.youtube.com/embed/Zemce4Y1Y-A" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="650" 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="100%" height="366" src="//www.youtube.com/embed/OFuDvqZmUrE" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="650" 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="100%" height="366" src="//www.youtube.com/embed/1tavDv5hXpo" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="650" 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="100%" height="366" src="//www.youtube.com/embed/CRJZBZ_-6hQ" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="650" height="366" src="//www.youtube.com/embed/CRJZBZ_-6hQ" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
And there were lots of great talks from the React community:
|
||||
|
||||
* [Michael Chan](https://www.youtube.com/watch?v=ERB1TJBn32c&list=PLCC436JpVnK0Phxld2dD4tM4xPMxJCiRD&index=2) looks at how to solve problems like CSS theming and media queries with contexts and plain old JavaScript. He also looks at the role of container-components and when it's better to "just use CSS.".
|
||||
* [Elie Rotenberg](https://www.youtube.com/watch?v=JSjhhUvB9DY&index=3&list=PLCC436JpVnK0Phxld2dD4tM4xPMxJCiRD) talks about Flux over the Wire, building isomorphic, real-time React apps using a novel interpretation of Flux.
|
||||
* [Ryan Florence](https://www.youtube.com/watch?v=BF58ZJ1ZQxY&list=PLCC436JpVnK0Phxld2dD4tM4xPMxJCiRD&index=6) says “Your front and back ends are already successfully in production but you don't have to miss out on the productivity that React brings. Forget the rewrites, this is brownfield!”.
|
||||
* [Dan Abramov](https://www.youtube.com/watch?v=xsSnOQynTHs&index=7&list=PLCC436JpVnK0Phxld2dD4tM4xPMxJCiRD) demonstrates how React can be used together with webpack Hot Module Replacement to create a live editing environment with time travel that supercharges your debugging experience and transforms the way you work on real apps every day.
|
||||
* [Dan Abramov](https://www.youtube.com/watch?v=xsSnOQynTHs&index=7&list=PLCC436JpVnK0Phxld2dD4tM4xPMxJCiRD) demonstrates how React can be used together with Webpack Hot Module Replacement to create a live editing environment with time travel that supercharges your debugging experience and transforms the way you work on real apps every day.
|
||||
* [Mikhail Davydov](https://www.youtube.com/watch?v=ee_U2t-8L48&index=10&list=PLCC436JpVnK0Phxld2dD4tM4xPMxJCiRD) shows you how to ask the browser layout engine for help, how to avoid slavery of DSL, and build declarative Text UI using only web-technologies like HTML, JS, CSS and React.
|
||||
* [Kevin Robinson](https://www.youtube.com/watch?v=EOz4D_714R8&list=PLCC436JpVnK3HvUSAHpt-LRJkIK8pQG6R&index=3) shares how user experience choices are a primary influence on how Twitter design the data layer, especially for teams developing new products with full-stack capabilities.
|
||||
* [Jed Watson](https://www.youtube.com/watch?v=ctwmd5L1U_Q&list=PLCC436JpVnK3HvUSAHpt-LRJkIK8pQG6R&index=4) shares what Thinkmill have learned about React and mobile app development, and how they've approached the unique challenges of mobile web apps - with tools that are useful to all developers building touch interfaces with React, as well as a walkthrough of their development process and framework.
|
||||
|
||||
@@ -54,16 +54,18 @@ cancelablePromise
|
||||
cancelablePromise.cancel(); // Cancel the promise
|
||||
```
|
||||
|
||||
Where `makeCancelable` was originally [defined by @istarkov](https://github.com/facebook/react/issues/5465#issuecomment-157888325) as:
|
||||
Where `makeCancelable` is [defined by @istarkov](https://github.com/facebook/react/issues/5465#issuecomment-157888325) as:
|
||||
|
||||
```js
|
||||
const makeCancelable = (promise) => {
|
||||
let hasCanceled_ = false;
|
||||
|
||||
const wrappedPromise = new Promise((resolve, reject) => {
|
||||
promise.then(
|
||||
val => hasCanceled_ ? reject({isCanceled: true}) : resolve(val),
|
||||
error => hasCanceled_ ? reject({isCanceled: true}) : reject(error)
|
||||
promise.then((val) =>
|
||||
hasCanceled_ ? reject({isCanceled: true}) : resolve(val)
|
||||
);
|
||||
promise.catch((error) =>
|
||||
hasCanceled_ ? reject({isCanceled: true}) : reject(error)
|
||||
);
|
||||
});
|
||||
|
||||
@@ -75,5 +77,4 @@ const makeCancelable = (promise) => {
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
As an added bonus for getting your code cleaned up early, getting rid of `isMounted()` makes it one step easier for you to upgrade to ES6 classes, where using `isMounted()` is already prohibited. Happy coding!
|
||||
|
||||
@@ -440,7 +440,7 @@ Multiple components may be sharing `RowMixin` to render the header, and each of
|
||||
|
||||
If you see rendering logic inside a mixin, it’s time to extract a component!
|
||||
|
||||
Instead of `RowMixin`, we will define a `<RowHeader>` component. We will also replace the convention of defining a `getHeaderText()` method with the standard mechanism of top-data flow in React: passing props.
|
||||
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:
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ Run `npm start` to launch the development server. The browser will open automati
|
||||
|
||||

|
||||
|
||||
Create React App uses both webpack and Babel under the hood.
|
||||
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:
|
||||
|
||||

|
||||
@@ -76,7 +76,7 @@ Your `package.json` contains only a single build dependency and a few scripts:
|
||||
}
|
||||
```
|
||||
|
||||
We take care of updating Babel, ESLint, and webpack to stable compatible versions so you can update a single dependency to get them all.
|
||||
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
|
||||
|
||||
|
||||
@@ -1,229 +0,0 @@
|
||||
---
|
||||
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 benefited 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!
|
||||
@@ -1,174 +0,0 @@
|
||||
---
|
||||
title: "React v15.4.0"
|
||||
author: gaearon
|
||||
---
|
||||
|
||||
Today we are releasing React 15.4.0.
|
||||
|
||||
We didn't announce the [previous](https://github.com/facebook/react/blob/master/CHANGELOG.md#1510-may-20-2016) [minor](https://github.com/facebook/react/blob/master/CHANGELOG.md#1520-july-1-2016) [releases](https://github.com/facebook/react/blob/master/CHANGELOG.md#1530-july-29-2016) on the blog because most of the changes were bug fixes. However, 15.4.0 is a special release, and we would like to highlight a few notable changes in it.
|
||||
|
||||
### Separating React and React DOM
|
||||
|
||||
[More than a year ago](/react/blog/2015/09/10/react-v0.14-rc1.html#two-packages-react-and-react-dom), we started separating React and React DOM into separate packages. We deprecated `React.render()` in favor of `ReactDOM.render()` in React 0.14, and removed DOM-specific APIs from `React` completely in React 15. However, the React DOM implementation still [secretly lived inside the React package](https://www.reddit.com/r/javascript/comments/3m6wyu/found_this_line_in_the_react_codebase_made_me/cvcyo4a/).
|
||||
|
||||
In React 15.4.0, we are finally moving React DOM implementation to the React DOM package. The React package will now contain only the renderer-agnostic code such as `React.Component` and `React.createElement()`.
|
||||
|
||||
This solves a few long-standing issues, such as [errors](https://github.com/facebook/react/issues/7386) when you import React DOM in the same file as the [snapshot testing](https://facebook.github.io/jest/blog/2016/07/27/jest-14.html) renderer.
|
||||
|
||||
**If you only use the official and documented React APIs you won't need to change anything in your application.**
|
||||
|
||||
However, there is a possibility that you imported private APIs from `react/lib/*`, or that a package you rely on might use them. We would like to remind you that this was never supported, and that your apps should not rely on internal APIs. The React internals will keep changing as we work to make React better.
|
||||
|
||||
Another thing to watch out for is that React DOM Server is now about the same size as React DOM since it contains its own copy of the React reconciler. We don't recommend using React DOM Server on the client in most cases.
|
||||
|
||||
### Profiling Components with Chrome Timeline
|
||||
|
||||
You can now visualize React components in the Chrome Timeline. This lets you see which components exactly get mounted, updated, and unmounted, how much time they take relative to each other.
|
||||
|
||||
<center><img src="/react/img/blog/react-perf-chrome-timeline.png" width="651" height="228" alt="React components in Chrome timeline" /></center>
|
||||
|
||||
To use it:
|
||||
|
||||
1. Load your app with `?react_perf` in the query string (for example, `http://localhost:3000/?react_perf`).
|
||||
|
||||
2. Open the Chrome DevTools **Timeline** tab and press **Record**.
|
||||
|
||||
3. Perform the actions you want to profile. Don't record more than 20 seconds or Chrome might hang.
|
||||
|
||||
4. Stop recording.
|
||||
|
||||
5. React events will be grouped under the **User Timing** label.
|
||||
|
||||
Note that the numbers are relative so components will render faster in production. Still, this should help you realize when unrelated UI gets updated by mistake, and how deep and how often your UI updates occur.
|
||||
|
||||
Currently Chrome, Edge, and IE are the only browsers supporting this feature, but we use the standard [User Timing API](https://developer.mozilla.org/en-US/docs/Web/API/User_Timing_API) so we expect more browsers to add support for it.
|
||||
|
||||
### Mocking Refs for Snapshot Testing
|
||||
|
||||
If you're using Jest [snapshot testing](https://facebook.github.io/jest/blog/2016/07/27/jest-14.html), you might have had [issues](https://github.com/facebook/react/issues/7371) with components that rely on refs. With React 15.4.0, we introduce a way to provide mock refs to the test renderer. For example, consider this component using a ref in `componentDidMount`:
|
||||
|
||||
```js{5,11}
|
||||
import React from 'react';
|
||||
|
||||
export default class MyInput extends React.Component {
|
||||
componentDidMount() {
|
||||
this.input.focus();
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<input
|
||||
ref={node => this.input = node}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
With snapshot renderer, `this.input` will be `null` because there is no DOM. React 15.4.0 lets us avoid such crashes by passing a custom `createNodeMock` function to the snapshot renderer in an `options` argument:
|
||||
|
||||
```js{5-12,16}
|
||||
import React from 'react';
|
||||
import MyInput from './MyInput';
|
||||
import renderer from 'react-test-renderer';
|
||||
|
||||
function createNodeMock(element) {
|
||||
if (element.type === 'input') {
|
||||
return {
|
||||
focus() {},
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
it('renders correctly', () => {
|
||||
const options = {createNodeMock};
|
||||
const tree = renderer.create(<MyInput />, options);
|
||||
expect(tree).toMatchSnapshot();
|
||||
});
|
||||
```
|
||||
|
||||
We would like to thank [Brandon Dail](https://github.com/Aweary) for implementing this feature.
|
||||
|
||||
You can learn more about snapshot testing in [this Jest blog post](https://facebook.github.io/jest/blog/2016/07/27/jest-14.html).
|
||||
|
||||
---
|
||||
|
||||
## Installation
|
||||
|
||||
We recommend using [Yarn](https://yarnpkg.com/) or [npm](https://www.npmjs.com/) for managing front-end dependencies. If you're new to package managers, the [Yarn documentation](https://yarnpkg.com/en/docs/getting-started) is a good place to get started.
|
||||
|
||||
To install React with Yarn, run:
|
||||
|
||||
```bash
|
||||
yarn add react@15.4.0 react-dom@15.4.0
|
||||
```
|
||||
|
||||
To install React with npm, run:
|
||||
|
||||
```bash
|
||||
npm install --save react@15.4.0 react-dom@15.4.0
|
||||
```
|
||||
|
||||
We recommend using a bundler like [webpack](https://webpack.js.org/) or [Browserify](http://browserify.org/) so you can write modular code and bundle it together into small packages to optimize load time.
|
||||
|
||||
Remember that by default, React runs extra checks and provides helpful warnings in development mode. When deploying your app, make sure to [compile it in production mode](/react/docs/installation.html#development-and-production-versions).
|
||||
|
||||
In case you don't use a bundler, we also provide pre-built bundles in the npm packages which you can [include as script tags](/react/docs/installation.html#using-a-cdn) on your page:
|
||||
|
||||
* **React**
|
||||
Dev build with warnings: [react/dist/react.js](https://unpkg.com/react@15.4.0/dist/react.js)
|
||||
Minified build for production: [react/dist/react.min.js](https://unpkg.com/react@15.4.0/dist/react.min.js)
|
||||
* **React with Add-Ons**
|
||||
Dev build with warnings: [react/dist/react-with-addons.js](https://unpkg.com/react@15.4.0/dist/react-with-addons.js)
|
||||
Minified build for production: [react/dist/react-with-addons.min.js](https://unpkg.com/react@15.4.0/dist/react-with-addons.min.js)
|
||||
* **React DOM** (include React in the page before React DOM)
|
||||
Dev build with warnings: [react-dom/dist/react-dom.js](https://unpkg.com/react-dom@15.4.0/dist/react-dom.js)
|
||||
Minified build for production: [react-dom/dist/react-dom.min.js](https://unpkg.com/react-dom@15.4.0/dist/react-dom.min.js)
|
||||
* **React DOM Server** (include React in the page before React DOM Server)
|
||||
Dev build with warnings: [react-dom/dist/react-dom-server.js](https://unpkg.com/react-dom@15.4.0/dist/react-dom-server.js)
|
||||
Minified build for production: [react-dom/dist/react-dom-server.min.js](https://unpkg.com/react-dom@15.4.0/dist/react-dom-server.min.js)
|
||||
|
||||
We've also published version `15.4.0` of the `react`, `react-dom`, and addons packages on npm and the `react` package on bower.
|
||||
|
||||
- - -
|
||||
|
||||
## Changelog
|
||||
|
||||
### React
|
||||
* React package and browser build no longer "secretly" includes React DOM.
|
||||
<small>([@sebmarkbage](https://github.com/sebmarkbage) in [#7164](https://github.com/facebook/react/pull/7164) and [#7168](https://github.com/facebook/react/pull/7168))</small>
|
||||
* Required PropTypes now fail with specific messages for null and undefined.
|
||||
<small>([@chenglou](https://github.com/chenglou) in [#7291](https://github.com/facebook/react/pull/7291))</small>
|
||||
* Improved development performance by freezing children instead of copying.
|
||||
<small>([@keyanzhang](https://github.com/keyanzhang) in [#7455](https://github.com/facebook/react/pull/7455))</small>
|
||||
|
||||
### React DOM
|
||||
* Fixed occasional test failures when React DOM is used together with shallow renderer.
|
||||
<small>([@goatslacker](https://github.com/goatslacker) in [#8097](https://github.com/facebook/react/pull/8097))</small>
|
||||
* Added a warning for invalid `aria-` attributes.
|
||||
<small>([@jessebeach](https://github.com/jessebeach) in [#7744](https://github.com/facebook/react/pull/7744))</small>
|
||||
* Added a warning for using `autofocus` rather than `autoFocus`.
|
||||
<small>([@hkal](https://github.com/hkal) in [#7694](https://github.com/facebook/react/pull/7694))</small>
|
||||
* Removed an unnecessary warning about polyfilling `String.prototype.split`.
|
||||
<small>([@nhunzaker](https://github.com/nhunzaker) in [#7629](https://github.com/facebook/react/pull/7629))</small>
|
||||
* Clarified the warning about not calling PropTypes manually.
|
||||
<small>([@jedwards1211](https://github.com/jedwards1211) in [#7777](https://github.com/facebook/react/pull/7777))</small>
|
||||
* The unstable `batchedUpdates` API now passes the wrapped function's return value through.
|
||||
<small>([@bgnorlov](https://github.com/bgnorlov) in [#7444](https://github.com/facebook/react/pull/7444))</small>
|
||||
* Fixed a bug with updating text in IE 8.
|
||||
<small>([@mnpenner](https://github.com/mnpenner) in [#7832](https://github.com/facebook/react/pull/7832))</small>
|
||||
|
||||
### React Perf
|
||||
* When ReactPerf is started, you can now view the relative time spent in components as a chart in Chrome Timeline.
|
||||
<small>([@gaearon](https://github.com/gaearon) in [#7549](https://github.com/facebook/react/pull/7549))</small>
|
||||
|
||||
### React Test Utils
|
||||
* If you call `Simulate.click()` on a `<input disabled onClick={foo} />` then `foo` will get called whereas it didn't before.
|
||||
<small>([@nhunzaker](https://github.com/nhunzaker) in [#7642](https://github.com/facebook/react/pull/7642))</small>
|
||||
|
||||
### React Test Renderer
|
||||
* Due to packaging changes, it no longer crashes when imported together with React DOM in the same file.
|
||||
<small>([@sebmarkbage](https://github.com/sebmarkbage) in [#7164](https://github.com/facebook/react/pull/7164) and [#7168](https://github.com/facebook/react/pull/7168))</small>
|
||||
* `ReactTestRenderer.create()` now accepts `{createNodeMock: element => mock}` as an optional argument so you can mock refs with snapshot testing.
|
||||
<small>([@Aweary](https://github.com/Aweary) in [#7649](https://github.com/facebook/react/pull/7649) and [#8261](https://github.com/facebook/react/pull/8261))</small>
|
||||
@@ -1,227 +0,0 @@
|
||||
---
|
||||
title: "React v15.5.0"
|
||||
author: acdlite
|
||||
---
|
||||
|
||||
It's been exactly one year since the last breaking change to React. Our next major release, React 16, will include some exciting improvements, including a [complete rewrite](https://www.youtube.com/watch?v=ZCuYPiUIONs) of React's internals. [We take stability seriously](/react/contributing/design-principles.html#stability), and are committed to bringing those improvements to all of our users with minimal effort.
|
||||
|
||||
To that end, today we're releasing React 15.5.0.
|
||||
|
||||
### New Deprecation Warnings
|
||||
|
||||
The biggest change is that we've extracted `React.PropTypes` and `React.createClass` into their own packages. Both are still accessible via the main `React` object, but using either will log a one-time deprecation warning to the console when in development mode. This will enable future code size optimizations.
|
||||
|
||||
These warnings will not affect the behavior of your application. However, we realize they may cause some frustration, particularly if you use a testing framework that treats `console.error` as a failure.
|
||||
|
||||
**Adding new warnings is not something we do lightly.** Warnings in React are not mere suggestions — they are integral to our strategy of keeping as many people as possible on the latest version of React. We never add warnings without providing an incremental path forward.
|
||||
|
||||
So while the warnings may cause frustration in the short-term, we believe **prodding developers to migrate their codebases now prevents greater frustration in the future**. Proactively fixing warnings ensures you are prepared for the next major release. If your app produces zero warnings in 15.5, it should continue to work in 16 without any changes.
|
||||
|
||||
For each of these new deprecations, we've provided a codemod to automatically migrate your code. They are available as part of the [react-codemod](https://github.com/reactjs/react-codemod) project.
|
||||
|
||||
### Migrating from React.PropTypes
|
||||
|
||||
Prop types are a feature for runtime validation of props during development. We've extracted the built-in prop types to a separate package to reflect the fact that not everybody uses them.
|
||||
|
||||
In 15.5, instead of accessing `PropTypes` from the main `React` object, install the `prop-types` package and import them from there:
|
||||
|
||||
```js{11,16,25}
|
||||
// Before (15.4 and below)
|
||||
import React from 'react';
|
||||
|
||||
class Component extends React.Component {
|
||||
render() {
|
||||
return <div>{this.props.text}</div>;
|
||||
}
|
||||
}
|
||||
|
||||
Component.propTypes = {
|
||||
text: React.PropTypes.string.isRequired,
|
||||
}
|
||||
|
||||
// After (15.5)
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
class Component extends React.Component {
|
||||
render() {
|
||||
return <div>{this.props.text}</div>;
|
||||
}
|
||||
}
|
||||
|
||||
Component.propTypes = {
|
||||
text: PropTypes.string.isRequired,
|
||||
};
|
||||
```
|
||||
|
||||
The [codemod](https://github.com/reactjs/react-codemod#react-proptypes-to-prop-types) for this change performs this conversion automatically. Basic usage:
|
||||
|
||||
```bash
|
||||
jscodeshift -t react-codemod/transforms/React-PropTypes-to-prop-types.js <path>
|
||||
```
|
||||
|
||||
|
||||
The `propTypes`, `contextTypes`, and `childContextTypes` APIs will work exactly as before. The only change is that the built-in validators now live in a separate package.
|
||||
|
||||
You may also consider using [Flow](https://flow.org/) to statically type check your JavaScript code, including [React components](https://flow.org/en/docs/frameworks/react/#setup-flow-with-react-a-classtoc-idtoc-setup-flow-with-react-hreftoc-setup-flow-with-reacta).
|
||||
|
||||
### Migrating from React.createClass
|
||||
|
||||
When React was initially released, there was no idiomatic way to create classes in JavaScript, so we provided our own: `React.createClass`.
|
||||
|
||||
Later, classes were added to the language as part of ES2015, so we added the ability to create React components using JavaScript classes. **Along with functional components, JavaScript classes are now the [preferred way to create components in React](/react/docs/components-and-props.html#functional-and-class-components).**
|
||||
|
||||
For your existing `createClass` components, we recommend that you migrate them to JavaScript classes. However, if you have components that rely on mixins, converting to classes may not be immediately feasible. If so, `create-react-class` is available on npm as a drop-in replacement:
|
||||
|
||||
```js{4,13,15}
|
||||
// Before (15.4 and below)
|
||||
var React = require('react');
|
||||
|
||||
var Component = React.createClass({
|
||||
mixins: [MixinA],
|
||||
render() {
|
||||
return <Child />;
|
||||
}
|
||||
});
|
||||
|
||||
// After (15.5)
|
||||
var React = require('react');
|
||||
var createReactClass = require('create-react-class');
|
||||
|
||||
var Component = createReactClass({
|
||||
mixins: [MixinA],
|
||||
render() {
|
||||
return <Child />;
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
Your components will continue to work the same as they did before.
|
||||
|
||||
The [codemod](https://github.com/reactjs/react-codemod#explanation-of-the-new-es2015-class-transform-with-property-initializers) for this change attempts to convert a `createClass` component to a JavaScript class, with a fallback to `create-react-class` if necessary. It has converted thousands of components internally at Facebook.
|
||||
|
||||
Basic usage:
|
||||
|
||||
```bash
|
||||
jscodeshift -t react-codemod/transforms/class.js path/to/components
|
||||
```
|
||||
|
||||
### Discontinuing support for React Addons
|
||||
|
||||
We're discontinuing active maintenance of React Addons packages. In truth, most of these packages haven't been actively maintained in a long time. They will continue to work indefinitely, but we recommend migrating away as soon as you can to prevent future breakages.
|
||||
|
||||
- **react-addons-create-fragment** – React 16 will have first-class support for fragments, at which point this package won't be necessary. We recommend using arrays of keyed elements instead.
|
||||
- **react-addons-css-transition-group** - Use [react-transition-group/CSSTransitionGroup](https://github.com/reactjs/react-transition-group) instead. Version 1.1.1 provides a drop-in replacement.
|
||||
- **react-addons-linked-state-mixin** - Explicitly set the `value` and `onChange` handler instead.
|
||||
- **react-addons-pure-render-mixin** - Use [`React.PureComponent`](/react/docs/react-api.html#react.purecomponent) instead.
|
||||
- **react-addons-shallow-compare** - Use [`React.PureComponent`](/react/docs/react-api.html#react.purecomponent) instead.
|
||||
- **react-addons-transition-group** - Use [react-transition-group/TransitionGroup](https://github.com/reactjs/react-transition-group) instead. Version 1.1.1 provides a drop-in replacement.
|
||||
- **react-addons-update** - Use [immutability-helper](https://github.com/kolodny/immutability-helper) instead, a drop-in replacement.
|
||||
- **react-linked-input** - Explicitly set the `value` and `onChange` handler instead.
|
||||
|
||||
We're also discontinuing support for the `react-with-addons` UMD build. It will be removed in React 16.
|
||||
|
||||
### React Test Utils
|
||||
|
||||
Currently, the React Test Utils live inside `react-addons-test-utils`. As of 15.5, we're deprecating that package and moving them to `react-dom/test-utils` instead:
|
||||
|
||||
```js
|
||||
// Before (15.4 and below)
|
||||
import TestUtils from 'react-addons-test-utils';
|
||||
|
||||
// After (15.5)
|
||||
import TestUtils from 'react-dom/test-utils';
|
||||
```
|
||||
|
||||
This reflects the fact that what we call the Test Utils are really a set of APIs that wrap the DOM renderer.
|
||||
|
||||
The exception is shallow rendering, which is not DOM-specific. The shallow renderer has been moved to `react-test-renderer/shallow`.
|
||||
|
||||
```js{2,5}
|
||||
// Before (15.4 and below)
|
||||
import { createRenderer } from 'react-addons-test-utils';
|
||||
|
||||
// After (15.5)
|
||||
import { createRenderer } from 'react-test-renderer/shallow';
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Acknowledgements
|
||||
|
||||
A special thank you to these folks for transferring ownership of npm package names:
|
||||
|
||||
- [Jason Miller](https://github.com/developit)
|
||||
- [Aaron Ackerman](https://github.com/aackerman)
|
||||
- [Vinicius Marson](https://github.com/viniciusmarson)
|
||||
|
||||
---
|
||||
|
||||
## Installation
|
||||
|
||||
We recommend using [Yarn](https://yarnpkg.com/) or [npm](https://www.npmjs.com/) for managing front-end dependencies. If you're new to package managers, the [Yarn documentation](https://yarnpkg.com/en/docs/getting-started) is a good place to get started.
|
||||
|
||||
To install React with Yarn, run:
|
||||
|
||||
```bash
|
||||
yarn add react@^15.5.0 react-dom@^15.5.0
|
||||
```
|
||||
|
||||
To install React with npm, run:
|
||||
|
||||
```bash
|
||||
npm install --save react@^15.5.0 react-dom@^15.5.0
|
||||
```
|
||||
|
||||
We recommend using a bundler like [webpack](https://webpack.js.org/) or [Browserify](http://browserify.org/) so you can write modular code and bundle it together into small packages to optimize load time.
|
||||
|
||||
Remember that by default, React runs extra checks and provides helpful warnings in development mode. When deploying your app, make sure to [compile it in production mode](/react/docs/installation.html#development-and-production-versions).
|
||||
|
||||
In case you don't use a bundler, we also provide pre-built bundles in the npm packages which you can [include as script tags](/react/docs/installation.html#using-a-cdn) on your page:
|
||||
|
||||
* **React**
|
||||
Dev build with warnings: [react/dist/react.js](https://unpkg.com/react@15.5.0/dist/react.js)
|
||||
Minified build for production: [react/dist/react.min.js](https://unpkg.com/react@15.5.0/dist/react.min.js)
|
||||
* **React with Add-Ons**
|
||||
Dev build with warnings: [react/dist/react-with-addons.js](https://unpkg.com/react@15.5.0/dist/react-with-addons.js)
|
||||
Minified build for production: [react/dist/react-with-addons.min.js](https://unpkg.com/react@15.5.0/dist/react-with-addons.min.js)
|
||||
* **React DOM** (include React in the page before React DOM)
|
||||
Dev build with warnings: [react-dom/dist/react-dom.js](https://unpkg.com/react-dom@15.5.0/dist/react-dom.js)
|
||||
Minified build for production: [react-dom/dist/react-dom.min.js](https://unpkg.com/react-dom@15.5.0/dist/react-dom.min.js)
|
||||
* **React DOM Server** (include React in the page before React DOM Server)
|
||||
Dev build with warnings: [react-dom/dist/react-dom-server.js](https://unpkg.com/react-dom@15.5.0/dist/react-dom-server.js)
|
||||
Minified build for production: [react-dom/dist/react-dom-server.min.js](https://unpkg.com/react-dom@15.5.0/dist/react-dom-server.min.js)
|
||||
|
||||
We've also published version `15.5.0` of the `react`, `react-dom`, and addons packages on npm and the `react` package on bower.
|
||||
|
||||
---
|
||||
|
||||
## Changelog
|
||||
|
||||
## 15.5.0 (April 7, 2017)
|
||||
|
||||
### React
|
||||
|
||||
* Added a deprecation warning for `React.createClass`. Points users to create-react-class instead. ([@acdlite](https://github.com/acdlite) in [d9a4fa4](https://github.com/facebook/react/commit/d9a4fa4f51c6da895e1655f32255cf72c0fe620e))
|
||||
* Added a deprecation warning for `React.PropTypes`. Points users to prop-types instead. ([@acdlite](https://github.com/acdlite) in [043845c](https://github.com/facebook/react/commit/043845ce75ea0812286bbbd9d34994bb7e01eb28))
|
||||
* Fixed an issue when using `ReactDOM` together with `ReactDOMServer`. ([@wacii](https://github.com/wacii) in [#9005](https://github.com/facebook/react/pull/9005))
|
||||
* Fixed issue with Closure Compiler. ([@anmonteiro](https://github.com/anmonteiro) in [#8895](https://github.com/facebook/react/pull/8895))
|
||||
* Another fix for Closure Compiler. ([@Shastel](https://github.com/Shastel) in [#8882](https://github.com/facebook/react/pull/8882))
|
||||
* Added component stack info to invalid element type warning. ([@n3tr](https://github.com/n3tr) in [#8495](https://github.com/facebook/react/pull/8495))
|
||||
|
||||
### React DOM
|
||||
|
||||
* Fixed Chrome bug when backspacing in number inputs. ([@nhunzaker](https://github.com/nhunzaker) in [#7359](https://github.com/facebook/react/pull/7359))
|
||||
* Added `react-dom/test-utils`, which exports the React Test Utils. ([@bvaughn](https://github.com/bvaughn))
|
||||
|
||||
### React Test Renderer
|
||||
|
||||
* Fixed bug where `componentWillUnmount` was not called for children. ([@gre](https://github.com/gre) in [#8512](https://github.com/facebook/react/pull/8512))
|
||||
* Added `react-test-renderer/shallow`, which exports the shallow renderer. ([@bvaughn](https://github.com/bvaughn))
|
||||
|
||||
### React Addons
|
||||
|
||||
* Last release for addons; they will no longer be actively maintained.
|
||||
* Removed `peerDependencies` so that addons continue to work indefinitely. ([@acdlite](https://github.com/acdlite) and [@bvaughn](https://github.com/bvaughn) in [8a06cd7](https://github.com/facebook/react/commit/8a06cd7a786822fce229197cac8125a551e8abfa) and [67a8db3](https://github.com/facebook/react/commit/67a8db3650d724a51e70be130e9008806402678a))
|
||||
* Updated to remove references to `React.createClass` and `React.PropTypes` ([@acdlite](https://github.com/acdlite) in [12a96b9](https://github.com/facebook/react/commit/12a96b94823d6b6de6b1ac13bd576864abd50175))
|
||||
* `react-addons-test-utils` is deprecated. Use `react-dom/test-utils` and `react-test-renderer/shallow` instead. ([@bvaughn](https://github.com/bvaughn))
|
||||
@@ -1,107 +0,0 @@
|
||||
---
|
||||
title: "What's New in Create React App"
|
||||
author: gaearon
|
||||
---
|
||||
|
||||
Less than a year ago, we introduced [Create React App](/react/blog/2016/07/22/create-apps-with-no-configuration.html) as an officially supported way to create apps with zero configuration. The project has since enjoyed tremendous growth, with over 950 commits by more than 250 contributors.
|
||||
|
||||
Today, we are excited to announce that many features that have been in the pipeline for the last few months are finally released.
|
||||
|
||||
As usual with Create React App, **you can enjoy these improvements in your existing non-ejected apps by updating a single dependency** and following our [migration instructions](https://github.com/facebookincubator/create-react-app/releases/tag/v1.0.0).
|
||||
|
||||
Newly created apps will get these improvements automatically.
|
||||
|
||||
### webpack 2
|
||||
|
||||
>*This change was contributed by [@Timer](https://github.com/Timer) in [#1291](https://github.com/facebookincubator/create-react-app/pull/1291).*
|
||||
|
||||
We have upgraded to webpack 2 which has been [officially released](https://medium.com/webpack/webpack-2-and-beyond-40520af9067f) a few months ago. It is a big upgrade with many bugfixes and general improvements. We have been testing it for a while, and now consider it stable enough to recommend it to everyone.
|
||||
|
||||
While the Webpack configuration format has changed, Create React App users who didn't eject don't need to worry about it as we have updated the configuration on our side.
|
||||
|
||||
If you had to eject your app for one reason or another, Webpack provides a [configuration migration guide](https://webpack.js.org/guides/migrating/) that you can follow to update your apps. Note that with each release of Create React App, we are working to support more use cases out of the box so that you don't have to eject in the future.
|
||||
|
||||
The biggest notable webpack 2 feature is the ability to write and import [ES6 modules](http://2ality.com/2014/09/es6-modules-final.html) directly without compiling them to CommonJS. This shouldn’t affect how you write code since you likely already use `import` and `export` statements, but it will help catch more mistakes like missing named exports at compile time:
|
||||
|
||||
<img src='/react/img/blog/cra-update-exports.gif' alt='Export validation' style="max-width:100%">
|
||||
|
||||
In the future, as the ecosystem around ES6 modules matures, you can expect more improvements to your app's bundle size thanks to [tree shaking](https://webpack.js.org/guides/tree-shaking/).
|
||||
|
||||
### Runtime Error Overlay
|
||||
|
||||
>*This change was contributed by [@Timer](https://github.com/Timer) and [@nicinabox](https://github.com/nicinabox) in [#1101](https://github.com/facebookincubator/create-react-app/pull/1101), [@bvaughn](https://github.com/bvaughn) in [#2201](https://github.com/facebookincubator/create-react-app/pull/2201).*
|
||||
|
||||
Have you ever made a mistake in code and only realized it after the console is flooded with cryptic errors? Or worse, have you ever shipped an app with crashes in production because you accidentally missed an error in development?
|
||||
|
||||
To address these issues, we are introducing an overlay that pops up whenever there is an uncaught error in your application. It only appears in development, and you can dismiss it by pressing Escape.
|
||||
|
||||
A GIF is worth a thousand words:
|
||||
|
||||
<img src='/react/img/blog/cra-runtime-error.gif' alt='Runtime error overlay' style="max-width:100%">
|
||||
|
||||
(Yes, it integrates with your editor!)
|
||||
|
||||
In the future, we plan to teach the runtime error overlay to understand more about your React app. For example, after React 16 we plan to show React component stacks in addition to the JavaScript stacks when an error is thrown.
|
||||
|
||||
|
||||
### Progressive Web Apps by Default
|
||||
|
||||
>*This change was contributed by [@jeffposnick](https://github.com/jeffposnick) in [#1728](https://github.com/facebookincubator/create-react-app/pull/1728).*
|
||||
|
||||
Newly created projects are built as [Progressive Web Apps](https://developers.google.com/web/progressive-web-apps/) by default. This means that they employ [service workers](https://developers.google.com/web/fundamentals/getting-started/primers/service-workers) with an [offline-first caching strategy](https://developers.google.com/web/fundamentals/instant-and-offline/offline-cookbook/#cache-falling-back-to-network) to minimize the time it takes to serve the app to the users who visit it again. You can opt out of this behavior, but we recommend it both for new and existing apps, especially if you target mobile devices.
|
||||
|
||||
<img src='/react/img/blog/cra-pwa.png' alt='Loading assets from service worker' style="max-width:100%">
|
||||
|
||||
New apps automatically have these features, but you can easily convert an existing project to a Progressive Web App by following [our migration guide](https://github.com/facebookincubator/create-react-app/releases/tag/v1.0.0).
|
||||
|
||||
We will be adding [more documentation](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#making-a-progressive-web-app) on this topic in the coming weeks. Please feel free to [ask any questions](https://github.com/facebookincubator/create-react-app/issues/new) on the issue tracker!
|
||||
|
||||
|
||||
### Jest 20
|
||||
|
||||
>*This change was contributed by [@rogeliog](https://github.com/rogeliog) in [#1614](https://github.com/facebookincubator/create-react-app/pull/1614) and [@gaearon](https://github.com/gaearon) in [#2171](https://github.com/facebookincubator/create-react-app/pull/2171).*
|
||||
|
||||
We are now using the latest version of Jest that includes numerous bugfixes and improvements. You can read more about the changes in [Jest 19](https://facebook.github.io/jest/blog/2017/02/21/jest-19-immersive-watch-mode-test-platform-improvements.html) and [Jest 20](http://facebook.github.io/jest/blog/2017/05/06/jest-20-delightful-testing-multi-project-runner.html) blog posts.
|
||||
|
||||
Highlights include a new [immersive watch mode](https://facebook.github.io/jest/blog/2017/02/21/jest-19-immersive-watch-mode-test-platform-improvements.html#immersive-watch-mode), [a better snapshot format](https://facebook.github.io/jest/blog/2017/02/21/jest-19-immersive-watch-mode-test-platform-improvements.html#snapshot-updates), [improvements to printing skipped tests](https://facebook.github.io/jest/blog/2017/02/21/jest-19-immersive-watch-mode-test-platform-improvements.html#improved-printing-of-skipped-tests), and [new testing APIs](https://facebook.github.io/jest/blog/2017/05/06/jest-20-delightful-testing-multi-project-runner.html#new-improved-testing-apis).
|
||||
|
||||
<img src='/react/img/blog/cra-jest-search.gif' alt='Immersive test watcher' style="max-width:100%">
|
||||
|
||||
Additionally, Create React App now support configuring a few Jest options related to coverage reporting.
|
||||
|
||||
### Code Splitting with Dynamic import()
|
||||
|
||||
>*This change was contributed by [@Timer](https://github.com/Timer) in [#1538](https://github.com/facebookincubator/create-react-app/pull/1538) and [@tharakawj](https://github.com/tharakawj) in [#1801](https://github.com/facebookincubator/create-react-app/pull/1801).*
|
||||
|
||||
It is important to keep the initial JavaScript payload of web apps down to the minimum, and [load the rest of the code on demand](https://medium.com/@addyosmani/progressive-web-apps-with-react-js-part-2-page-load-performance-33b932d97cf2). Although Create React App supported [code splitting](https://webpack.js.org/guides/code-splitting-async/) using `require.ensure()` since the first release, it used a webpack-specific syntax that did not work in Jest or other environments.
|
||||
|
||||
In this release, we are adding support for the [dynamic `import()` proposal](http://2ality.com/2017/01/import-operator.html#loading-code-on-demand) which aligns with the future web standards. Unlike `require.ensure()`, it doesn't break Jest tests, and should eventually become a part of JavaScript. We encourage you to use `import()` to delay loading the code for non-critical component subtrees until you need to render them.
|
||||
|
||||
<img src='/react/img/blog/cra-dynamic-import.gif' alt='Creating chunks with dynamic import' style="max-width:100%">
|
||||
|
||||
### Better Console Output
|
||||
|
||||
>*This change was contributed by [@gaearon](https://github.com/gaearon) in [#2120](https://github.com/facebookincubator/create-react-app/pull/2120), [#2125](https://github.com/facebookincubator/create-react-app/pull/2125), and [#2161](https://github.com/facebookincubator/create-react-app/pull/2161).*
|
||||
|
||||
We have improved the console output across the board.
|
||||
|
||||
For example, when you start the development server, we now display the LAN address in additional to the localhost address so that you can quickly access the app from a mobile device on the same network:
|
||||
|
||||
<img src='/react/img/blog/cra-better-output.png' alt='Better console output' style="max-width:100%">
|
||||
|
||||
When lint errors are reported, we no longer show the warnings so that you can concentrate on more critical issues. Errors and warnings in the production build output are better formatted, and the build error overlay font size now matches the browser font size more closely.
|
||||
|
||||
### But Wait... There's More!
|
||||
|
||||
You can only fit so much in a blog post, but there are other long-requested features in this release, such as [environment-specific and local `.env` files](https://github.com/facebookincubator/create-react-app/pull/1344), [a lint rule against confusingly named globals](https://github.com/facebookincubator/create-react-app/pull/2130), [support for multiple proxies in development](https://github.com/facebookincubator/create-react-app/pull/1790), [a customizable browser launch script](https://github.com/facebookincubator/create-react-app/pull/1590), and many bugfixes.
|
||||
|
||||
You can read the full changelog and the migration guide in the [v1.0.0 release notes](https://github.com/facebookincubator/create-react-app/releases/tag/v1.0.0).
|
||||
|
||||
### Acknowledgements
|
||||
|
||||
This release is a result of months of work from many people in the React community. It is focused on improving both developer and end user experience, as we believe they are complementary and go hand in hand.
|
||||
|
||||
We are grateful to [everyone who has offered their contributions](https://github.com/facebookincubator/create-react-app/graphs/contributors), whether in code, documentation, or by helping other people. We would like to specifically thank [Joe Haddad](https://github.com/timer) for his invaluable help maintaining the project.
|
||||
|
||||
We are excited to bring these improvements to everybody using Create React App, and we are looking forward to more of your feedback and contributions.
|
||||
|
||||
@@ -1,95 +0,0 @@
|
||||
---
|
||||
title: "React v15.6.0"
|
||||
author: flarnie
|
||||
---
|
||||
|
||||
Today we are releasing React 15.6.0. As we prepare for React 16.0, we have been fixing and cleaning up many things. This release continues to pave the way.
|
||||
|
||||
## Improving Inputs
|
||||
|
||||
In React 15.6.0 the `onChange` event for inputs is a little bit more reliable and handles more edge cases, including the following:
|
||||
|
||||
* not firing when radio button is clicked but not changed ([issue 1471](https://github.com/facebook/react/issues/1471))
|
||||
* changing an input of type `range` with the arrow keys ([issue 554](https://github.com/facebook/react/issues/554))
|
||||
* pasting text into a text area in IE11 ([issue 7211](https://github.com/facebook/react/issues/7211))
|
||||
* auto-fill in IE11 ([issue 6614](https://github.com/facebook/react/issues/6614))
|
||||
* clearing input with 'x' button or right-click 'delete' in IE11 ([issue 6822](https://github.com/facebook/react/issues/6822))
|
||||
* not firing when characters are present in the input on render in IE11 ([issue 2185](https://github.com/facebook/react/issues/2185))
|
||||
|
||||
Thanks to [Jason Quense](https://github.com/jquense) and everyone who helped out on those issues and PRs.
|
||||
|
||||
## Less Noisy Deprecation Warnings
|
||||
|
||||
We are also including a couple of new warnings for upcoming deprecations. These should not affect most users, and for more details see the changelog below.
|
||||
|
||||
After the last release, we got valuable community feedback that deprecation warnings were causing noise and failing tests. **In React 15.6, we have downgraded deprecation warnings to use `console.warn` instead of `console.error`.** Our other warnings will still use `console.error` because they surface urgent issues which could lead to bugs. Unlike our other warnings, deprecation warnings can be fixed over time and won't cause problems in your app if shipped. We believe that downgrading the urgency of deprecation warnings will make your next update easier. Thanks to everyone who was involved in the discussion of this change.
|
||||
|
||||
---
|
||||
|
||||
## Installation
|
||||
|
||||
We recommend using [Yarn](https://yarnpkg.com/) or [npm](https://www.npmjs.com/) for managing front-end dependencies. If you're new to package managers, the [Yarn documentation](https://yarnpkg.com/en/docs/getting-started) is a good place to get started.
|
||||
|
||||
To install React with Yarn, run:
|
||||
|
||||
```bash
|
||||
yarn add react@^15.6.0 react-dom@^15.6.0
|
||||
```
|
||||
|
||||
To install React with npm, run:
|
||||
|
||||
```bash
|
||||
npm install --save react@^15.6.0 react-dom@^15.6.0
|
||||
```
|
||||
|
||||
We recommend using a bundler like [webpack](https://webpack.js.org/) or [Browserify](http://browserify.org/) so you can write modular code and bundle it together into small packages to optimize load time.
|
||||
|
||||
Remember that by default, React runs extra checks and provides helpful warnings in development mode. When deploying your app, make sure to [use the production build](/react/docs/optimizing-performance.html#use-the-production-build).
|
||||
|
||||
In case you don't use a bundler, we also provide pre-built bundles in the npm packages which you can [include as script tags](/react/docs/installation.html#using-a-cdn) on your page:
|
||||
|
||||
* **React**<br/>
|
||||
Dev build with warnings: [react/dist/react.js](https://unpkg.com/react@15.6.0/dist/react.js)<br/>
|
||||
Minified build for production: [react/dist/react.min.js](https://unpkg.com/react@15.6.0/dist/react.min.js)<br/>
|
||||
* **React with Add-Ons**<br/>
|
||||
Dev build with warnings: [react/dist/react-with-addons.js](https://unpkg.com/react@15.6.0/dist/react-with-addons.js)<br/>
|
||||
Minified build for production: [react/dist/react-with-addons.min.js](https://unpkg.com/react@15.5.0/dist/react-with-addons.min.js)<br/>
|
||||
* **React DOM** (include React in the page before React DOM)<br/>
|
||||
Dev build with warnings: [react-dom/dist/react-dom.js](https://unpkg.com/react-dom@15.6.0/dist/react-dom.js)<br/>
|
||||
Minified build for production: [react-dom/dist/react-dom.min.js](https://unpkg.com/react-dom@15.6.0/dist/react-dom.min.js)<br/>
|
||||
* **React DOM Server** (include React in the page before React DOM Server)<br/>
|
||||
Dev build with warnings: [react-dom/dist/react-dom-server.js](https://unpkg.com/react-dom@15.6.0/dist/react-dom-server.js)<br/>
|
||||
Minified build for production: [react-dom/dist/react-dom-server.min.js](https://unpkg.com/react-dom@15.6.0/dist/react-dom-server.min.js)<br/>
|
||||
|
||||
We've also published version `15.6.0` of `react` and `react-dom` on npm, and the `react` package on bower.
|
||||
|
||||
---
|
||||
|
||||
## Changelog
|
||||
|
||||
## 15.6.0 (June 13, 2017)
|
||||
|
||||
### React
|
||||
|
||||
* Downgrade deprecation warnings to use `console.warn` instead of `console.error`. ([@flarnie](https://github.com/flarnie) in [#9753](https://github.com/facebook/react/pull/9753))
|
||||
* Add a deprecation warning for `React.createClass`. Points users to `create-react-class` instead. ([@flarnie](https://github.com/flarnie) in [#9771](https://github.com/facebook/react/pull/9771))
|
||||
* Add deprecation warnings and separate module for `React.DOM` factory helpers. ([@nhunzaker](https://github.com/nhunzaker) in [#8356](https://github.com/facebook/react/pull/8356))
|
||||
* Warn for deprecation of `React.createMixin` helper, which was never used. ([@aweary](https://github.com/aweary) in [#8853](https://github.com/facebook/react/pull/8853))
|
||||
|
||||
### React DOM
|
||||
|
||||
* Add support for CSS variables in `style` attribute. ([@aweary](https://github.com/aweary) in [#9302](https://github.com/facebook/react/pull/9302))
|
||||
* Add support for CSS Grid style properties. ([@ericsakmar](https://github.com/ericsakmar) in [#9185](https://github.com/facebook/react/pull/9185))
|
||||
* Fix bug where inputs mutated value on type conversion. ([@nhunzaker](https://github.com/mhunzaker) in [#9806](https://github.com/facebook/react/pull/9806))
|
||||
* Fix issues with `onChange` not firing properly for some inputs. ([@jquense](https://github.com/jquense) in [#8575](https://github.com/facebook/react/pull/8575))
|
||||
* Fix bug where controlled number input mistakenly allowed period. ([@nhunzaker](https://github.com/nhunzaker) in [#9584](https://github.com/facebook/react/pull/9584))
|
||||
* Fix bug where performance entries were being cleared. ([@chrisui](https://github.com/chrisui) in [#9451](https://github.com/facebook/react/pull/9451))
|
||||
|
||||
### React Addons
|
||||
|
||||
* Fix AMD support for addons depending on `react`. ([@flarnie](https://github.com/flarnie) in [#9919](https://github.com/facebook/react/issues/9919))
|
||||
* Fix `isMounted()` to return `true` in `componentWillUnmount`. ([@mridgway](https://github.com/mridgway) in [#9638](https://github.com/facebook/react/issues/9638))
|
||||
* Fix `react-addons-update` to not depend on native `Object.assign`. ([@gaearon](https://github.com/gaearon) in [#9937](https://github.com/facebook/react/pull/9937))
|
||||
* Remove broken Google Closure Compiler annotation from `create-react-class`. ([@gaearon](https://github.com/gaearon) in [#9933](https://github.com/facebook/react/pull/9933))
|
||||
* Remove unnecessary dependency from `react-linked-input`. ([@gaearon](https://github.com/gaearon) in [#9766](https://github.com/facebook/react/pull/9766))
|
||||
* Point `react-addons-(css-)transition-group` to the new package. ([@gaearon](https://github.com/gaearon) in [#9937](https://github.com/facebook/react/pull/9937))
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
general:
|
||||
branches:
|
||||
ignore:
|
||||
- gh-pages
|
||||
@@ -1,146 +0,0 @@
|
||||
---
|
||||
id: conferences
|
||||
title: Conferences
|
||||
layout: community
|
||||
sectionid: community
|
||||
permalink: community/conferences.html
|
||||
redirect_from: "docs/conferences.html"
|
||||
---
|
||||
|
||||
## Upcoming Conferences
|
||||
|
||||
### React Rally
|
||||
August 24-25 in Salt Lake City, Utah USA
|
||||
|
||||
[Website](http://www.reactrally.com) - [Twitter](https://twitter.com/reactrally)
|
||||
|
||||
### React Native EU 2017
|
||||
September 6-7 in Wroclaw, Poland
|
||||
|
||||
[Website](http://react-native.eu/)
|
||||
|
||||
### ReactNext 2017
|
||||
September 8-10 in Tel Aviv, Israel
|
||||
|
||||
[Website](http://react-next.com/) - [Twitter](https://twitter.com/ReactNext)
|
||||
|
||||
### React Boston 2017
|
||||
September 23-24 in Boston, Massachusetts USA
|
||||
|
||||
[Website](http://www.reactboston.com/) - [Twitter](https://twitter.com/ReactBoston)
|
||||
|
||||
### React Alicante 2017
|
||||
September 28-30 in Alicante, Spain
|
||||
|
||||
[Website](http://reactalicante.es) - [Twitter](https://twitter.com/ReactAlicante)
|
||||
|
||||
### ReactJS Day 2017
|
||||
October 6 in Verona, Italy
|
||||
|
||||
[Website](http://2017.reactjsday.it) - [Twitter](https://twitter.com/reactjsday)
|
||||
|
||||
### React Conf Brasil 2017
|
||||
October 7 in Sao Paulo, Brazil
|
||||
|
||||
[Website](http://reactconfbr.com.br) - [Twitter](https://twitter.com/reactconfbr) - [Facebook](https://www.facebook.com/reactconf/)
|
||||
|
||||
### State.js Conference 2017
|
||||
October 13 in Stockholm, Sweden
|
||||
|
||||
[Website](https://statejs.com/)
|
||||
|
||||
### ReactiveConf 2017
|
||||
October 25–27, Bratislava, Slovakia
|
||||
|
||||
[Website](https://reactiveconf.com)
|
||||
|
||||
|
||||
|
||||
## 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)
|
||||
|
||||
### Agent Conference 2017
|
||||
January 20-21 in Dornbirn, Austria
|
||||
|
||||
[Website](http://agent.sh/)
|
||||
|
||||
### React Conf 2017
|
||||
March 13-14 in Santa Clara, CA
|
||||
|
||||
[Website](http://conf.reactjs.org/)
|
||||
|
||||
### React London 2017
|
||||
March 28th at the [QEII Centre, London](http://qeiicentre.london/)
|
||||
|
||||
[Website](http://react.london/)
|
||||
|
||||
### React Amsterdam 2017
|
||||
April 21st in Amsterdam, The Netherlands
|
||||
|
||||
[Website](https://react.amsterdam) - [Twitter](https://twitter.com/reactamsterdam)
|
||||
|
||||
### ReactEurope 2017
|
||||
May 18th & 19th 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)
|
||||
|
||||
### Chain React 2017
|
||||
July 10-11 in Portland, Oregon USA
|
||||
|
||||
[Website](https://infinite.red/ChainReactConf) - [Twitter](https://twitter.com/chainreactconf)
|
||||
@@ -1,174 +0,0 @@
|
||||
---
|
||||
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>
|
||||
|
||||
> [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,404 +0,0 @@
|
||||
---
|
||||
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 Facebook's 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's 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.
|
||||
* [`fixtures`](https://github.com/facebook/react/tree/master/fixtures) contains a few small React test applications for contributors.
|
||||
* [`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/stack/client`](https://github.com/facebook/react/blob/f53854424b33692907234fe7a1f80b888fd80751/src/renderers/dom/stack/client) may import other files in the same folder or any folder below.
|
||||
|
||||
However they can't import modules from [`src/renderers/dom/stack/server`](https://github.com/facebook/react/blob/f53854424b33692907234fe7a1f80b888fd80751/src/renderers/dom/stack/server) because it is not a child directory of [`src/renderers/dom/stack/client`](https://github.com/facebook/react/blob/f53854424b33692907234fe7a1f80b888fd80751/src/renderers/dom/stack/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/stack/client`](https://github.com/facebook/react/blob/f53854424b33692907234fe7a1f80b888fd80751/src/renderers/dom/stack/client) and [`src/renderers/dom/stack/server`](https://github.com/facebook/react/blob/f53854424b33692907234fe7a1f80b888fd80751/src/renderers/dom/stack/server) lives in [`src/renderers/dom/shared`](https://github.com/facebook/react/blob/f53854424b33692907234fe7a1f80b888fd80751/src/renderers/dom/shared).
|
||||
|
||||
By the same logic, if [`src/renderers/dom/stack/client`](https://github.com/facebook/react/blob/f53854424b33692907234fe7a1f80b888fd80751/src/renderers/dom/stack/client) needs to share a utility with something in [`src/renderers/native`](https://github.com/facebook/react/blob/f53854424b33692907234fe7a1f80b888fd80751/src/renderers/native), this utility would be in [`src/renderers/shared`](https://github.com/facebook/react/blob/f53854424b33692907234fe7a1f80b888fd80751/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.
|
||||
|
||||
The equivalent code in ES6 would look 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.Component`
|
||||
* `React.Children`
|
||||
|
||||
**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 renderers, 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 the 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).
|
||||
|
||||
### What Next?
|
||||
|
||||
Read the [next section](/react/contributing/implementation-notes.html) to learn about the current implementation of reconciler in more detail.
|
||||
@@ -3,9 +3,10 @@ id: design-principles
|
||||
title: Design Principles
|
||||
layout: contributing
|
||||
permalink: contributing/design-principles.html
|
||||
prev: implementation-notes.html
|
||||
---
|
||||
|
||||
After using React in a couple of applications, you might be interested in contributing to React. Before [diving into specifics](https://github.com/facebook/react/blob/master/CONTRIBUTING.md), we think it's important to establish a few design principles guiding our decisions about changes in React.
|
||||
|
||||
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:**
|
||||
@@ -20,7 +21,7 @@ The key feature of React is composition of components. Components written by dif
|
||||
|
||||
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 feature, 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.
|
||||
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.
|
||||
|
||||
@@ -124,7 +125,7 @@ We do, however, provide some global configuration on the build level. For exampl
|
||||
|
||||
### 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.
|
||||
We see the value of React in the way it allows us to write components that have less 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.
|
||||
|
||||
@@ -146,7 +147,7 @@ Optimizing for search is also important because of our reliance on [codemods](ht
|
||||
|
||||
[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 unambiguous 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.
|
||||
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
|
||||
|
||||
|
||||
@@ -1,163 +0,0 @@
|
||||
---
|
||||
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/84v837e9/) 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 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 **[beginner friendly issues](https://github.com/facebook/react/issues?q=is%3Aopen+is%3Aissue+label%3A%22Difficulty%3A+beginner%22)** 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. Format your code with [prettier](https://github.com/prettier/prettier) (`npm run prettier`).
|
||||
6. Make sure your code lints (`npm run lint`).
|
||||
7. Run the [Flow](https://flowtype.org/) typechecks (`npm run flow`).
|
||||
8. 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 run `npm run build` and then open `fixtures/packaging/babel-standalone/dev.html`. This file already uses `react.js` from the `build` folder so it will pick up your changes.
|
||||
|
||||
If you want to try your changes in your existing React project, you may copy `build/dist/react.development.js`, `build/dist/react-dom.development.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';`
|
||||
* 120 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.
|
||||
@@ -1,896 +0,0 @@
|
||||
---
|
||||
id: implementation-notes
|
||||
title: Implementation Notes
|
||||
layout: contributing
|
||||
permalink: contributing/implementation-notes.html
|
||||
prev: codebase-overview.html
|
||||
next: design-principles.html
|
||||
---
|
||||
|
||||
This section is a collection of implementation notes for the [stack reconciler](/react/contributing/codebase-overview.html#stack-reconciler).
|
||||
|
||||
It is very technical and assumes a strong understanding of React public API as well as how it's divided into core, renderers, and the reconciler. If you're not very familiar with the React codebase, read [the codebase overview](/react/contributing/codebase-overview.html) first.
|
||||
|
||||
It also assumes an understanding of the [differences between React components, their instances, and elements](/react/blog/2015/12/18/react-components-elements-and-instances.html).
|
||||
|
||||
The stack reconciler is powering all the 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.
|
||||
|
||||
### Video: Building React from Scratch
|
||||
|
||||
[Paul O'Shannessy](https://twitter.com/zpao) gave a talk about [building React from scratch](https://www.youtube.com/watch?v=_MAD4Oly9yg) that largely inspired this document.
|
||||
|
||||
Both this document and his talk are simplifications of the real codebase so you might get a better understanding by getting familiar with both of them.
|
||||
|
||||
### Overview
|
||||
|
||||
The reconciler itself doesn't have a public API. [Renderers](/react/contributing/codebase-overview.html#stack-renderers) like React DOM and React Native use it to efficiently update the user interface according to the React components written by the user.
|
||||
|
||||
### Mounting as a Recursive Process
|
||||
|
||||
Let's consider the first time you mount a component:
|
||||
|
||||
```js
|
||||
ReactDOM.render(<App />, rootEl);
|
||||
```
|
||||
|
||||
React DOM will pass `<App />` along to the reconciler. Remember that `<App />` is a React element, that is, a description of *what* to render. You can think about it as a plain object:
|
||||
|
||||
```js
|
||||
console.log(<App />);
|
||||
// { type: App, props: {} }
|
||||
```
|
||||
|
||||
The reconciler will check if `App` is a class or a function.
|
||||
|
||||
If `App` is a function, the reconciler will call `App(props)` to get the rendered element.
|
||||
|
||||
If `App` is a class, the reconciler will instantiate an `App` with `new App(props)`, call the `componentWillMount()` lifecycle method, and then will call the `render()` method to get the rendered element.
|
||||
|
||||
Either way, the reconciler will learn the element `App` "rendered to".
|
||||
|
||||
This process is recursive. `App` may render to a `<Greeting />`, `Greeting` may render to a `<Button />`, and so on. The reconciler will "drill down" through user-defined components recursively as it learns what each component renders to.
|
||||
|
||||
You can imagine this process as a pseudocode:
|
||||
|
||||
```js
|
||||
function isClass(type) {
|
||||
// React.Component subclasses have this flag
|
||||
return (
|
||||
Boolean(type.prototype) &&
|
||||
Boolean(type.prototype.isReactComponent)
|
||||
);
|
||||
}
|
||||
|
||||
// This function takes a React element (e.g. <App />)
|
||||
// and returns a DOM or Native node representing the mounted tree.
|
||||
function mount(element) {
|
||||
var type = element.type;
|
||||
var props = element.props;
|
||||
|
||||
// We will determine the rendered element
|
||||
// by either running the type as function
|
||||
// or creating an instance and calling render().
|
||||
var renderedElement;
|
||||
if (isClass(type)) {
|
||||
// Component class
|
||||
var publicInstance = new type(props);
|
||||
// Set the props
|
||||
publicInstance.props = props;
|
||||
// Call the lifecycle if necessary
|
||||
if (publicInstance.componentWillMount) {
|
||||
publicInstance.componentWillMount();
|
||||
}
|
||||
// Get the rendered element by calling render()
|
||||
renderedElement = publicInstance.render();
|
||||
} else {
|
||||
// Component function
|
||||
renderedElement = type(props);
|
||||
}
|
||||
|
||||
// This process is recursive because a component may
|
||||
// return an element with a type of another component.
|
||||
return mount(renderedElement);
|
||||
|
||||
// Note: this implementation is incomplete and recurses infinitely!
|
||||
// It only handles elements like <App /> or <Button />.
|
||||
// It doesn't handle elements like <div /> or <p /> yet.
|
||||
}
|
||||
|
||||
var rootEl = document.getElementById('root');
|
||||
var node = mount(<App />);
|
||||
rootEl.appendChild(node);
|
||||
```
|
||||
|
||||
>**Note:**
|
||||
>
|
||||
>This really *is* a pseudo-code. It isn't similar to the real implementation. It will also cause a stack overflow because we haven't discussed when to stop the recursion.
|
||||
|
||||
Let's recap a few key ideas in the example above:
|
||||
|
||||
* React elements are plain objects representing the component type (e.g. `App`) and the props.
|
||||
* User-defined components (e.g. `App`) can be classes or functions but they all "render to" elements.
|
||||
* "Mounting" is a recursive process that creates a DOM or Native tree given the top-level React element (e.g. `<App />`).
|
||||
|
||||
### Mounting Host Elements
|
||||
|
||||
This process would be useless if we didn't render something to the screen as a result.
|
||||
|
||||
In addition to user-defined ("composite") components, React elements may also represent platform-specific ("host") components. For example, `Button` might return a `<div />` from its render method.
|
||||
|
||||
If element's `type` property is a string, we are dealing with a host element:
|
||||
|
||||
```js
|
||||
console.log(<div />);
|
||||
// { type: 'div', props: {} }
|
||||
```
|
||||
|
||||
There is no user-defined code associated with host elements.
|
||||
|
||||
When the reconciler encounters a host element, it lets the renderer take care of mounting it. For example, React DOM would create a DOM node.
|
||||
|
||||
If the host element has children, the reconciler recursively mounts them following the same algorithm as above. It doesn't matter whether children are host (like `<div><hr /></div>`), composite (like `<div><Button /></div>`), or both.
|
||||
|
||||
The DOM nodes produced by the child components will be appended to the parent DOM node, and recursively, the complete DOM structure will be assembled.
|
||||
|
||||
>**Note:**
|
||||
>
|
||||
>The reconciler itself is not tied to the DOM. The exact result of mounting (sometimes called "mount image" in the source code) depends on the renderer, and can be a DOM node (React DOM), a string (React DOM Server), or a number representing a native view (React Native).
|
||||
|
||||
If we were to extend the code to handle host elements, it would look like this:
|
||||
|
||||
```js
|
||||
function isClass(type) {
|
||||
// React.Component subclasses have this flag
|
||||
return (
|
||||
Boolean(type.prototype) &&
|
||||
Boolean(type.prototype.isReactComponent)
|
||||
);
|
||||
}
|
||||
|
||||
// This function only handles elements with a composite type.
|
||||
// For example, it handles <App /> and <Button />, but not a <div />.
|
||||
function mountComposite(element) {
|
||||
var type = element.type;
|
||||
var props = element.props;
|
||||
|
||||
var renderedElement;
|
||||
if (isClass(type)) {
|
||||
// Component class
|
||||
var publicInstance = new type(props);
|
||||
// Set the props
|
||||
publicInstance.props = props;
|
||||
// Call the lifecycle if necessary
|
||||
if (publicInstance.componentWillMount) {
|
||||
publicInstance.componentWillMount();
|
||||
}
|
||||
renderedElement = publicInstance.render();
|
||||
} else if (typeof type === 'function') {
|
||||
// Component function
|
||||
renderedElement = type(props);
|
||||
}
|
||||
|
||||
// This is recursive but we'll eventually reach the bottom of recursion when
|
||||
// the element is host (e.g. <div />) rather than composite (e.g. <App />):
|
||||
return mount(renderedElement);
|
||||
}
|
||||
|
||||
// This function only handles elements with a host type.
|
||||
// For example, it handles <div /> and <p /> but not an <App />.
|
||||
function mountHost(element) {
|
||||
var type = element.type;
|
||||
var props = element.props;
|
||||
var children = props.children || [];
|
||||
if (!Array.isArray(children)) {
|
||||
children = [children];
|
||||
}
|
||||
children = children.filter(Boolean);
|
||||
|
||||
// This block of code shouldn't be in the reconciler.
|
||||
// Different renderers might initialize nodes differently.
|
||||
// For example, React Native would create iOS or Android views.
|
||||
var node = document.createElement(type);
|
||||
Object.keys(props).forEach(propName => {
|
||||
if (propName !== 'children') {
|
||||
node.setAttribute(propName, props[propName]);
|
||||
}
|
||||
});
|
||||
|
||||
// Mount the children
|
||||
children.forEach(childElement => {
|
||||
// Children may be host (e.g. <div />) or composite (e.g. <Button />).
|
||||
// We will also mount them recursively:
|
||||
var childNode = mount(childElement);
|
||||
|
||||
// This line of code is also renderer-specific.
|
||||
// It would be different depending on the renderer:
|
||||
node.appendChild(childNode);
|
||||
});
|
||||
|
||||
// Return the DOM node as mount result.
|
||||
// This is where the recursion ends.
|
||||
return node;
|
||||
}
|
||||
|
||||
function mount(element) {
|
||||
var type = element.type;
|
||||
if (typeof type === 'function') {
|
||||
// User-defined components
|
||||
return mountComposite(element);
|
||||
} else if (typeof type === 'string') {
|
||||
// Platform-specific components
|
||||
return mountHost(element);
|
||||
}
|
||||
}
|
||||
|
||||
var rootEl = document.getElementById('root');
|
||||
var node = mount(<App />);
|
||||
rootEl.appendChild(node);
|
||||
```
|
||||
|
||||
This is working but still far from how the reconciler is really implemented. The key missing ingredient is support for updates.
|
||||
|
||||
### Introducing Internal Instances
|
||||
|
||||
The key feature of React is that you can re-render everything, and it won't recreate the DOM or reset the state:
|
||||
|
||||
```js
|
||||
ReactDOM.render(<App />, rootEl);
|
||||
// Should reuse the existing DOM:
|
||||
ReactDOM.render(<App />, rootEl);
|
||||
```
|
||||
|
||||
However, our implementation above only knows how to mount the initial tree. It can't perform updates on it because it doesn't store all the necessary information, such as all the `publicInstance`s, or which DOM `node`s correspond to which components.
|
||||
|
||||
The stack reconciler codebase solves this by making the `mount()` function a method and putting it on a class. There are drawbacks to this approach, and we are going in the opposite direction in the [ongoing rewrite of the reconciler](/react/contributing/codebase-overview.html#fiber-reconciler). Nevertheless this is how it works now.
|
||||
|
||||
Instead of separate `mountHost` and `mountComposite` functions, we will create two classes: `DOMComponent` and `CompositeComponent`.
|
||||
|
||||
Both classes have a constructor accepting the `element`, as well as a `mount()` method returning the mounted node. We will replace a top-level `mount()` function with a factory that instantiates the correct class:
|
||||
|
||||
```js
|
||||
function instantiateComponent(element) {
|
||||
var type = element.type;
|
||||
if (typeof type === 'function') {
|
||||
// User-defined components
|
||||
return new CompositeComponent(element);
|
||||
} else if (typeof type === 'string') {
|
||||
// Platform-specific components
|
||||
return new DOMComponent(element);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
First, let's consider the implementation of `CompositeComponent`:
|
||||
|
||||
```js
|
||||
class CompositeComponent {
|
||||
constructor(element) {
|
||||
this.currentElement = element;
|
||||
this.renderedComponent = null;
|
||||
this.publicInstance = null;
|
||||
}
|
||||
|
||||
getPublicInstance() {
|
||||
// For composite components, expose the class instance.
|
||||
return this.publicInstance;
|
||||
}
|
||||
|
||||
mount() {
|
||||
var element = this.currentElement;
|
||||
var type = element.type;
|
||||
var props = element.props;
|
||||
|
||||
var publicInstance;
|
||||
var renderedElement;
|
||||
if (isClass(type)) {
|
||||
// Component class
|
||||
publicInstance = new type(props);
|
||||
// Set the props
|
||||
publicInstance.props = props;
|
||||
// Call the lifecycle if necessary
|
||||
if (publicInstance.componentWillMount) {
|
||||
publicInstance.componentWillMount();
|
||||
}
|
||||
renderedElement = publicInstance.render();
|
||||
} else if (typeof type === 'function') {
|
||||
// Component function
|
||||
publicInstance = null;
|
||||
renderedElement = type(props);
|
||||
}
|
||||
|
||||
// Save the public instance
|
||||
this.publicInstance = publicInstance;
|
||||
|
||||
// Instantiate the child internal instance according to the element.
|
||||
// It would be a DOMComponent for <div /> or <p />,
|
||||
// and a CompositeComponent for <App /> or <Button />:
|
||||
var renderedComponent = instantiateComponent(renderedElement);
|
||||
this.renderedComponent = renderedComponent;
|
||||
|
||||
// Mount the rendered output
|
||||
return renderedComponent.mount();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This is not much different from our previous `mountComposite()` implementation, but now we can save some information, such as `this.currentElement`, `this.renderedComponent`, and `this.publicInstance`, for use during updates.
|
||||
|
||||
Note that an instance of `CompositeComponent` is not the same thing as an instance of the user-supplied `element.type`. `CompositeComponent` is an implementation detail of our reconciler, and is never exposed to the user. The user-defined class is the one we read from `element.type`, and `CompositeComponent` creates an instance of it.
|
||||
|
||||
To avoid the confusion, we will call instances of `CompositeComponent` and `DOMComponent` "internal instances". They exist so we can associate some long-lived data with them. Only the renderer and the reconciler are aware that they exist.
|
||||
|
||||
In contrast, we call an instance of the user-defined class a "public instance". The public instance is what you see as `this` in the `render()` and other methods of your custom components.
|
||||
|
||||
The `mountHost()` function, refactored to be a `mount()` method on `DOMComponent` class, also looks familiar:
|
||||
|
||||
```js
|
||||
class DOMComponent {
|
||||
constructor(element) {
|
||||
this.currentElement = element;
|
||||
this.renderedChildren = [];
|
||||
this.node = null;
|
||||
}
|
||||
|
||||
getPublicInstance() {
|
||||
// For DOM components, only expose the DOM node.
|
||||
return this.node;
|
||||
}
|
||||
|
||||
mount() {
|
||||
var element = this.currentElement;
|
||||
var type = element.type;
|
||||
var props = element.props;
|
||||
var children = props.children || [];
|
||||
if (!Array.isArray(children)) {
|
||||
children = [children];
|
||||
}
|
||||
|
||||
// Create and save the node
|
||||
var node = document.createElement(type);
|
||||
this.node = node;
|
||||
|
||||
// Set the attributes
|
||||
Object.keys(props).forEach(propName => {
|
||||
if (propName !== 'children') {
|
||||
node.setAttribute(propName, props[propName]);
|
||||
}
|
||||
});
|
||||
|
||||
// Create and save the contained children.
|
||||
// Each of them can be a DOMComponent or a CompositeComponent,
|
||||
// depending on whether the element type is a string or a function.
|
||||
var renderedChildren = children.map(instantiateComponent);
|
||||
this.renderedChildren = renderedChildren;
|
||||
|
||||
// Collect DOM nodes they return on mount
|
||||
var childNodes = renderedChildren.map(child => child.mount());
|
||||
childNodes.forEach(childNode => node.appendChild(childNode));
|
||||
|
||||
// Return the DOM node as mount result
|
||||
return node;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The main difference after refactoring from `mountHost()` is that we now keep `this.node` and `this.renderedChildren` associated with the internal DOM component instance. We will also use them for applying non-destructive updates in the future.
|
||||
|
||||
As a result, each internal instance, composite or host, now points to its child internal instances. To help visualize this, if a functional `<App>` component renders a `<Button>` class component, and `Button` class renders a `<div>`, the internal instance tree would look like this:
|
||||
|
||||
```js
|
||||
[object CompositeComponent] {
|
||||
currentElement: <App />,
|
||||
publicInstance: null,
|
||||
renderedComponent: [object CompositeComponent] {
|
||||
currentElement: <Button />,
|
||||
publicInstance: [object Button],
|
||||
renderedComponent: [object DOMComponent] {
|
||||
currentElement: <div />,
|
||||
node: [object HTMLDivElement],
|
||||
renderedChildren: []
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
In the DOM you would only see the `<div>`. However the internal instance tree contains both composite and host internal instances.
|
||||
|
||||
The composite internal instances need to store:
|
||||
|
||||
* The current element.
|
||||
* The public instance if element type is a class.
|
||||
* The single rendered internal instance. It can be either a `DOMComponent` or a `CompositeComponent`.
|
||||
|
||||
The host internal instances need to store:
|
||||
|
||||
* The current element.
|
||||
* The DOM node.
|
||||
* All the child internal instances. Each of them can be either a `DOMComponent` or a `CompositeComponent`.
|
||||
|
||||
If you're struggling to imagine how an internal instance tree is structured in more complex applications, [React DevTools](https://github.com/facebook/react-devtools) can give you a close approximation, as it highlights host instances with grey, and composite instances with purple:
|
||||
|
||||
<img src="/react/img/docs/implementation-notes-tree.png" width="500" style="max-width: 100%" alt="React DevTools tree" />
|
||||
|
||||
To complete this refactoring, we will introduce a function that mounts a complete tree into a container node, just like `ReactDOM.render()`. It returns a public instance, also like `ReactDOM.render()`:
|
||||
|
||||
```js
|
||||
function mountTree(element, containerNode) {
|
||||
// Create the top-level internal instance
|
||||
var rootComponent = instantiateComponent(element);
|
||||
|
||||
// Mount the top-level component into the container
|
||||
var node = rootComponent.mount();
|
||||
containerNode.appendChild(node);
|
||||
|
||||
// Return the public instance it provides
|
||||
var publicInstance = rootComponent.getPublicInstance();
|
||||
return publicInstance;
|
||||
}
|
||||
|
||||
var rootEl = document.getElementById('root');
|
||||
mountTree(<App />, rootEl);
|
||||
```
|
||||
|
||||
### Unmounting
|
||||
|
||||
Now that we have internal instances that hold onto their children and the DOM nodes, we can implement unmounting. For a composite component, unmounting calls a lifecycle hook and recurses.
|
||||
|
||||
```js
|
||||
class CompositeComponent {
|
||||
|
||||
// ...
|
||||
|
||||
unmount() {
|
||||
// Call the lifecycle hook if necessary
|
||||
var publicInstance = this.publicInstance;
|
||||
if (publicInstance) {
|
||||
if (publicInstance.componentWillUnmount) {
|
||||
publicInstance.componentWillUnmount();
|
||||
}
|
||||
}
|
||||
|
||||
// Unmount the single rendered component
|
||||
var renderedComponent = this.renderedComponent;
|
||||
renderedComponent.unmount();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
For `DOMComponent`, unmounting tells each child to unmount:
|
||||
|
||||
```js
|
||||
class DOMComponent {
|
||||
|
||||
// ...
|
||||
|
||||
unmount() {
|
||||
// Unmount all the children
|
||||
var renderedChildren = this.renderedChildren;
|
||||
renderedChildren.forEach(child => child.unmount());
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
In practice, unmounting DOM components also removes the event listeners and clears some caches, but we will skip those details.
|
||||
|
||||
We can now add a new top-level function called `unmountTree(containerNode)` that is similar to `ReactDOM.unmountComponentAtNode()`:
|
||||
|
||||
```js
|
||||
function unmountTree(containerNode) {
|
||||
// Read the internal instance from a DOM node:
|
||||
// (This doesn't work yet, we will need to change mountTree() to store it.)
|
||||
var node = containerNode.firstChild;
|
||||
var rootComponent = node._internalInstance;
|
||||
|
||||
// Unmount the tree and clear the container
|
||||
rootComponent.unmount();
|
||||
containerNode.innerHTML = '';
|
||||
}
|
||||
```
|
||||
|
||||
In order for this to work, we need to read an internal root instance from a DOM node. We will modify `mountTree()` to add the `_internalInstance` property to the root DOM node. We will also teach `mountTree()` to destroy any existing tree so it can be called multiple times:
|
||||
|
||||
```js
|
||||
function mountTree(element, containerNode) {
|
||||
// Destroy any existing tree
|
||||
if (containerNode.firstChild) {
|
||||
unmountTree(containerNode);
|
||||
}
|
||||
|
||||
// Create the top-level internal instance
|
||||
var rootComponent = instantiateComponent(element);
|
||||
|
||||
// Mount the top-level component into the container
|
||||
var node = rootComponent.mount();
|
||||
containerNode.appendChild(node);
|
||||
|
||||
// Save a reference to the internal instance
|
||||
node._internalInstance = rootComponent;
|
||||
|
||||
// Return the public instance it provides
|
||||
var publicInstance = rootComponent.getPublicInstance();
|
||||
return publicInstance;
|
||||
}
|
||||
```
|
||||
|
||||
Now, running `unmountTree()`, or running `mountTree()` repeatedly, removes the old tree and runs the `componentWillUnmount()` lifecycle hook on components.
|
||||
|
||||
### Updating
|
||||
|
||||
In the previous section, we implemented unmounting. However React wouldn't be very useful if each prop change unmounted and mounted the whole tree. The goal of the reconciler is to reuse existing instances where possible to preserve the DOM and the state:
|
||||
|
||||
```js
|
||||
var rootEl = document.getElementById('root');
|
||||
|
||||
mountTree(<App />, rootEl);
|
||||
// Should reuse the existing DOM:
|
||||
mountTree(<App />, rootEl);
|
||||
```
|
||||
|
||||
We will extend our internal instance contract with one more method. In addition to `mount()` and `unmount()`, both `DOMComponent` and `CompositeComponent` will implement a new method called `receive(nextElement)`:
|
||||
|
||||
```js
|
||||
class CompositeComponent {
|
||||
// ...
|
||||
|
||||
receive(nextElement) {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
class DOMComponent {
|
||||
// ...
|
||||
|
||||
receive(nextElement) {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Its job is to do whatever is necessary to bring the component (and any of its children) up to date with the description provided by the `nextElement`.
|
||||
|
||||
This is the part that is often described as "virtual DOM diffing" although what really happens is that we walk the internal tree recursively and let each internal instance receive an update.
|
||||
|
||||
### Updating Composite Components
|
||||
|
||||
When a composite component receives a new element, we run the `componentWillUpdate()` lifecycle hook.
|
||||
|
||||
Then we re-render the component with the new props, and get the next rendered element:
|
||||
|
||||
```js
|
||||
class CompositeComponent {
|
||||
|
||||
// ...
|
||||
|
||||
receive(nextElement) {
|
||||
var prevProps = this.currentElement.props;
|
||||
var publicInstance = this.publicInstance;
|
||||
var prevRenderedComponent = this.renderedComponent;
|
||||
var prevRenderedElement = prevRenderedComponent.currentElement;
|
||||
|
||||
// Update *own* element
|
||||
this.currentElement = nextElement;
|
||||
var type = nextElement.type;
|
||||
var nextProps = nextElement.props;
|
||||
|
||||
// Figure out what the next render() output is
|
||||
var nextRenderedElement;
|
||||
if (isClass(type)) {
|
||||
// Component class
|
||||
// Call the lifecycle if necessary
|
||||
if (publicInstance.componentWillUpdate) {
|
||||
publicInstance.componentWillUpdate(nextProps);
|
||||
}
|
||||
// Update the props
|
||||
publicInstance.props = nextProps;
|
||||
// Re-render
|
||||
nextRenderedElement = publicInstance.render();
|
||||
} else if (typeof type === 'function') {
|
||||
// Component function
|
||||
nextRenderedElement = type(nextProps);
|
||||
}
|
||||
|
||||
// ...
|
||||
```
|
||||
|
||||
Next, we can look at the rendered element's `type`. If the `type` has not changed since the last render, the component below can also be updated in place.
|
||||
|
||||
For example, if it returned `<Button color="red" />` the first time, and `<Button color="blue" />` the second time, we can just tell the corresponding internal instance to `receive()` the next element:
|
||||
|
||||
```js
|
||||
// ...
|
||||
|
||||
// If the rendered element type has not changed,
|
||||
// reuse the existing component instance and exit.
|
||||
if (prevRenderedElement.type === nextRenderedElement.type) {
|
||||
prevRenderedComponent.receive(nextRenderedElement);
|
||||
return;
|
||||
}
|
||||
|
||||
// ...
|
||||
```
|
||||
|
||||
However, if the next rendered element has a different `type` than the previously rendered element, we can't update the internal instance. A `<button>` can't "become" an `<input>`.
|
||||
|
||||
Instead, we have to unmount the existing internal instance and mount the new one corresponding to the rendered element type. For example, this is what happens when a component that previously rendered a `<button />` renders an `<input />`:
|
||||
|
||||
```js
|
||||
// ...
|
||||
|
||||
// If we reached this point, we need to unmount the previously
|
||||
// mounted component, mount the new one, and swap their nodes.
|
||||
|
||||
// Find the old node because it will need to be replaced
|
||||
var prevNode = prevRenderedComponent.getHostNode();
|
||||
|
||||
// Unmount the old child and mount a new child
|
||||
prevRenderedComponent.unmount();
|
||||
var nextRenderedComponent = instantiateComponent(nextRenderedElement);
|
||||
var nextNode = nextRenderedComponent.mount();
|
||||
|
||||
// Replace the reference to the child
|
||||
this.renderedComponent = nextRenderedComponent;
|
||||
|
||||
// Replace the old node with the new one
|
||||
// Note: this is renderer-specific code and
|
||||
// ideally should live outside of CompositeComponent:
|
||||
prevNode.parentNode.replaceChild(nextNode, prevNode);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
To sum this up, when a composite component receives a new element, it may either delegate the update to its rendered internal instance, or unmount it and mount a new one in its place.
|
||||
|
||||
There is another condition under which a component will re-mount rather than receive an element, and that is when the element's `key` has changed. We don't discuss `key` handling in this document because it adds more complexity to an already complex tutorial.
|
||||
|
||||
Note that we needed to add a method called `getHostNode()` to the internal instance contract so that it's possible to locate the platform-specific node and replace it during the update. Its implementation is straightforward for both classes:
|
||||
|
||||
```js
|
||||
class CompositeComponent {
|
||||
// ...
|
||||
|
||||
getHostNode() {
|
||||
// Ask the rendered component to provide it.
|
||||
// This will recursively drill down any composites.
|
||||
return this.renderedComponent.getHostNode();
|
||||
}
|
||||
}
|
||||
|
||||
class DOMComponent {
|
||||
// ...
|
||||
|
||||
getHostNode() {
|
||||
return this.node;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Updating Host Components
|
||||
|
||||
Host component implementations, such as `DOMComponent`, update differently. When they receive an element, they need to update the underlying platform-specific view. In case of React DOM, this means updating the DOM attributes:
|
||||
|
||||
```js
|
||||
class DOMComponent {
|
||||
// ...
|
||||
|
||||
receive(nextElement) {
|
||||
var node = this.node;
|
||||
var prevElement = this.currentElement;
|
||||
var prevProps = prevElement.props;
|
||||
var nextProps = nextElement.props;
|
||||
this.currentElement = nextElement;
|
||||
|
||||
// Remove old attributes.
|
||||
Object.keys(prevProps).forEach(propName => {
|
||||
if (propName !== 'children' && !nextProps.hasOwnProperty(propName)) {
|
||||
node.removeAttribute(propName);
|
||||
}
|
||||
});
|
||||
// Set next attributes.
|
||||
Object.keys(nextProps).forEach(propName => {
|
||||
if (propName !== 'children') {
|
||||
node.setAttribute(propName, nextProps[propName]);
|
||||
}
|
||||
});
|
||||
|
||||
// ...
|
||||
```
|
||||
|
||||
Then, host components need to update their children. Unlike composite components, they might contain more than a single child.
|
||||
|
||||
In this simplified example, we use an array of internal instances and iterate over it, either updating or replacing the internal instances depending on whether the received `type` matches their previous `type`. The real reconciler also takes element's `key` in the account and track moves in addition to insertions and deletions, but we will omit this logic.
|
||||
|
||||
We collect DOM operations on children in a list so we can execute them in batch:
|
||||
|
||||
```js
|
||||
// ...
|
||||
|
||||
// These are arrays of React elements:
|
||||
var prevChildren = prevProps.children || [];
|
||||
if (!Array.isArray(prevChildren)) {
|
||||
prevChildren = [prevChildren];
|
||||
}
|
||||
var nextChildren = nextProps.children || [];
|
||||
if (!Array.isArray(nextChildren)) {
|
||||
nextChildren = [nextChildren];
|
||||
}
|
||||
// These are arrays of internal instances:
|
||||
var prevRenderedChildren = this.renderedChildren;
|
||||
var nextRenderedChildren = [];
|
||||
|
||||
// As we iterate over children, we will add operations to the array.
|
||||
var operationQueue = [];
|
||||
|
||||
// Note: the section below is extremely simplified!
|
||||
// It doesn't handle reorders, children with holes, or keys.
|
||||
// It only exists to illustrate the overall flow, not the specifics.
|
||||
|
||||
for (var i = 0; i < nextChildren.length; i++) {
|
||||
// Try to get an existing internal instance for this child
|
||||
var prevChild = prevRenderedChildren[i];
|
||||
|
||||
// If there is no internal instance under this index,
|
||||
// a child has been appended to the end. Create a new
|
||||
// internal instance, mount it, and use its node.
|
||||
if (!prevChild) {
|
||||
var nextChild = instantiateComponent(nextChildren[i]);
|
||||
var node = nextChild.mount();
|
||||
|
||||
// Record that we need to append a node
|
||||
operationQueue.push({type: 'ADD', node});
|
||||
nextRenderedChildren.push(nextChild);
|
||||
continue;
|
||||
}
|
||||
|
||||
// We can only update the instance if its element's type matches.
|
||||
// For example, <Button size="small" /> can be updated to
|
||||
// <Button size="large" /> but not to an <App />.
|
||||
var canUpdate = prevChildren[i].type === nextChildren[i].type;
|
||||
|
||||
// If we can't update an existing instance, we have to unmount it
|
||||
// and mount a new one instead of it.
|
||||
if (!canUpdate) {
|
||||
var prevNode = prevChild.node;
|
||||
prevChild.unmount();
|
||||
|
||||
var nextChild = instantiateComponent(nextChildren[i]);
|
||||
var nextNode = nextChild.mount();
|
||||
|
||||
// Record that we need to swap the nodes
|
||||
operationQueue.push({type: 'REPLACE', prevNode, nextNode});
|
||||
nextRenderedChildren.push(nextChild);
|
||||
continue;
|
||||
}
|
||||
|
||||
// If we can update an existing internal instance,
|
||||
// just let it receive the next element and handle its own update.
|
||||
prevChild.receive(nextChildren[i]);
|
||||
nextRenderedChildren.push(prevChild);
|
||||
}
|
||||
|
||||
// Finally, unmount any children that don't exist:
|
||||
for (var j = nextChildren.length; j < prevChildren.length; j++) {
|
||||
var prevChild = prevRenderedChildren[j];
|
||||
var node = prevChild.node;
|
||||
prevChild.unmount();
|
||||
|
||||
// Record that we need to remove the node
|
||||
operationQueue.push({type: 'REMOVE', node});
|
||||
}
|
||||
|
||||
// Point the list of rendered children to the updated version.
|
||||
this.renderedChildren = nextRenderedChildren;
|
||||
|
||||
// ...
|
||||
```
|
||||
|
||||
As the last step, we execute the DOM operations. Again, the real reconciler code is more complex because it also handles moves:
|
||||
|
||||
```js
|
||||
// ...
|
||||
|
||||
// Process the operation queue.
|
||||
while (operationQueue.length > 0) {
|
||||
var operation = operationQueue.shift();
|
||||
switch (operation.type) {
|
||||
case 'ADD':
|
||||
this.node.appendChild(operation.node);
|
||||
break;
|
||||
case 'REPLACE':
|
||||
this.node.replaceChild(operation.nextNode, operation.prevNode);
|
||||
break;
|
||||
case 'REMOVE':
|
||||
this.node.removeChild(operation.node);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
And that is it for updating host components.
|
||||
|
||||
### Top-Level Updates
|
||||
|
||||
Now that both `CompositeComponent` and `DOMComponent` implement the `receive(nextElement)` method, we can change the top-level `mountTree()` function to use it when the element `type` is the same as it was the last time:
|
||||
|
||||
```js
|
||||
function mountTree(element, containerNode) {
|
||||
// Check for an existing tree
|
||||
if (containerNode.firstChild) {
|
||||
var prevNode = containerNode.firstChild;
|
||||
var prevRootComponent = prevNode._internalInstance;
|
||||
var prevElement = prevRootComponent.currentElement;
|
||||
|
||||
// If we can, reuse the existing root component
|
||||
if (prevElement.type === element.type) {
|
||||
prevRootComponent.receive(element);
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise, unmount the existing tree
|
||||
unmountTree(containerNode);
|
||||
}
|
||||
|
||||
// ...
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
Now calling `mountTree()` two times with the same type isn't destructive:
|
||||
|
||||
```js
|
||||
var rootEl = document.getElementById('root');
|
||||
|
||||
mountTree(<App />, rootEl);
|
||||
// Reuses the existing DOM:
|
||||
mountTree(<App />, rootEl);
|
||||
```
|
||||
|
||||
These are the basics of how React works internally.
|
||||
|
||||
### What We Left Out
|
||||
|
||||
This document is simplified compared to the real codebase. There are a few important aspects we didn't address:
|
||||
|
||||
* Components can render `null`, and the reconciler can handle "empty slots" in arrays and rendered output.
|
||||
|
||||
* The reconciler also reads `key` from the elements, and uses it to establish which internal instance corresponds to which element in an array. A bulk of complexity in the actual React implementation is related to that.
|
||||
|
||||
* In addition to composite and host internal instance classes, there are also classes for "text" and "empty" components. They represent text nodes and the "empty slots" you get by rendering `null`.
|
||||
|
||||
* Renderers use [injection](/react/contributing/codebase-overview.html#dynamic-injection) to pass the host internal class to the reconciler. For example, React DOM tells the reconciler to use `ReactDOMComponent` as the host internal instance implementation.
|
||||
|
||||
* The logic for updating the list of children is extracted into a mixin called `ReactMultiChild` which is used by the host internal instance class implementations both in React DOM and React Native.
|
||||
|
||||
* The reconciler also implements support for `setState()` in composite components. Multiple updates inside event handlers get batched into a single update.
|
||||
|
||||
* The reconciler also takes care of attaching and detaching refs to composite components and host nodes.
|
||||
|
||||
* Lifecycle hooks that are called after the DOM is ready, such as `componentDidMount()` and `componentDidUpdate()`, get collected into "callback queues" and are executed in a single batch.
|
||||
|
||||
* React puts information about the current update into an internal object called "transaction". Transactions are useful for keeping track of the queue of pending lifecycle hooks, the current DOM nesting for the warnings, and anything else that is "global" to a specific update. Transactions also ensure React "cleans everything up" after updates. For example, the transaction class provided by React DOM restores the input selection after any update.
|
||||
|
||||
### Jumping into the Code
|
||||
|
||||
* [`ReactMount`](https://github.com/facebook/react/blob/83381c1673d14cd16cf747e34c945291e5518a86/src/renderers/dom/client/ReactMount.js) is where the code like `mountTree()` and `unmountTree()` from this tutorial lives. It takes care of mounting and unmounting top-level components. [`ReactNativeMount`](https://github.com/facebook/react/blob/83381c1673d14cd16cf747e34c945291e5518a86/src/renderers/native/ReactNativeMount.js) is its React Native analog.
|
||||
* [`ReactDOMComponent`](https://github.com/facebook/react/blob/83381c1673d14cd16cf747e34c945291e5518a86/src/renderers/dom/shared/ReactDOMComponent.js) is the equivalent of `DOMComponent` in this tutorial. It implements the host component class for React DOM renderer. [`ReactNativeBaseComponent`](https://github.com/facebook/react/blob/83381c1673d14cd16cf747e34c945291e5518a86/src/renderers/native/ReactNativeBaseComponent.js) is its React Native analog.
|
||||
* [`ReactCompositeComponent`](https://github.com/facebook/react/blob/83381c1673d14cd16cf747e34c945291e5518a86/src/renderers/shared/stack/reconciler/ReactCompositeComponent.js) is the equivalent of `CompositeComponent` in this tutorial. It handles calling user-defined components and maintaining their state.
|
||||
* [`instantiateReactComponent`](https://github.com/facebook/react/blob/83381c1673d14cd16cf747e34c945291e5518a86/src/renderers/shared/stack/reconciler/instantiateReactComponent.js) contains the switch that picks the right internal instance class to construct for an element. It is equivalent to `instantiateComponent()` in this tutorial.
|
||||
|
||||
* [`ReactReconciler`](https://github.com/facebook/react/blob/83381c1673d14cd16cf747e34c945291e5518a86/src/renderers/shared/stack/reconciler/ReactReconciler.js) is a wrapper with `mountComponent()`, `receiveComponent()`, and `unmountComponent()` methods. It calls the underlying implementations on the internal instances, but also includes some code around them that is shared by all internal instance implementations.
|
||||
|
||||
* [`ReactChildReconciler`](https://github.com/facebook/react/blob/83381c1673d14cd16cf747e34c945291e5518a86/src/renderers/shared/stack/reconciler/ReactChildReconciler.js) implements the logic for mounting, updating, and unmounting children according to the `key` of their elements.
|
||||
|
||||
* [`ReactMultiChild`](https://github.com/facebook/react/blob/83381c1673d14cd16cf747e34c945291e5518a86/src/renderers/shared/stack/reconciler/ReactMultiChild.js) implements processing the operation queue for child insertions, deletions, and moves independently of the renderer.
|
||||
|
||||
* `mount()`, `receive()`, and `unmount()` are really called `mountComponent()`, `receiveComponent()`, and `unmountComponent()` in React codebase for legacy reasons, but they receive elements.
|
||||
|
||||
* Properties on the internal instances start with an underscore, e.g. `_currentElement`. They are considered to be read-only public fields throughout the codebase.
|
||||
|
||||
### Future Directions
|
||||
|
||||
Stack reconciler has inherent limitations such as being synchronous and unable to interrupt the work or split it in chunks. There is a work in progress on the [new Fiber reconciler](/react/contributing/codebase-overview.html#fiber-reconciler) with a [completely different architecture](https://github.com/acdlite/react-fiber-architecture). In the future, we intend to replace stack reconciler with it, but at the moment it is far from feature parity.
|
||||
|
||||
### Next Steps
|
||||
|
||||
Read the [next section](/react/contributing/design-principles.html) to learn about the guiding principles we use for React development.
|
||||
@@ -7,9 +7,8 @@
|
||||
|
||||
@mixin code-typography {
|
||||
font-family: 'source-code-pro', Menlo, Consolas, 'Courier New', monospace;
|
||||
line-height: 1.5;
|
||||
font-size: 13px;
|
||||
-webkit-text-size-adjust: none;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
$skinnyContentWidth: 650px;
|
||||
@@ -20,28 +19,7 @@ $columnGutter: 40px;
|
||||
$twoColumnWidth: 2 * $columnWidth + $columnGutter;
|
||||
$navHeight: 50px;
|
||||
|
||||
// Breakpoints
|
||||
$bp-large: 960px;
|
||||
$bp-medium: 640px;
|
||||
$bp-small: 480px;
|
||||
|
||||
@mixin bp-small {
|
||||
@media (max-width: $bp-small) {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin bp-medium {
|
||||
@media (max-width: $bp-medium) {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin bp-large {
|
||||
@media (max-width: $bp-large) {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
||||
// basic reset
|
||||
* {
|
||||
@@ -68,20 +46,15 @@ html {
|
||||
|
||||
.container {
|
||||
padding-top: $navHeight;
|
||||
width: 100%;
|
||||
min-width: $contentWidth + (2 * $contentPadding);
|
||||
}
|
||||
|
||||
.wrap {
|
||||
max-width: $contentWidth + (2 * $contentPadding);
|
||||
width: $contentWidth + (2 * $contentPadding);
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
padding-left: 20px;
|
||||
padding-right: 20px;
|
||||
|
||||
@include bp-large {
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.skinnyWrap {
|
||||
@@ -122,7 +95,6 @@ h1, h2, h3, h4, h5, h6 {
|
||||
.hash-link {
|
||||
color: $mediumTextColor;
|
||||
display: none;
|
||||
padding-left: 8px;
|
||||
}
|
||||
|
||||
// Main Nav
|
||||
@@ -138,21 +110,21 @@ h1, h2, h3, h4, h5, h6 {
|
||||
width: 100%;
|
||||
z-index: 100;
|
||||
|
||||
@include bp-large {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
a {
|
||||
color: $lightColor;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.nav-site {
|
||||
display: inline-flex;
|
||||
display: -ms-flexbox;
|
||||
flex: 1;
|
||||
-ms-flex: 1;
|
||||
.nav-site-internal {
|
||||
margin: 0 0 0 20px;
|
||||
}
|
||||
|
||||
.nav-site-external {
|
||||
float: right;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.nav-site {
|
||||
li {
|
||||
margin: 0;
|
||||
}
|
||||
@@ -164,82 +136,17 @@ h1, h2, h3, h4, h5, h6 {
|
||||
display: inline-block;
|
||||
height: $navHeight;
|
||||
color: #ddd;
|
||||
white-space: nowrap;
|
||||
|
||||
@include bp-large {
|
||||
display: flex;
|
||||
display: -ms-flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 0 5px;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
&.active {
|
||||
position: relative;
|
||||
color: $lightTextColor;
|
||||
border-bottom: 3px solid $primary;
|
||||
background: #333;
|
||||
|
||||
&:after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
border-bottom: 3px solid $primary;
|
||||
}
|
||||
|
||||
@include bp-large {
|
||||
background: inherit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.nav-site-item {
|
||||
&--hidden-sm {
|
||||
@include bp-large {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.nav-site-search {
|
||||
@include bp-large {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
right: 0;
|
||||
top: 0;
|
||||
margin: 0 10px;
|
||||
|
||||
&:focus {
|
||||
width: 170px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.nav-site-internal {
|
||||
margin: 0 0 0 20px;
|
||||
|
||||
@include bp-large {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.nav-site-external {
|
||||
float: right;
|
||||
margin: 0;
|
||||
|
||||
@include bp-large {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 55px;
|
||||
float: none;
|
||||
}
|
||||
}
|
||||
|
||||
.nav-home {
|
||||
@@ -248,20 +155,11 @@ h1, h2, h3, h4, h5, h6 {
|
||||
line-height: $navHeight;
|
||||
height: $navHeight;
|
||||
display: inline-block;
|
||||
|
||||
@include bp-large {
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.nav-logo {
|
||||
vertical-align: middle;
|
||||
display: inline-block;
|
||||
|
||||
@include bp-large {
|
||||
height: 30px;
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
|
||||
ul {
|
||||
@@ -274,37 +172,10 @@ h1, h2, h3, h4, h5, h6 {
|
||||
}
|
||||
}
|
||||
|
||||
.nav-lists {
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
width: calc(100% - 120px);
|
||||
|
||||
@include bp-large {
|
||||
display: flex;
|
||||
display: -ms-flex;
|
||||
width: calc(100% + 20px);
|
||||
margin: 0 -10px;
|
||||
font-size: 0.9em;
|
||||
|
||||
li {
|
||||
display: flex;
|
||||
display: -ms-flex;
|
||||
-ms-flex: 1 0 auto;
|
||||
align-items: center;
|
||||
|
||||
a {
|
||||
-ms-flex: 1;
|
||||
text-align: center;
|
||||
line-height: 1.2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Hero!
|
||||
|
||||
.hero {
|
||||
min-height: 300px;
|
||||
height: 300px;
|
||||
// background: $darkColor url(../img/header.png) no-repeat center;
|
||||
background: $darkColor;
|
||||
padding-top: 50px;
|
||||
@@ -329,13 +200,8 @@ h1, h2, h3, h4, h5, h6 {
|
||||
}
|
||||
|
||||
.buttons-unit {
|
||||
display: flex;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
margin-top: 60px;
|
||||
text-align: center;
|
||||
font-size: 1em;
|
||||
|
||||
a {
|
||||
color: $blueColor;
|
||||
@@ -349,11 +215,6 @@ h1, h2, h3, h4, h5, h6 {
|
||||
&:active {
|
||||
background: darken($primary, 5%);
|
||||
}
|
||||
|
||||
@include bp-large {
|
||||
margin: 5px;
|
||||
font-size: 1em;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -372,17 +233,12 @@ h1, h2, h3, h4, h5, h6 {
|
||||
float: left;
|
||||
width: 210px;
|
||||
|
||||
@include bp-medium {
|
||||
width: 100%;
|
||||
padding-bottom: 40px;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
}
|
||||
ul ul {
|
||||
margin: 0 0 6px 20px;
|
||||
margin: 6px 0 0 20px;
|
||||
}
|
||||
li {
|
||||
line-height: 16px;
|
||||
@@ -436,25 +292,6 @@ h1, h2, h3, h4, h5, h6 {
|
||||
padding-bottom: 0;
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
> ul {
|
||||
@include bp-medium {
|
||||
columns: 2
|
||||
}
|
||||
|
||||
@include bp-small {
|
||||
columns: 1;
|
||||
}
|
||||
|
||||
li {
|
||||
margin: 0;
|
||||
|
||||
a {
|
||||
padding: 0;
|
||||
line-height: 1.6;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -474,8 +311,7 @@ h1, h2, h3, h4, h5, h6 {
|
||||
.home-divider {
|
||||
border-top-color: #bbb;
|
||||
margin: 0 auto;
|
||||
width: 100%;
|
||||
max-width: 400px;
|
||||
width: 400px;
|
||||
}
|
||||
|
||||
.skinny-row {
|
||||
@@ -501,11 +337,6 @@ h1, h2, h3, h4, h5, h6 {
|
||||
margin-left: 40px;
|
||||
width: $columnWidth;
|
||||
|
||||
@include bp-large {
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
h3 {
|
||||
color: $darkColor;
|
||||
font-size: 24px;
|
||||
@@ -616,6 +447,14 @@ h1, h2, h3, h4, h5, h6 {
|
||||
float: right;
|
||||
}
|
||||
|
||||
footer {
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
margin-top: 36px;
|
||||
margin-bottom: 18px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
section.black content {
|
||||
padding-bottom: 18px;
|
||||
}
|
||||
@@ -628,10 +467,6 @@ section.black content {
|
||||
@include clearfix;
|
||||
|
||||
padding-top: 20px;
|
||||
padding-bottom: 80px;
|
||||
@include bp-medium {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
padding: 5px 15px;
|
||||
@@ -666,17 +501,13 @@ section.black content {
|
||||
}
|
||||
|
||||
padding-top: 20px;
|
||||
padding-bottom: 80px;
|
||||
@include bp-medium {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
// Make a notice box out of blockquotes in the documentation:
|
||||
blockquote {
|
||||
padding: 15px 30px 15px 15px;
|
||||
margin: 20px 0;
|
||||
background-color: rgba(248, 245, 236, 0.5);
|
||||
border-left: 5px solid rgba(191, 87, 73, 0.2);
|
||||
background-color: rgba(204, 122, 111, 0.09999999999999998);
|
||||
border-left: 5px solid rgba(191, 87, 73, 0.19999999999999996);
|
||||
h4 {
|
||||
margin-top: 0;
|
||||
}
|
||||
@@ -777,17 +608,7 @@ figure {
|
||||
|
||||
.inner-content {
|
||||
float: right;
|
||||
width: 100%;
|
||||
max-width: $skinnyContentWidth;
|
||||
|
||||
@include bp-large {
|
||||
width: calc(100% - 240px);
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
@include bp-medium {
|
||||
width: 100%;
|
||||
}
|
||||
width: $skinnyContentWidth;
|
||||
}
|
||||
|
||||
.nosidebar .inner-content {
|
||||
@@ -806,48 +627,8 @@ h1 {
|
||||
font-weight: normal;
|
||||
line-height: 20px;
|
||||
margin-top: 17px;
|
||||
|
||||
@include bp-medium {
|
||||
float: left;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Community
|
||||
*/
|
||||
|
||||
.communityContent {
|
||||
@include clearfix;
|
||||
|
||||
h3 {
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
padding-top: 20px;
|
||||
|
||||
blockquote {
|
||||
padding: 5px 15px;
|
||||
margin: 20px 0;
|
||||
background-color: #f8f5ec;
|
||||
border-left: 5px solid #f7ebc6;
|
||||
}
|
||||
|
||||
th {
|
||||
padding-right: 6px;
|
||||
text-align: right;
|
||||
vertical-align: top;
|
||||
font-weight: normal;
|
||||
@include code-typography;
|
||||
}
|
||||
|
||||
td {
|
||||
vertical-align: top;
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Blog */
|
||||
|
||||
.post-list-item + .post-list-item {
|
||||
@@ -921,8 +702,7 @@ p a code {
|
||||
border-radius: 0 3px 3px 3px;
|
||||
float: left;
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
max-width: $twoColumnWidth;
|
||||
width: $twoColumnWidth;
|
||||
}
|
||||
|
||||
.playgroundPreview {
|
||||
@@ -931,7 +711,6 @@ p a code {
|
||||
float: right;
|
||||
padding: 15px 20px;
|
||||
width: $columnWidth;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.playgroundError {
|
||||
@@ -946,7 +725,6 @@ p a code {
|
||||
|
||||
.MarkdownEditor .content {
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.hll {
|
||||
@@ -1028,9 +806,9 @@ p a code {
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
@include bp-large {
|
||||
@media screen and (max-width: 960px) {
|
||||
.nav-main {
|
||||
position: relative;
|
||||
position: static;
|
||||
}
|
||||
.container {
|
||||
padding-top: 0;
|
||||
@@ -1043,7 +821,6 @@ p a code {
|
||||
|
||||
.post img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.pagination {
|
||||
@@ -1064,20 +841,6 @@ div[data-twttr-id] iframe {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
.fb_iframe_widget {
|
||||
max-width: 100%;
|
||||
|
||||
* {
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
#twitter-widget-0 {
|
||||
@include bp-large {
|
||||
display: none !important; // Need !important because they inline display on the iframe.
|
||||
}
|
||||
}
|
||||
|
||||
/* Acknowledgements */
|
||||
|
||||
.three-column {
|
||||
@@ -1097,6 +860,12 @@ div[data-twttr-id] iframe {
|
||||
|
||||
/* Algolia Doc Search */
|
||||
|
||||
@media screen and (max-width: 960px) {
|
||||
#algolia-doc-search {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
input#algolia-doc-search {
|
||||
background: transparent url('/react/img/search.png') no-repeat 10px center;
|
||||
background-size: 16px 16px;
|
||||
@@ -1117,21 +886,10 @@ input#algolia-doc-search {
|
||||
width: 170px;
|
||||
|
||||
transition: width .2s ease;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
width: 240px;
|
||||
}
|
||||
|
||||
@include bp-large {
|
||||
background-color: transparent;
|
||||
width: 0;
|
||||
cursor: pointer;
|
||||
|
||||
&:focus {
|
||||
width: 200px;
|
||||
background-color: #333;
|
||||
}
|
||||
}
|
||||
input#algolia-doc-search:focus {
|
||||
width: 240px;
|
||||
}
|
||||
|
||||
.algolia-autocomplete .aa-dropdown-menu {
|
||||
@@ -1167,96 +925,3 @@ input#algolia-doc-search {
|
||||
.aa-cursor .algolia-docsearch-suggestion {
|
||||
background: #f1f3f5;
|
||||
}
|
||||
|
||||
/**
|
||||
* Footer
|
||||
*/
|
||||
|
||||
footer.nav-footer {
|
||||
box-sizing: border-box;
|
||||
border: none;
|
||||
font-weight: 300;
|
||||
color: #202020;
|
||||
font-size: 15px;
|
||||
line-height: 24px;
|
||||
background: #2D2D2D;
|
||||
box-shadow: inset 0 10px 10px -5px #0d1116;
|
||||
padding-top: 2em;
|
||||
padding-bottom: 2em;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
footer .sitemap {
|
||||
display: flex;
|
||||
display: -ms-flexbox;
|
||||
justify-content: space-between;
|
||||
max-width: 1080px;
|
||||
margin: 0 auto 3em;
|
||||
}
|
||||
footer .sitemap div {
|
||||
flex: 1;
|
||||
-ms-flex: 1;
|
||||
}
|
||||
footer .sitemap .nav-home {
|
||||
display: table;
|
||||
margin: -12px 20px 0 0;
|
||||
padding: 10px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
transition: opacity 0.15s ease-in-out;
|
||||
background: url("../img/logo_small_gray.png") no-repeat content-box;
|
||||
}
|
||||
footer .sitemap .nav-home:hover,
|
||||
footer .sitemap .nav-home:focus {
|
||||
background-image: url("../img/logo_small.png");
|
||||
}
|
||||
@media screen and (max-width: 740px) {
|
||||
footer .sitemap {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
footer .sitemap a {
|
||||
color: white;
|
||||
display: table;
|
||||
margin: 2px -10px;
|
||||
padding: 3px 10px;
|
||||
}
|
||||
footer .sitemap a:hover,
|
||||
footer .sitemap a:focus {
|
||||
color: #61dafb;
|
||||
text-decoration: none;
|
||||
}
|
||||
footer .sitemap h6 > a:hover,
|
||||
footer .sitemap h6 > a:focus {
|
||||
color: #61dafb;
|
||||
text-decoration: none;
|
||||
}
|
||||
footer .sitemap h5,
|
||||
footer .sitemap h6 {
|
||||
margin: 0 0 10px;
|
||||
}
|
||||
footer .sitemap h5,
|
||||
footer .sitemap h6,
|
||||
footer .sitemap h5 > a,
|
||||
footer .sitemap h6 > a {
|
||||
color: white;
|
||||
}
|
||||
footer .sitemap h5 > a,
|
||||
footer .sitemap h6 > a {
|
||||
margin: 0 -10px;
|
||||
}
|
||||
footer .fbOpenSource {
|
||||
display: block;
|
||||
margin: 1em auto;
|
||||
opacity: 0.4;
|
||||
transition: opacity 0.15s ease-in-out;
|
||||
width: 170px;
|
||||
}
|
||||
footer .fbOpenSource:hover {
|
||||
opacity: 1.0;
|
||||
}
|
||||
footer .copyright {
|
||||
color: rgba(255, 255, 255, 0.4);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
28
docs/docs/01-why-react.de-DE.md
Normal file
28
docs/docs/01-why-react.de-DE.md
Normal file
@@ -0,0 +1,28 @@
|
||||
---
|
||||
id: why-react-de-DE
|
||||
title: Warum React?
|
||||
permalink: docs/why-react-de-DE.html
|
||||
---
|
||||
React ist eine JavaScript-Bibliothek von Facebook und Instagram für Benutzeroberflächen. Man kann sich React als das **V** in **[MVC](https://de.wikipedia.org/wiki/Model_View_Controller)** vorstellen.
|
||||
|
||||
Wir haben React für folgende Aufgabe entwickelt: **umfangreiche Anwendungen zu bauen, deren Daten sich zeitlich ändern**.
|
||||
|
||||
## Einfach
|
||||
|
||||
Beschreibe, wie sich Deine App zu jedem gewünschten Zeitpunkt präsentieren soll und React kümmert sich um alle Benutzeroberflächen-Änderungen sobald sich die zugrundeliegenden Daten ändern.
|
||||
|
||||
## Deklarativ
|
||||
|
||||
Bei Datenveränderungen drückt React bildlich die "Aktualisieren"-Taste und versteht sich darauf, nur die veränderten Elemente zu erneuern.
|
||||
|
||||
## Baue zusammensetzbare Komponenten
|
||||
|
||||
React unterstützt die Entwicklung wiederverwendbarer Komponenten. Tatsächlich machst Du in React nichts anderes, als Komponenten zu bauen. Dank ihrer Kapselung erleichtern Komponenten die Wiederverwendung und das Testen von Code sowie die Trennung der Belange.
|
||||
|
||||
## Gib' ihnen fünf Minuten
|
||||
|
||||
React hinterfragt eine ganze Reihe konventioneller Standpunkte. Auf den ersten Blick mögen einige Ideen verrückt klingen. [Gib' ihnen fünf Minuten](https://signalvnoise.com/posts/3124-give-it-five-minutes) während Du diese Anleitung liest; diese verrückten Ideen halfen dabei, tausende von Komponenten innerhalb und außerhalb von Facebook und Instagram zu entwickeln.
|
||||
|
||||
## Erfahre mehr
|
||||
|
||||
Erfahre mehr über unsere Motivation zur Entwicklung von React in [diesem Blogeintrag](/react/blog/2013/06/05/why-react.html).
|
||||
29
docs/docs/01-why-react.it-IT.md
Normal file
29
docs/docs/01-why-react.it-IT.md
Normal file
@@ -0,0 +1,29 @@
|
||||
---
|
||||
id: why-react-it-IT
|
||||
title: Perché React?
|
||||
permalink: docs/why-react-it-IT.html
|
||||
next: displaying-data-it-IT.html
|
||||
---
|
||||
React è una libreria JavaScript per creare interfacce utente scritta da Facebook e Instagram. A molti piace pensare a React come alla **V** di **[MVC](https://it.wikipedia.org/wiki/Model-View-Controller)**.
|
||||
|
||||
Abbiamo costruito React per risolvere un problema: **costruire applicazioni di grandi dimensioni con dati che cambiano nel tempo**.
|
||||
|
||||
## Semplice
|
||||
|
||||
Dichiara semplicemente come la tua app debba apparire in ogni istante, e React gestirà automaticamente tutti gli aggiornamenti della UI quando i dati sottostanti cambiano.
|
||||
|
||||
## Dichiarativo
|
||||
|
||||
Quando i dati cambiano, React preme idealmente il bottone "aggiorna", e sa come aggiornare soltanto le parti che sono cambiate.
|
||||
|
||||
## Costruisci Componenti Componibili
|
||||
|
||||
React è basato interamente sulla costruzione di componenti riutilizzabili. Infatti, con React l'*unica* cosa che fai è costruire componenti. Dal momento che sono così incapsulati, i componenti facilitano il riutilizzo del codice, la verifica e la separazione dei concetti.
|
||||
|
||||
## Dagli Cinque Minuti
|
||||
|
||||
React sfida molte convenzioni, e a prima vista alcune delle idee potrebbero sembrare folli. [Dagli cinque minuti](https://signalvnoise.com/posts/3124-give-it-five-minutes) mentre leggi questa guida; quelle idee folli hanno funzionato per costruire migliaia di componenti sia dentro che fuori da Facebook e Instagram.
|
||||
|
||||
## Per Approfondire
|
||||
|
||||
Puoi approfondire le nostre motivazioni per la costruzione di React leggendo [questo articolo del blog](/react/blog/2013/06/05/why-react.html).
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user