Compare commits
238 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1c1f68e8dc | ||
|
|
443683525f | ||
|
|
88296d994d | ||
|
|
eee3bce748 | ||
|
|
6466714e4c | ||
|
|
7df71a2525 | ||
|
|
28e51005dc | ||
|
|
fbe19e90b9 | ||
|
|
db0ec1ab0f | ||
|
|
ac0c3e60fb | ||
|
|
9d8f7aed0e | ||
|
|
3fe1664601 | ||
|
|
cc3b821f66 | ||
|
|
2692cf4f03 | ||
|
|
b691f7448f | ||
|
|
dec8b62796 | ||
|
|
44550c374f | ||
|
|
d7d9b81a85 | ||
|
|
d128b45c6f | ||
|
|
e2a70ac0ea | ||
|
|
b062596fd4 | ||
|
|
5014781d21 | ||
|
|
923aee7cf5 | ||
|
|
04ebe6d8c1 | ||
|
|
445ded0e3b | ||
|
|
de4c0127ad | ||
|
|
48949f35c5 | ||
|
|
a8fc7d80e2 | ||
|
|
ceb282a46d | ||
|
|
1668ccb2b0 | ||
|
|
95cf873e53 | ||
|
|
7d5498de1b | ||
|
|
e2c648e93c | ||
|
|
ca8ddfda02 | ||
|
|
a53e45ada0 | ||
|
|
c07ed1a498 | ||
|
|
f87407034d | ||
|
|
6f26178a3a | ||
|
|
7480eb2317 | ||
|
|
933898b457 | ||
|
|
5d08b299a7 | ||
|
|
6165c49f1d | ||
|
|
20587a4733 | ||
|
|
6a89bc9be0 | ||
|
|
ba488ce64f | ||
|
|
b06fd4b36d | ||
|
|
2d37da10db | ||
|
|
b46d90e09d | ||
|
|
4b11e25746 | ||
|
|
1d74e43b2c | ||
|
|
27ce7a9151 | ||
|
|
a9578c9d5b | ||
|
|
b82f13546f | ||
|
|
3979c734a2 | ||
|
|
24f27f81a5 | ||
|
|
9c7d8a941d | ||
|
|
f05fe34a85 | ||
|
|
ea6c7f4edb | ||
|
|
a7cb3ace36 | ||
|
|
89defaa712 | ||
|
|
24dd09fea7 | ||
|
|
1d108d8f6a | ||
|
|
60ec3c6b37 | ||
|
|
55a788e756 | ||
|
|
1cf81c1aa9 | ||
|
|
457730dded | ||
|
|
d81d9e260f | ||
|
|
c577b82875 | ||
|
|
2d049e8df6 | ||
|
|
cd65b60960 | ||
|
|
b52288cbcf | ||
|
|
4327cde28b | ||
|
|
08c320d047 | ||
|
|
2b5c43029e | ||
|
|
c8c879f1c5 | ||
|
|
a107f6d12e | ||
|
|
4717d2480c | ||
|
|
91dc94cec6 | ||
|
|
1f605930cc | ||
|
|
c7020c017d | ||
|
|
9b025df36b | ||
|
|
b0b1303207 | ||
|
|
4f20847f8b | ||
|
|
3e95d99fe2 | ||
|
|
1dce444f70 | ||
|
|
4dfe234950 | ||
|
|
8ecaaddd23 | ||
|
|
a793486541 | ||
|
|
6b85431df6 | ||
|
|
32edcfc9cd | ||
|
|
a28dc34918 | ||
|
|
3135f888f0 | ||
|
|
84fc62f30f | ||
|
|
c4c7e0a966 | ||
|
|
918037bd30 | ||
|
|
5fe354bc1e | ||
|
|
9a9a6cf10b | ||
|
|
6ac0bbfd17 | ||
|
|
75e9127216 | ||
|
|
1d099c001f | ||
|
|
ffa70704ca | ||
|
|
71f0c6fef9 | ||
|
|
a6bdb0022f | ||
|
|
1d93d28494 | ||
|
|
c3d43193c9 | ||
|
|
da9a658e35 | ||
|
|
3bc9d9caa7 | ||
|
|
d5059c91f5 | ||
|
|
ec4c0f1dd6 | ||
|
|
4d99f2bdd4 | ||
|
|
ce1f57e940 | ||
|
|
2fbe0cd333 | ||
|
|
747d65133a | ||
|
|
195b03e196 | ||
|
|
c023d53f02 | ||
|
|
c1f0b4e9da | ||
|
|
26d060797c | ||
|
|
118b93c591 | ||
|
|
654829da66 | ||
|
|
88e29060cd | ||
|
|
a7b81a60c0 | ||
|
|
db985af3c3 | ||
|
|
2c16a6bb9d | ||
|
|
b4949fd8c6 | ||
|
|
206bc2a330 | ||
|
|
2c00d750c2 | ||
|
|
ae79e023d5 | ||
|
|
bef7ae4800 | ||
|
|
b7d7f47a5e | ||
|
|
85de53c450 | ||
|
|
96d39380fa | ||
|
|
d5a769ec89 | ||
|
|
869d26c3b4 | ||
|
|
c3f2c6b19d | ||
|
|
465d35a78a | ||
|
|
bf3f9cffc2 | ||
|
|
4b7f7b371b | ||
|
|
0dd4ff1bc8 | ||
|
|
577818e419 | ||
|
|
2589ed586d | ||
|
|
b9ce809aaf | ||
|
|
dd01e016a6 | ||
|
|
329b107606 | ||
|
|
fb7b8f201f | ||
|
|
74da40520c | ||
|
|
f5f0256d82 | ||
|
|
25bdc55fb8 | ||
|
|
f5f1c749b6 | ||
|
|
951b243d17 | ||
|
|
a9b2d841f7 | ||
|
|
58d6f4fac6 | ||
|
|
03846d6916 | ||
|
|
774a94b6c2 | ||
|
|
283dbc30ee | ||
|
|
f4374bd168 | ||
|
|
87958ea037 | ||
|
|
52235eadfd | ||
|
|
cb963b09ab | ||
|
|
1fb75eaa9e | ||
|
|
a71a787038 | ||
|
|
cbc450860e | ||
|
|
ecdc185deb | ||
|
|
cc2e5cc3d7 | ||
|
|
5c2a88a9a1 | ||
|
|
5bc9daa125 | ||
|
|
21a4e7a826 | ||
|
|
556bd43a26 | ||
|
|
8426fafe90 | ||
|
|
7ae3bbee25 | ||
|
|
bada298857 | ||
|
|
5a540f778a | ||
|
|
bed4c0595c | ||
|
|
0c89348be4 | ||
|
|
53d16f86fd | ||
|
|
ecd66274a7 | ||
|
|
586f487ea9 | ||
|
|
03e7900edb | ||
|
|
345329e079 | ||
|
|
f5798f729d | ||
|
|
dcd34ab6c1 | ||
|
|
8a78b2497a | ||
|
|
58d66ad47f | ||
|
|
f6448ff595 | ||
|
|
4421c71120 | ||
|
|
9a6ef44a06 | ||
|
|
ae5ebe3d92 | ||
|
|
0c59b3c71f | ||
|
|
6e58219117 | ||
|
|
6259f15e33 | ||
|
|
e48635bd59 | ||
|
|
cf592f29bc | ||
|
|
00e9080314 | ||
|
|
17336bc8ee | ||
|
|
1df0e8a012 | ||
|
|
66a279df53 | ||
|
|
5eb67ed4e2 | ||
|
|
fcd42c1e28 | ||
|
|
c99abadafb | ||
|
|
8753a838cf | ||
|
|
749e809478 | ||
|
|
fb37b44e79 | ||
|
|
8f8a26c091 | ||
|
|
c2e9167e45 | ||
|
|
13ef94ad46 | ||
|
|
c2388bf09b | ||
|
|
b52ea6bd8f | ||
|
|
bdf263625d | ||
|
|
8c7bbbfc21 | ||
|
|
15631e02a2 | ||
|
|
1907f72934 | ||
|
|
ba62748217 | ||
|
|
224ace32be | ||
|
|
3ef748abb3 | ||
|
|
3f8b8d754c | ||
|
|
7a18e4e00b | ||
|
|
60ed71459c | ||
|
|
7b39bbaa91 | ||
|
|
2927c4ce76 | ||
|
|
3e47b3002b | ||
|
|
1bac6d567f | ||
|
|
92cfbf16c2 | ||
|
|
b445b26164 | ||
|
|
832c503c92 | ||
|
|
076d7fd63a | ||
|
|
3ed71070a3 | ||
|
|
08dbefedc7 | ||
|
|
4be377650e | ||
|
|
8898803b4a | ||
|
|
21f71d72f0 | ||
|
|
d79061e0c6 | ||
|
|
d951c560e4 | ||
|
|
6cf782b75c | ||
|
|
dca0f7315c | ||
|
|
0983d2dbcf | ||
|
|
d90cbec236 | ||
|
|
6e20d410bb | ||
|
|
b4f6460bff | ||
|
|
199056cf1b |
22
.flowconfig
22
.flowconfig
@@ -1,13 +1,13 @@
|
||||
[ignore]
|
||||
|
||||
.*/examples/.*
|
||||
.*/build/.*
|
||||
.*/node_modules/y18n/.*
|
||||
.*/__mocks__/.*
|
||||
.*/__tests__/.*
|
||||
<PROJECT_ROOT>/examples/.*
|
||||
<PROJECT_ROOT>/build/.*
|
||||
<PROJECT_ROOT>/.*/node_modules/y18n/.*
|
||||
<PROJECT_ROOT>/.*/__mocks__/.*
|
||||
<PROJECT_ROOT>/.*/__tests__/.*
|
||||
|
||||
# Ignore Docs
|
||||
.*/docs/.*
|
||||
<PROJECT_ROOT>/.*/docs/.*
|
||||
|
||||
[include]
|
||||
|
||||
@@ -21,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\\.\\(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\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(3[0-1]\\|[1-2][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*www[a-z,_]*\\)?)\\)
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(3[0-1]\\|[1-2][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*www[a-z,_]*\\)?)\\)?:? #[0-9]+
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError
|
||||
|
||||
[version]
|
||||
^0.27.0
|
||||
^0.31.0
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -15,9 +15,10 @@ docs/code
|
||||
docs/_site
|
||||
docs/.sass-cache
|
||||
docs/js/*
|
||||
docs/downloads
|
||||
docs/downloads/*.zip
|
||||
docs/vendor/bundle
|
||||
examples/shared/*.js
|
||||
examples/**/bundle.js
|
||||
test/the-files-to-test.generated.js
|
||||
*.log*
|
||||
chrome-user-data
|
||||
|
||||
42
.travis.yml
42
.travis.yml
@@ -28,8 +28,8 @@ script:
|
||||
|
||||
GH_PAGES_DIR="$TRAVIS_BUILD_DIR"/../react-gh-pages
|
||||
echo "machine github.com login reactjs-bot password $GITHUB_TOKEN" >~/.netrc
|
||||
git config --global user.name "Travis CI"
|
||||
git config --global user.email "travis@reactjs.org"
|
||||
git config --global user.name "$GITHUB_USER_NAME"
|
||||
git config --global user.email "$GITHUB_USER_EMAIL"
|
||||
|
||||
git clone --branch gh-pages --depth=50 \
|
||||
https://reactjs-bot@github.com/facebook/react.git \
|
||||
@@ -39,7 +39,7 @@ script:
|
||||
bundle exec rake release
|
||||
cd $GH_PAGES_DIR
|
||||
git status
|
||||
if ! git diff-index --quiet HEAD --; then
|
||||
if test -n "$(git status --porcelain)"; then
|
||||
git add -A .
|
||||
git commit -m "Rebuild website"
|
||||
git push origin gh-pages
|
||||
@@ -71,20 +71,40 @@ script:
|
||||
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
|
||||
./node_modules/.bin/grunt jest:coverage
|
||||
cat ./coverage/lcov.info | ./node_modules/.bin/coveralls
|
||||
|
||||
echo 'Testing in server-render (HTML generation) mode...'
|
||||
printf '\nmodule.exports.useCreateElement = false;\n' \
|
||||
>> src/renderers/dom/shared/ReactDOMFeatureFlags.js
|
||||
./node_modules/.bin/grunt jest:normal
|
||||
git checkout -- src/renderers/dom/shared/ReactDOMFeatureFlags.js
|
||||
|
||||
echo 'Testing in fiber mode...'
|
||||
printf '\nmodule.exports.useFiber = true;\n' \
|
||||
>> src/renderers/dom/shared/ReactDOMFeatureFlags.js
|
||||
FIBER_TESTS=`\
|
||||
NODE_ENV=test node node_modules/jest/bin/jest --json | \
|
||||
node -e "\
|
||||
var data = JSON.parse(require('fs').readFileSync('/dev/stdin', 'utf8')); \
|
||||
console.log(data.numPassedTests + '/' + data.numTotalTests)\
|
||||
"\
|
||||
`
|
||||
git checkout -- src/renderers/dom/shared/ReactDOMFeatureFlags.js
|
||||
node scripts/facts-tracker/index.js \
|
||||
"fiber-tests" "$FIBER_TESTS"
|
||||
|
||||
./node_modules/.bin/gulp react:extract-errors
|
||||
elif [ "$TEST_TYPE" = flow ]; then
|
||||
set -e
|
||||
./node_modules/.bin/grunt flow
|
||||
|
||||
ALL_FILES=`find src -name '*.js' | grep -v umd/ | grep -v __tests__ | grep -v __mocks__`
|
||||
COUNT_ALL_FILES=`echo "$ALL_FILES" | wc -l`
|
||||
COUNT_WITH_FLOW=`grep '@flow' $ALL_FILES | perl -pe 's/:.+//' | wc -l`
|
||||
node scripts/facts-tracker/index.js \
|
||||
"flow-files" "$COUNT_WITH_FLOW/$COUNT_ALL_FILES"
|
||||
|
||||
else
|
||||
./node_modules/.bin/grunt $TEST_TYPE
|
||||
fi
|
||||
|
||||
52
CHANGELOG.md
52
CHANGELOG.md
@@ -1,3 +1,55 @@
|
||||
## 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
|
||||
|
||||
101
CONTRIBUTING.md
101
CONTRIBUTING.md
@@ -1,102 +1,5 @@
|
||||
# Contributing to React
|
||||
|
||||
React is one of Facebook's first open source projects that is both under very active development and is also being used to ship code to everybody on [facebook.com](https://www.facebook.com). We're still working out the kinks to make contributing to this project as easy and transparent as possible, but we're not quite there yet. Hopefully this document makes the process for contributing clear and answers some questions that you may have.
|
||||
Want to contribute to React? There are a few things you need to know.
|
||||
|
||||
## [Code of Conduct](https://code.facebook.com/codeofconduct)
|
||||
|
||||
Facebook has adopted a Code of Conduct that we expect project participants to adhere to. Please read [the full text](https://code.facebook.com/codeofconduct) so that you can understand what actions will and will not be tolerated.
|
||||
|
||||
## Our Development Process
|
||||
|
||||
Some of the core team will be working directly on GitHub. These changes will be public from the beginning. Other changesets will come via a bridge with Facebook's internal source control. This is a necessity as it allows engineers at Facebook outside of the core team to move fast and contribute from an environment they are comfortable in.
|
||||
|
||||
### `master` is unsafe
|
||||
|
||||
We will do our best to keep `master` in good shape, with tests passing at all times. But in order to move fast, we will make API changes that your application might not be compatible with. We will do our best to communicate these changes and always version appropriately so you can lock into a specific version if need be.
|
||||
|
||||
### Test Suite
|
||||
|
||||
Use `grunt test` to run the full test suite with PhantomJS.
|
||||
|
||||
This command is just a facade to [Jest](https://facebook.github.io/jest/). You may optionally run `npm install -g jest-cli` and use Jest commands directly to have more control over how tests are executed.
|
||||
|
||||
For example, `jest --watch` lets you automatically run the test suite on every file change.
|
||||
|
||||
You can also run a subset of tests by passing a prefix to `jest`. For instance, `jest ReactDOMSVG` will only run tests in the files that start with `ReactDOMSVG`, such as `ReactDOMSVG-test.js`.
|
||||
|
||||
When you know which tests you want to run, you can achieve a fast feedback loop by using these two features together. For example, `jest ReactDOMSVG --watch` will re-run only the matching tests on every change.
|
||||
|
||||
Just make sure to run the whole test suite before submitting a pull request!
|
||||
|
||||
### Pull Requests
|
||||
|
||||
**Working on your first Pull Request?** You can learn how from this *free* series [How to Contribute to an Open Source Project on GitHub](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github)
|
||||
|
||||
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.
|
||||
We wrote a **[contribution guide](https://facebook.github.io/react/contributing/how-to-contribute.html)** to help you get started.
|
||||
|
||||
38
Gruntfile.js
38
Gruntfile.js
@@ -117,12 +117,41 @@ module.exports = function(grunt) {
|
||||
'build-modules',
|
||||
'browserify:addonsMin',
|
||||
]);
|
||||
grunt.registerTask('build:dom', [
|
||||
'build-modules',
|
||||
'version-check',
|
||||
'browserify:dom',
|
||||
]);
|
||||
grunt.registerTask('build:dom-min', [
|
||||
'build-modules',
|
||||
'version-check',
|
||||
'browserify:domMin',
|
||||
]);
|
||||
grunt.registerTask('build:dom-server', [
|
||||
'build-modules',
|
||||
'version-check',
|
||||
'browserify:domServer',
|
||||
]);
|
||||
grunt.registerTask('build:dom-server-min', [
|
||||
'build-modules',
|
||||
'version-check',
|
||||
'browserify:domServerMin',
|
||||
]);
|
||||
grunt.registerTask('build:dom-fiber', [
|
||||
'build-modules',
|
||||
'version-check',
|
||||
'browserify:domFiber',
|
||||
]);
|
||||
grunt.registerTask('build:dom-fiber-min', [
|
||||
'build-modules',
|
||||
'version-check',
|
||||
'browserify:domFiberMin',
|
||||
]);
|
||||
grunt.registerTask('build:npm-react', [
|
||||
'version-check',
|
||||
'build-modules',
|
||||
'npm-react:release',
|
||||
]);
|
||||
grunt.registerTask('build:react-dom', require('./grunt/tasks/react-dom'));
|
||||
|
||||
var jestTasks = require('./grunt/tasks/jest');
|
||||
grunt.registerTask('jest:normal', jestTasks.normal);
|
||||
@@ -141,7 +170,12 @@ module.exports = function(grunt) {
|
||||
'browserify:addons',
|
||||
'browserify:min',
|
||||
'browserify:addonsMin',
|
||||
'build:react-dom',
|
||||
'browserify:dom',
|
||||
'browserify:domMin',
|
||||
'browserify:domServer',
|
||||
'browserify:domServerMin',
|
||||
'browserify:domFiber',
|
||||
'browserify:domFiberMin',
|
||||
'npm-react:release',
|
||||
'npm-react:pack',
|
||||
'npm-react-dom:release',
|
||||
|
||||
61
README.md
61
README.md
@@ -13,11 +13,11 @@ React is a JavaScript library for building user interfaces.
|
||||
We have several examples [on the website](https://facebook.github.io/react/). Here is the first one to get you started:
|
||||
|
||||
```js
|
||||
var HelloMessage = React.createClass({
|
||||
render: function() {
|
||||
class HelloMessage extends React.Component {
|
||||
render() {
|
||||
return <div>Hello {this.props.name}</div>;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ReactDOM.render(
|
||||
<HelloMessage name="John" />,
|
||||
@@ -31,16 +31,16 @@ You'll notice that we used an HTML-like syntax; [we call it JSX](https://faceboo
|
||||
|
||||
## Installation
|
||||
|
||||
The fastest way to get started is to serve JavaScript from 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):
|
||||
The fastest way to get started is to serve JavaScript from a CDN. We're using [unpkg](https://unpkg.com/) below but React is also available on [cdnjs](https://cdnjs.com/libraries/react) and [jsdelivr](https://www.jsdelivr.com/projects/react):
|
||||
|
||||
```html
|
||||
<!-- The core React library -->
|
||||
<script src="https://npmcdn.com/react@15.3.1/dist/react.js"></script>
|
||||
<script src="https://unpkg.com/react@15.4.0/dist/react.js"></script>
|
||||
<!-- The ReactDOM Library -->
|
||||
<script src="https://npmcdn.com/react-dom@15.3.1/dist/react-dom.js"></script>
|
||||
<script src="https://unpkg.com/react-dom@15.4.0/dist/react-dom.js"></script>
|
||||
```
|
||||
|
||||
We've also built a [starter kit](https://facebook.github.io/react/downloads/react-15.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.
|
||||
We've also built a [starter kit](https://facebook.github.io/react/downloads/react-15.4.0.zip) which might be useful if this is your first time using React. It includes a webpage with an example of using React with live code.
|
||||
|
||||
If you'd like to use [bower](http://bower.io), it's as easy as:
|
||||
|
||||
@@ -54,50 +54,17 @@ And it's just as easy with [npm](http://npmjs.com):
|
||||
npm i --save react
|
||||
```
|
||||
|
||||
## Contribute
|
||||
## Contributing
|
||||
|
||||
The main purpose of this repository is to continue to evolve React core, making it faster and easier to use. If you're interested in helping with that, then keep reading. If you're not interested in helping right now that's ok too. :) Any feedback you have about using React would be greatly appreciated.
|
||||
The main purpose of this repository is to continue to evolve React core, making it faster and easier to use. If you're interested in helping with that, check out our [contribution guide](https://facebook.github.io/react/contributing/how-to-contribute.html).
|
||||
|
||||
### Building Your Copy of React
|
||||
### [Code of Conduct](https://code.facebook.com/codeofconduct)
|
||||
|
||||
The process to build `react.js` is built entirely on top of node.js, using many libraries you may already be familiar with.
|
||||
|
||||
#### Prerequisites
|
||||
|
||||
* You have `node` installed at v4.0.0+ and `npm` at v2.0.0+.
|
||||
* You 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
|
||||
```
|
||||
Facebook has adopted a Code of Conduct that we expect project participants to adhere to. Please read [the full text](https://code.facebook.com/codeofconduct) so that you can understand what actions will and will not be tolerated.
|
||||
|
||||
### Good First Bug
|
||||
To help you get your feet wet and get you familiar with our contribution process, we have a list of [good first bugs](https://github.com/facebook/react/labels/good%20first%20bug) that contain bugs which are fairly easy to fix. This is a great place to get started.
|
||||
|
||||
To help you get your feet wet and get you familiar with our contribution process, we have a list of [good first bugs](https://github.com/facebook/react/labels/good%20first%20bug) that contain bugs which are fairly easy to fix. This is a great place to get started.
|
||||
|
||||
### License
|
||||
|
||||
@@ -107,9 +74,5 @@ React documentation is [Creative Commons licensed](./LICENSE-docs).
|
||||
|
||||
Examples provided in this repository and in the documentation are [separately licensed](./LICENSE-examples).
|
||||
|
||||
### More…
|
||||
|
||||
There's only so much we can cram in here. To read more about the community and guidelines for submitting pull requests, please read the [Contributing document](CONTRIBUTING.md).
|
||||
|
||||
## Troubleshooting
|
||||
See the [Troubleshooting Guide](https://github.com/facebook/react/wiki/Troubleshooting)
|
||||
|
||||
@@ -34,7 +34,7 @@ Use Jekyll to serve the website locally (by default, at `http://localhost:4000`)
|
||||
$ cd react/docs
|
||||
$ bundle exec rake
|
||||
$ bundle exec jekyll serve -w
|
||||
$ open http://localhost:4000/react/
|
||||
$ open http://localhost:4000/react/index.html
|
||||
```
|
||||
|
||||
We use [SASS](http://sass-lang.com/) (with [Bourbon](http://bourbon.io/)) for our CSS, and we use JSX to transform some of our JS.
|
||||
|
||||
@@ -6,8 +6,8 @@ require('open-uri')
|
||||
desc "download babel-browser"
|
||||
task :fetch_remotes do
|
||||
IO.copy_stream(
|
||||
open('https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.34/browser.min.js'),
|
||||
'js/babel-browser.min.js'
|
||||
open('https://unpkg.com/babel-standalone@6.15.0/babel.min.js'),
|
||||
'js/babel.min.js'
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
@@ -20,22 +20,29 @@ defaults:
|
||||
type: pages
|
||||
values:
|
||||
sectionid: blog
|
||||
- scope:
|
||||
path: tutorial
|
||||
type: pages
|
||||
values:
|
||||
layout: tutorial
|
||||
sectionid: tutorial
|
||||
- scope:
|
||||
path: docs
|
||||
type: pages
|
||||
values:
|
||||
layout: docs
|
||||
sectionid: docs
|
||||
- scope:
|
||||
path: tips
|
||||
type: pages
|
||||
values:
|
||||
sectionid: docs
|
||||
- scope:
|
||||
path: contributing
|
||||
type: pages
|
||||
values:
|
||||
sectionid: docs
|
||||
- scope:
|
||||
path: community
|
||||
type: pages
|
||||
values:
|
||||
layout: community
|
||||
sectionid: community
|
||||
exclude:
|
||||
- Gemfile
|
||||
- Gemfile.lock
|
||||
@@ -53,13 +60,13 @@ sass:
|
||||
gems:
|
||||
- jekyll-redirect-from
|
||||
- jekyll-paginate
|
||||
react_version: 15.3.0
|
||||
react_version: 15.3.2
|
||||
react_hashes:
|
||||
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
|
||||
dev: bQIyvl+8Ufi5KiKZPG9VItNWmhcAXA1pa5nHIEoBGob+rdbjJnpNV3s288Mz2yZu
|
||||
prod: drG4TSBgFQ0Hb/A3ynRyFDT22irpJDL+duuxvYD5mkC9adCYDqEwnX13371waqiH
|
||||
addons_dev: gCLxBq3yes/qREmjcw3Tdk5dUh3iB54huWqgxq1lAJZTYzLahJqEik5ZiVnq9Zt4
|
||||
addons_prod: pmUKSclxJREtkrfcUJvBYTEoJCvO6Vj5ob8IgPSiIX0G3c4w2dKBJMoGEhlv9Gev
|
||||
dom_dev: ZzFfcTbsRst34N23lWs6TtlfonXwDgpeALh+ObwYXav5BSo0j7KsaAtcdn+xrnS1
|
||||
dom_prod: MTxlP+/p3lyvc2+LZc2B5xy5reGwrA80whnflxNc6zPgLUmMvbwUoKy7qorBH+P4
|
||||
dom_server_dev: jHjmbawtj2AhVuJlmE/O1HXAIbQMzHvoXRZEVdhTSrfJXACRVpZm/BpuAi4K89xn
|
||||
dom_server_prod: LCYUMPll/9t/UsNa/Q1zfti2awxxiiczBUZcQBdeGACH0sU6BEAllZuGxo5b6/kf
|
||||
|
||||
@@ -112,8 +112,6 @@ li {
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
a {
|
||||
color: $linkColor;
|
||||
text-decoration: none;
|
||||
@@ -131,3 +129,7 @@ a {
|
||||
.center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
input {
|
||||
font-family: inherit;
|
||||
}
|
||||
|
||||
14
docs/_data/nav_community.yml
Normal file
14
docs/_data/nav_community.yml
Normal file
@@ -0,0 +1,14 @@
|
||||
- title: Community Resources
|
||||
items:
|
||||
- id: support
|
||||
title: Where To Get Support
|
||||
- id: conferences
|
||||
title: Conferences
|
||||
- id: videos
|
||||
title: Videos
|
||||
- id: complementary-tools
|
||||
title: Complementary Tools
|
||||
href: https://github.com/facebook/react/wiki/Complementary-Tools
|
||||
- id: examples
|
||||
title: Examples
|
||||
href: https://github.com/facebook/react/wiki/Examples
|
||||
@@ -1,4 +1,10 @@
|
||||
- title: Contributing
|
||||
items:
|
||||
- id: how-to-contribute
|
||||
title: How to Contribute
|
||||
- id: codebase-overview
|
||||
title: Codebase Overview
|
||||
- id: implementation-notes
|
||||
title: Implementation Notes
|
||||
- id: design-principles
|
||||
title: Design Principles
|
||||
|
||||
@@ -1,104 +1,84 @@
|
||||
- title: Quick Start
|
||||
items:
|
||||
- id: getting-started
|
||||
title: Getting Started
|
||||
- id: tutorial
|
||||
title: Tutorial
|
||||
- id: thinking-in-react
|
||||
title: Thinking in React
|
||||
- title: Community Resources
|
||||
- id: installation
|
||||
title: Installation
|
||||
- id: hello-world
|
||||
title: Hello World
|
||||
- id: introducing-jsx
|
||||
title: Introducing JSX
|
||||
- id: rendering-elements
|
||||
title: Rendering Elements
|
||||
- id: components-and-props
|
||||
title: Components and Props
|
||||
- id: state-and-lifecycle
|
||||
title: State and Lifecycle
|
||||
- id: handling-events
|
||||
title: Handling Events
|
||||
- id: conditional-rendering
|
||||
title: Conditional Rendering
|
||||
- id: lists-and-keys
|
||||
title: Lists and Keys
|
||||
- id: forms
|
||||
title: Forms
|
||||
- id: lifting-state-up
|
||||
title: Lifting State Up
|
||||
- id: composition-vs-inheritance
|
||||
title: Composition vs Inheritance
|
||||
- id: thinking-in-react
|
||||
title: Thinking In React
|
||||
- title: Advanced Guides
|
||||
items:
|
||||
- id: conferences
|
||||
title: Conferences
|
||||
- id: videos
|
||||
title: Videos
|
||||
- id: complementary-tools
|
||||
title: Complementary Tools
|
||||
href: https://github.com/facebook/react/wiki/Complementary-Tools
|
||||
- id: examples
|
||||
title: Examples
|
||||
href: https://github.com/facebook/react/wiki/Examples
|
||||
- title: Guides
|
||||
items:
|
||||
- id: why-react
|
||||
title: Why React?
|
||||
- id: displaying-data
|
||||
title: Displaying Data
|
||||
subitems:
|
||||
- id: jsx-in-depth
|
||||
title: JSX in Depth
|
||||
- id: jsx-spread
|
||||
title: JSX Spread Attributes
|
||||
- id: jsx-gotchas
|
||||
title: JSX Gotchas
|
||||
- id: interactivity-and-dynamic-uis
|
||||
title: Interactivity and Dynamic UIs
|
||||
- id: multiple-components
|
||||
title: Multiple Components
|
||||
- id: reusable-components
|
||||
title: Reusable Components
|
||||
- id: transferring-props
|
||||
title: Transferring Props
|
||||
- id: forms
|
||||
title: Forms
|
||||
- id: working-with-the-browser
|
||||
title: Working With the Browser
|
||||
subitems:
|
||||
- id: more-about-refs
|
||||
title: Refs to Components
|
||||
- id: tooling-integration
|
||||
title: Tooling Integration
|
||||
subitems:
|
||||
- id: language-tooling
|
||||
title: Language Tooling
|
||||
- id: package-management
|
||||
title: Package Management
|
||||
- id: environments
|
||||
title: Server-side Environments
|
||||
- id: addons
|
||||
title: Add-Ons
|
||||
subitems:
|
||||
- id: animation
|
||||
title: Animation
|
||||
- id: two-way-binding-helpers
|
||||
title: Two-Way Binding Helpers
|
||||
- id: test-utils
|
||||
title: Test Utilities
|
||||
- id: clone-with-props
|
||||
title: Cloning Elements
|
||||
- id: create-fragment
|
||||
title: Keyed Fragments
|
||||
- id: update
|
||||
title: Immutability Helpers
|
||||
- id: pure-render-mixin
|
||||
title: PureRenderMixin
|
||||
- id: perf
|
||||
title: Performance Tools
|
||||
- id: shallow-compare
|
||||
title: Shallow Compare
|
||||
- id: advanced-performance
|
||||
title: Advanced Performance
|
||||
- id: context
|
||||
title: Context
|
||||
title: JSX In Depth
|
||||
- id: typechecking-with-proptypes
|
||||
title: Typechecking With PropTypes
|
||||
- id: refs-and-the-dom
|
||||
title: Refs and the DOM
|
||||
- id: uncontrolled-components
|
||||
title: Uncontrolled Components
|
||||
- id: optimizing-performance
|
||||
title: Optimizing Performance
|
||||
- id: react-without-es6
|
||||
title: React Without ES6
|
||||
- id: react-without-jsx
|
||||
title: React Without JSX
|
||||
- id: reconciliation
|
||||
title: Reconciliation
|
||||
- id: context
|
||||
title: Context
|
||||
- id: web-components
|
||||
title: Web Components
|
||||
- title: Reference
|
||||
items:
|
||||
- id: top-level-api
|
||||
title: Top-Level API
|
||||
- id: component-api
|
||||
title: Component API
|
||||
- id: component-specs
|
||||
title: Component Specs and Lifecycle
|
||||
- id: tags-and-attributes
|
||||
title: Supported Tags and Attributes
|
||||
- id: events
|
||||
title: Event System
|
||||
- id: dom-differences
|
||||
title: DOM Differences
|
||||
- id: special-non-dom-attributes
|
||||
title: Special Non-DOM Attributes
|
||||
- id: reconciliation
|
||||
title: Reconciliation
|
||||
- id: webcomponents
|
||||
title: Web Components
|
||||
- id: glossary
|
||||
title: React (Virtual) DOM Terminology
|
||||
- id: react-api
|
||||
title: React
|
||||
subitems:
|
||||
- id: react-component
|
||||
title: React.Component
|
||||
- id: react-dom
|
||||
title: ReactDOM
|
||||
- id: react-dom-server
|
||||
title: ReactDOMServer
|
||||
- id: dom-elements
|
||||
title: DOM Elements
|
||||
- id: events
|
||||
title: SyntheticEvent
|
||||
- id: addons
|
||||
title: Add-Ons
|
||||
subitems:
|
||||
- id: perf
|
||||
title: Performance Tools
|
||||
- id: test-utils
|
||||
title: Test Utilities
|
||||
- id: animation
|
||||
title: Animation
|
||||
- id: create-fragment
|
||||
title: Keyed Fragments
|
||||
- id: update
|
||||
title: Immutability Helpers
|
||||
- id: pure-render-mixin
|
||||
title: PureRenderMixin
|
||||
- id: shallow-compare
|
||||
title: Shallow Compare
|
||||
- id: two-way-binding-helpers
|
||||
title: Two-way Binding Helpers
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
- title: Tips
|
||||
items:
|
||||
- id: introduction
|
||||
title: Introduction
|
||||
- id: inline-styles
|
||||
title: Inline Styles
|
||||
- id: if-else-in-JSX
|
||||
title: If-Else in JSX
|
||||
- id: self-closing-tag
|
||||
title: Self-Closing Tag
|
||||
- id: maximum-number-of-jsx-root-nodes
|
||||
title: Maximum Number of JSX Root Nodes
|
||||
- id: style-props-value-px
|
||||
title: Shorthand for Specifying Pixel Values in style props
|
||||
- id: children-props-type
|
||||
title: Type of the Children props
|
||||
- id: controlled-input-null-value
|
||||
title: Value of null for Controlled Input
|
||||
- id: componentWillReceiveProps-not-triggered-after-mounting
|
||||
title: componentWillReceiveProps Not Triggered After Mounting
|
||||
- id: props-in-getInitialState-as-anti-pattern
|
||||
title: Props in getInitialState Is an Anti-Pattern
|
||||
- id: dom-event-listeners
|
||||
title: DOM Event Listeners in a Component
|
||||
- id: initial-ajax
|
||||
title: Load Initial Data via AJAX
|
||||
- id: false-in-jsx
|
||||
title: False in JSX
|
||||
- id: communicate-between-components
|
||||
title: Communicate Between Components
|
||||
- id: expose-component-functions
|
||||
title: Expose Component Functions
|
||||
- id: children-undefined
|
||||
title: this.props.children undefined
|
||||
- id: use-react-with-other-libraries
|
||||
title: Use React with Other Libraries
|
||||
- id: dangerously-set-inner-html
|
||||
title: Dangerously Set innerHTML
|
||||
71
docs/_data/nav_tutorial.yml
Normal file
71
docs/_data/nav_tutorial.yml
Normal file
@@ -0,0 +1,71 @@
|
||||
- title: Tutorial
|
||||
items:
|
||||
- id: tutorial
|
||||
title: Overview
|
||||
subitems:
|
||||
- id: what-were-building
|
||||
title: What We're Building
|
||||
href: /react/tutorial/tutorial.html#what-were-building
|
||||
forceInternal: true
|
||||
- id: what-is-react
|
||||
title: What is React?
|
||||
href: /react/tutorial/tutorial.html#what-is-react
|
||||
forceInternal: true
|
||||
- id: getting-started
|
||||
title: Getting Started
|
||||
href: /react/tutorial/tutorial.html#getting-started
|
||||
forceInternal: true
|
||||
- id: passing-data-through-props
|
||||
title: Passing Data Through Props
|
||||
href: /react/tutorial/tutorial.html#passing-data-through-props
|
||||
forceInternal: true
|
||||
- id: an-interactive-component
|
||||
title: An Interactive Component
|
||||
href: /react/tutorial/tutorial.html#an-interactive-component
|
||||
forceInternal: true
|
||||
- id: developer-tools
|
||||
title: Developer Tools
|
||||
href: /react/tutorial/tutorial.html#developer-tools
|
||||
forceInternal: true
|
||||
- id: lifting-state-up
|
||||
title: Lifting State Up
|
||||
href: /react/tutorial/tutorial.html#lifting-state-up
|
||||
forceInternal: true
|
||||
subitems:
|
||||
- id: why-immutability-is-important
|
||||
title: Why Immutability Is Important
|
||||
href: /react/tutorial/tutorial.html#why-immutability-is-important
|
||||
forceInternal: true
|
||||
- id: functional-components
|
||||
title: Functional Components
|
||||
href: /react/tutorial/tutorial.html#functional-components
|
||||
forceInternal: true
|
||||
- id: taking-turns
|
||||
title: Taking Turns
|
||||
href: /react/tutorial/tutorial.html#taking-turns
|
||||
forceInternal: true
|
||||
- id: declaring-a-winner
|
||||
title: Declaring a Winner
|
||||
href: /react/tutorial/tutorial.html#declaring-a-winner
|
||||
forceInternal: true
|
||||
- id: storing-a-history
|
||||
title: Storing A History
|
||||
href: /react/tutorial/tutorial.html#storing-a-history
|
||||
forceInternal: true
|
||||
subitems:
|
||||
- id: showing-the-moves
|
||||
title: Showing the Moves
|
||||
href: /react/tutorial/tutorial.html#showing-the-moves
|
||||
forceInternal: true
|
||||
- id: keys
|
||||
title: Keys
|
||||
href: /react/tutorial/tutorial.html#keys
|
||||
forceInternal: true
|
||||
- id: implementing-time-travel
|
||||
title: Implementing Time Travel
|
||||
href: /react/tutorial/tutorial.html#implementing-time-travel
|
||||
forceInternal: true
|
||||
- id: wrapping-up
|
||||
title: Wrapping Up
|
||||
href: /react/tutorial/tutorial.html#wrapping-up
|
||||
forceInternal: true
|
||||
41
docs/_includes/footer.html
Normal file
41
docs/_includes/footer.html
Normal file
@@ -0,0 +1,41 @@
|
||||
<footer class="nav-footer">
|
||||
<section class="sitemap">
|
||||
<a href="/react/" class="nav-home">
|
||||
</a>
|
||||
<div>
|
||||
<h5><a href="/react/docs/">Docs</a></h5>
|
||||
<a href="/react/docs/hello-world.html">Quick Start</a>
|
||||
<a href="/react/docs/thinking-in-react.html">Thinking in React</a>
|
||||
<a href="/react/tutorial/tutorial.html">Tutorial</a>
|
||||
<a href="/react/docs/jsx-in-depth.html">Advanced Guides</a>
|
||||
</div>
|
||||
<div>
|
||||
<h5><a href="/react/community/support.html">Community</a></h5>
|
||||
<a href="http://stackoverflow.com/questions/tagged/reactjs" target="_blank">Stack Overflow</a>
|
||||
<a href="https://discuss.reactjs.org/" target="_blank">Discussion Forum</a>
|
||||
<a href="https://discord.gg/0ZcbPKXt5bZjGY5n" target="_blank">Reactiflux Chat</a>
|
||||
<a href="https://www.facebook.com/react" target="_blank">Facebook</a>
|
||||
<a href="https://twitter.com/reactjs" target="_blank">Twitter</a>
|
||||
</div>
|
||||
<div>
|
||||
<h5><a href="/react/community/support.html">Resources</a></h5>
|
||||
<a href="/react/community/conferences.html">Conferences</a>
|
||||
<a href="/react/community/videos.html">Videos</a>
|
||||
<a href="https://github.com/facebook/react/wiki/Examples" target="_blank">Examples</a>
|
||||
<a href="https://github.com/facebook/react/wiki/Complementary-Tools" target="_blank">Complementary Tools</a>
|
||||
</div>
|
||||
<div>
|
||||
<h5>More</h5>
|
||||
<a href="/react/blog/">Blog</a>
|
||||
<a href="https://github.com/facebook/react" target="_blank">GitHub</a>
|
||||
<a href="http://facebook.github.io/react-native/" target="_blank">React Native</a>
|
||||
<a href="/react/acknowledgements.html">Acknowledgements</a>
|
||||
</div>
|
||||
</section>
|
||||
<a href="https://code.facebook.com/projects/" target="_blank" class="fbOpenSource">
|
||||
<img src="/react/img/oss_logo.png" alt="Facebook Open Source" width="170" height="45"/>
|
||||
</a>
|
||||
<section class="copyright">
|
||||
Copyright © {{ site.time | date: '%Y' }} Facebook Inc.
|
||||
</section>
|
||||
</footer>
|
||||
13
docs/_includes/hero.html
Normal file
13
docs/_includes/hero.html
Normal file
@@ -0,0 +1,13 @@
|
||||
<div class="hero">
|
||||
<div class="wrap">
|
||||
<div class="text"><strong>React</strong></div>
|
||||
<div class="minitext">
|
||||
A JavaScript library for building user interfaces
|
||||
</div>
|
||||
|
||||
<div class="buttons-unit">
|
||||
<a href="/react/docs/hello-world.html" class="button">Get Started</a>
|
||||
<a href="/react/tutorial/tutorial.html" class="button">Take the Tutorial</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
24
docs/_includes/nav_community.html
Normal file
24
docs/_includes/nav_community.html
Normal file
@@ -0,0 +1,24 @@
|
||||
<div class="nav-docs">
|
||||
<!-- Community Nav -->
|
||||
{% for section in site.data.nav_community %}
|
||||
<div class="nav-docs-section">
|
||||
<h3>{{ section.title }}</h3>
|
||||
<ul>
|
||||
{% for item in section.items %}
|
||||
<li>
|
||||
{{ item | community_sidebar_link }}
|
||||
{% if item.subitems %}
|
||||
<ul>
|
||||
{% for subitem in item.subitems %}
|
||||
<li>
|
||||
{{ subitem | community_sidebar_link }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
@@ -6,12 +6,12 @@
|
||||
<ul>
|
||||
{% for item in section.items %}
|
||||
<li>
|
||||
{{ item | sidebar_item_link}}
|
||||
{{ item | docs_sidebar_link}}
|
||||
{% if item.subitems %}
|
||||
<ul>
|
||||
{% for subitem in item.subitems %}
|
||||
<li>
|
||||
{{ subitem | sidebar_item_link}}
|
||||
{{ subitem | docs_sidebar_link }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
@@ -22,20 +22,6 @@
|
||||
</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">
|
||||
@@ -49,4 +35,5 @@
|
||||
</ul>
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
</div>
|
||||
|
||||
24
docs/_includes/nav_tutorial.html
Normal file
24
docs/_includes/nav_tutorial.html
Normal file
@@ -0,0 +1,24 @@
|
||||
<div class="nav-docs">
|
||||
<!-- Tutorial Nav -->
|
||||
{% for section in site.data.nav_tutorial %}
|
||||
<div class="nav-docs-section">
|
||||
<h3>{{ section.title }}</h3>
|
||||
<ul>
|
||||
{% for item in section.items %}
|
||||
<li>
|
||||
{{ item | tutorial_sidebar_link }}
|
||||
{% if item.subitems %}
|
||||
<ul>
|
||||
{% for subitem in item.subitems %}
|
||||
<li>
|
||||
{{ subitem | tutorial_sidebar_link }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
23
docs/_includes/navigation.html
Normal file
23
docs/_includes/navigation.html
Normal file
@@ -0,0 +1,23 @@
|
||||
<div class="nav-main">
|
||||
<div class="wrap">
|
||||
<a class="nav-home" href="/react/">
|
||||
<img class="nav-logo" src="/react/img/logo.svg" width="36" height="36">
|
||||
React
|
||||
</a>
|
||||
<div class="nav-lists">
|
||||
<ul class="nav-site nav-site-internal">
|
||||
<li><a href="/react/docs/hello-world.html"{% if page.sectionid == 'docs' or page.sectionid == 'tips' or page.sectionid == 'contributing' %} class="active"{% endif %}>Docs</a></li>
|
||||
<li><a href="/react/tutorial/tutorial.html"{% if page.sectionid == 'tutorial' %} class="active"{% endif %}>Tutorial</a></li>
|
||||
<li><a href="/react/community/support.html"{% if page.sectionid == 'community' %} class="active"{% endif %}>Community</a></li>
|
||||
<li><a href="/react/blog/"{% if page.sectionid == 'blog' %} class="active"{% endif %}>Blog</a></li>
|
||||
<li class="nav-site-search">
|
||||
<input id="algolia-doc-search" type="text" placeholder="Search docs..." />
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="nav-site nav-site-external">
|
||||
<li><a href="https://github.com/facebook/react">GitHub</a></li>
|
||||
<li><a href="https://facebook.github.io/react-native/">React Native</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,12 +1,13 @@
|
||||
var name = Math.random() > 0.5 ? 'Jane' : 'John';
|
||||
var HELLO_COMPONENT = `
|
||||
var HelloMessage = React.createClass({
|
||||
render: function() {
|
||||
class HelloMessage extends React.Component {
|
||||
render() {
|
||||
return <div>Hello {this.props.name}</div>;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ReactDOM.render(<HelloMessage name="John" />, mountNode);
|
||||
`;
|
||||
ReactDOM.render(<HelloMessage name="${name}" />, mountNode);
|
||||
`.trim();
|
||||
|
||||
ReactDOM.render(
|
||||
<ReactPlayground codeText={HELLO_COMPONENT} />,
|
||||
|
||||
@@ -1,16 +1,21 @@
|
||||
var MARKDOWN_COMPONENT = `
|
||||
var MarkdownEditor = React.createClass({
|
||||
getInitialState: function() {
|
||||
return {value: 'Type some *markdown* here!'};
|
||||
},
|
||||
handleChange: function() {
|
||||
class MarkdownEditor extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.handleChange = this.handleChange.bind(this);
|
||||
this.state = {value: 'Type some *markdown* here!'};
|
||||
}
|
||||
|
||||
handleChange() {
|
||||
this.setState({value: this.refs.textarea.value});
|
||||
},
|
||||
rawMarkup: function() {
|
||||
}
|
||||
|
||||
getRawMarkup() {
|
||||
var md = new Remarkable();
|
||||
return { __html: md.render(this.state.value) };
|
||||
},
|
||||
render: function() {
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="MarkdownEditor">
|
||||
<h3>Input</h3>
|
||||
@@ -21,15 +26,15 @@ var MarkdownEditor = React.createClass({
|
||||
<h3>Output</h3>
|
||||
<div
|
||||
className="content"
|
||||
dangerouslySetInnerHTML={this.rawMarkup()}
|
||||
dangerouslySetInnerHTML={this.getRawMarkup()}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ReactDOM.render(<MarkdownEditor />, mountNode);
|
||||
`;
|
||||
`.trim();
|
||||
|
||||
ReactDOM.render(
|
||||
<ReactPlayground codeText={MARKDOWN_COMPONENT} />,
|
||||
|
||||
@@ -1,26 +1,33 @@
|
||||
var TIMER_COMPONENT = `
|
||||
var Timer = React.createClass({
|
||||
getInitialState: function() {
|
||||
return {secondsElapsed: 0};
|
||||
},
|
||||
tick: function() {
|
||||
this.setState({secondsElapsed: this.state.secondsElapsed + 1});
|
||||
},
|
||||
componentDidMount: function() {
|
||||
this.interval = setInterval(this.tick, 1000);
|
||||
},
|
||||
componentWillUnmount: function() {
|
||||
class Timer extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {secondsElapsed: 0};
|
||||
}
|
||||
|
||||
tick() {
|
||||
this.setState((prevState) => ({
|
||||
secondsElapsed: prevState.secondsElapsed + 1
|
||||
}));
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.interval = setInterval(() => this.tick(), 1000);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
clearInterval(this.interval);
|
||||
},
|
||||
render: function() {
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>Seconds Elapsed: {this.state.secondsElapsed}</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ReactDOM.render(<Timer />, mountNode);
|
||||
`;
|
||||
`.trim();
|
||||
|
||||
ReactDOM.render(
|
||||
<ReactPlayground codeText={TIMER_COMPONENT} />,
|
||||
|
||||
@@ -1,41 +1,56 @@
|
||||
var TODO_COMPONENT = `
|
||||
var TodoList = React.createClass({
|
||||
render: function() {
|
||||
var createItem = function(item) {
|
||||
return <li key={item.id}>{item.text}</li>;
|
||||
};
|
||||
return <ul>{this.props.items.map(createItem)}</ul>;
|
||||
class TodoApp extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.handleChange = this.handleChange.bind(this);
|
||||
this.handleSubmit = this.handleSubmit.bind(this);
|
||||
this.state = {items: [], text: ''};
|
||||
}
|
||||
});
|
||||
var TodoApp = React.createClass({
|
||||
getInitialState: function() {
|
||||
return {items: [], text: ''};
|
||||
},
|
||||
onChange: function(e) {
|
||||
this.setState({text: e.target.value});
|
||||
},
|
||||
handleSubmit: function(e) {
|
||||
e.preventDefault();
|
||||
var nextItems = this.state.items.concat([{text: this.state.text, id: Date.now()}]);
|
||||
var nextText = '';
|
||||
this.setState({items: nextItems, text: nextText});
|
||||
},
|
||||
render: function() {
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<h3>TODO</h3>
|
||||
<TodoList items={this.state.items} />
|
||||
<form onSubmit={this.handleSubmit}>
|
||||
<input onChange={this.onChange} value={this.state.text} />
|
||||
<input onChange={this.handleChange} value={this.state.text} />
|
||||
<button>{'Add #' + (this.state.items.length + 1)}</button>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
handleChange(e) {
|
||||
this.setState({text: e.target.value});
|
||||
}
|
||||
|
||||
handleSubmit(e) {
|
||||
e.preventDefault();
|
||||
var newItem = {
|
||||
text: this.state.text,
|
||||
id: Date.now()
|
||||
};
|
||||
this.setState((prevState) => ({
|
||||
items: prevState.items.concat(newItem),
|
||||
text: ''
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
class TodoList extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<ul>
|
||||
{this.props.items.map(item => (
|
||||
<li key={item.id}>{item.text}</li>
|
||||
))}
|
||||
</ul>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ReactDOM.render(<TodoApp />, mountNode);
|
||||
`;
|
||||
`.trim();
|
||||
|
||||
ReactDOM.render(
|
||||
<ReactPlayground codeText={TODO_COMPONENT} />,
|
||||
|
||||
@@ -90,8 +90,14 @@ var ReactPlayground = React.createClass({
|
||||
|
||||
getDefaultProps: function() {
|
||||
return {
|
||||
transformer: function(code) {
|
||||
return babel.transform(code).code;
|
||||
transformer: function(code, options) {
|
||||
var presets = ['react'];
|
||||
if (!options || !options.skipES2015Transform) {
|
||||
presets.push('es2015');
|
||||
}
|
||||
return Babel.transform(code, {
|
||||
presets
|
||||
}).code;
|
||||
},
|
||||
editorTabTitle: 'Live JSX Editor',
|
||||
showCompiledJSTab: true,
|
||||
@@ -115,15 +121,15 @@ var ReactPlayground = React.createClass({
|
||||
this.setState({mode: mode});
|
||||
},
|
||||
|
||||
compileCode: function() {
|
||||
return this.props.transformer(this.state.code);
|
||||
compileCode: function(options) {
|
||||
return this.props.transformer(this.state.code, options);
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var isJS = this.state.mode === this.MODES.JS;
|
||||
var compiledCode = '';
|
||||
try {
|
||||
compiledCode = this.compileCode();
|
||||
compiledCode = this.compileCode({skipES2015Transform: true});
|
||||
} catch (err) {}
|
||||
|
||||
var JSContent =
|
||||
@@ -201,13 +207,15 @@ var ReactPlayground = React.createClass({
|
||||
} catch (e) { }
|
||||
|
||||
try {
|
||||
var compiledCode = this.compileCode();
|
||||
var compiledCode;
|
||||
if (this.props.renderCode) {
|
||||
compiledCode = this.compileCode({skipES2015Transform: true});
|
||||
ReactDOM.render(
|
||||
<CodeMirrorEditor codeText={compiledCode} readOnly={true} />,
|
||||
mountNode
|
||||
);
|
||||
} else {
|
||||
compiledCode = this.compileCode({skipES2015Transform: false});
|
||||
eval(compiledCode);
|
||||
}
|
||||
} catch (err) {
|
||||
|
||||
29
docs/_layouts/community.html
Normal file
29
docs/_layouts/community.html
Normal file
@@ -0,0 +1,29 @@
|
||||
---
|
||||
layout: default
|
||||
sectionid: community
|
||||
---
|
||||
|
||||
<section class="content wrap communityContent">
|
||||
<div class="inner-content">
|
||||
<a class="edit-page-link"
|
||||
href="https://github.com/facebook/react/tree/master/docs/{{ page.path }}"
|
||||
target="_blank">Edit on GitHub</a>
|
||||
<h1>
|
||||
{{ page.title }}
|
||||
</h1>
|
||||
<div class="subHeader">{{ page.description }}</div>
|
||||
|
||||
{{ content }}
|
||||
|
||||
<div class="docs-prevnext">
|
||||
{% if page.prev %}
|
||||
<a class="docs-prev" href="/react/community/{{ page.prev }}">← Prev</a>
|
||||
{% endif %}
|
||||
{% if page.next %}
|
||||
<a class="docs-next" href="/react/community/{{ page.next }}">Next →</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% include nav_community.html %}
|
||||
</section>
|
||||
@@ -4,8 +4,6 @@ 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>
|
||||
@@ -20,4 +18,6 @@ sectionid: contributing
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% include nav_docs.html %}
|
||||
</section>
|
||||
|
||||
@@ -1,16 +1,26 @@
|
||||
{% if page.excerpt %}
|
||||
{% assign type = 'article' %}
|
||||
{% assign sectionTitle = 'React Blog' %}
|
||||
{% assign description = page.excerpt | remove: '<p>' | remove: '</p>' %}
|
||||
{% else %}
|
||||
{% assign type = 'website' %}
|
||||
{% assign sectionTitle = 'React' %}
|
||||
{% assign description = 'A JavaScript library for building user interfaces' %}
|
||||
{% endif %}
|
||||
{% assign title = page.title | append: ' - ' | append: sectionTitle %}
|
||||
<!DOCTYPE html>
|
||||
<!--[if IE]><![endif]-->
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<title>{{ page.title }} | React</title>
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<meta property="og:title" content="{{ page.title }} | React">
|
||||
<meta property="og:type" content="website">
|
||||
<title>{{ title }}</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta property="og:title" content="{{ title }}">
|
||||
<meta property="og:type" content="{{ type }}">
|
||||
<meta property="og:url" content="https://facebook.github.io/react{{ page.url }}">
|
||||
<meta property="og:image" content="https://facebook.github.io/react/img/logo_og.png">
|
||||
<meta property="og:description" content="A JavaScript library for building user interfaces">
|
||||
<meta property="og:description" content="{{ description }}">
|
||||
<meta property="fb:app_id" content="623268441017527">
|
||||
|
||||
<link rel="shortcut icon" href="/react/favicon.ico">
|
||||
@@ -36,67 +46,21 @@
|
||||
<script src="/react/js/jsx.js"></script>
|
||||
<script src="/react/js/react.js"></script>
|
||||
<script src="/react/js/react-dom.js"></script>
|
||||
<script src="/react/js/babel-browser.min.js"></script>
|
||||
<script src="/react/js/babel.min.js"></script>
|
||||
<script src="/react/js/live_editor.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="container">
|
||||
|
||||
<div class="nav-main">
|
||||
<div class="wrap">
|
||||
<a class="nav-home" href="/react/index.html">
|
||||
<img class="nav-logo" src="/react/img/logo.svg" width="36" height="36">
|
||||
React
|
||||
</a>
|
||||
<ul class="nav-site nav-site-internal">
|
||||
<li><a href="/react/docs/getting-started.html"{% if page.sectionid == 'docs' or page.sectionid == 'tips' 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 %}
|
||||
{% include navigation.html %}
|
||||
|
||||
{{ content }}
|
||||
|
||||
<footer class="wrap">
|
||||
<div class="left">
|
||||
A Facebook & Instagram collaboration.<br>
|
||||
<a href="/react/acknowledgements.html">Acknowledgements</a>
|
||||
</div>
|
||||
<div class="right">
|
||||
© 2013–{{ site.time | date: '%Y' }} Facebook Inc.<br>
|
||||
Documentation licensed under <a href="https://creativecommons.org/licenses/by/4.0/">CC BY 4.0</a>.
|
||||
</div>
|
||||
</footer>
|
||||
{% include footer.html %}
|
||||
</div>
|
||||
<div id="fb-root"></div>
|
||||
|
||||
<div id="fb-root"></div>
|
||||
<script>
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||
|
||||
@@ -4,8 +4,6 @@ sectionid: docs
|
||||
---
|
||||
|
||||
<section class="content wrap documentationContent">
|
||||
{% include nav_docs.html %}
|
||||
|
||||
<div class="inner-content">
|
||||
<a class="edit-page-link" href="https://github.com/facebook/react/tree/master/docs/{{ page.path }}" target="_blank">Edit on GitHub</a>
|
||||
<h1>
|
||||
@@ -24,4 +22,6 @@ sectionid: docs
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% include nav_docs.html %}
|
||||
</section>
|
||||
|
||||
11
docs/_layouts/hero.html
Normal file
11
docs/_layouts/hero.html
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
layout: default
|
||||
---
|
||||
|
||||
{% if page.id == 'home' %}
|
||||
{% include hero.html %}
|
||||
{% endif %}
|
||||
|
||||
<section class="content wrap">
|
||||
{{ content }}
|
||||
</section>
|
||||
@@ -4,8 +4,9 @@ sectionid: blog
|
||||
---
|
||||
|
||||
<section class="content wrap blogContent">
|
||||
{% include nav_blog.html %}
|
||||
|
||||
<div class="inner-content">
|
||||
{% include blog_post.html isPermalink="true" page=page content=content %}
|
||||
</div>
|
||||
{% include nav_blog.html %}
|
||||
</section>
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
---
|
||||
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>
|
||||
29
docs/_layouts/tutorial.html
Normal file
29
docs/_layouts/tutorial.html
Normal file
@@ -0,0 +1,29 @@
|
||||
---
|
||||
layout: default
|
||||
sectionid: tutorial
|
||||
---
|
||||
|
||||
<section class="content wrap documentationContent">
|
||||
{% include nav_tutorial.html %}
|
||||
|
||||
<div class="inner-content">
|
||||
<a class="edit-page-link"
|
||||
href="https://github.com/facebook/react/tree/master/docs/{{ page.path }}"
|
||||
target="_blank">Edit on GitHub</a>
|
||||
<h1>
|
||||
{{ page.title }}
|
||||
</h1>
|
||||
<div class="subHeader">{{ page.description }}</div>
|
||||
|
||||
{{ content }}
|
||||
|
||||
<div class="docs-prevnext">
|
||||
{% if page.prev %}
|
||||
<a class="docs-prev" href="/react/tutorial/{{ page.prev }}">← Prev</a>
|
||||
{% endif %}
|
||||
{% if page.next %}
|
||||
<a class="docs-next" href="/react/tutorial/{{ page.next }}">Next →</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -1,20 +1,39 @@
|
||||
module Jekyll
|
||||
module SidebarItemFilter
|
||||
def sidebar_item_link(item)
|
||||
def docs_sidebar_link(item)
|
||||
return sidebar_helper(item, 'docs')
|
||||
end
|
||||
|
||||
def docs_old_sidebar_link(item)
|
||||
return sidebar_helper(item, 'docs-old')
|
||||
end
|
||||
|
||||
def community_sidebar_link(item)
|
||||
return sidebar_helper(item, 'community')
|
||||
end
|
||||
|
||||
def tutorial_sidebar_link(item)
|
||||
return sidebar_helper(item, 'tutorial')
|
||||
end
|
||||
|
||||
def sidebar_helper(item, group)
|
||||
forceInternal = item["forceInternal"]
|
||||
|
||||
pageID = @context.registers[:page]["id"]
|
||||
itemID = item["id"]
|
||||
href = item["href"] || "/react/docs/#{itemID}.html"
|
||||
href = item["href"] || "/react/#{group}/#{itemID}.html"
|
||||
classes = []
|
||||
if pageID == itemID
|
||||
classes.push("active")
|
||||
end
|
||||
if item["href"]
|
||||
if item["href"] && (forceInternal == nil)
|
||||
classes.push("external")
|
||||
end
|
||||
className = classes.size > 0 ? " class=\"#{classes.join(' ')}\"" : ""
|
||||
|
||||
return "<a href=\"#{href}\"#{className}>#{item["title"]}</a>"
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ to the DOM.
|
||||
> lightweight description of what the DOM should look like.
|
||||
|
||||
We call this process **reconciliation**. Check out
|
||||
[this jsFiddle](http://jsfiddle.net/fv6RD/3/) to see an example of
|
||||
[this jsFiddle](http://jsfiddle.net/2h6th4ju/) to see an example of
|
||||
reconciliation in action.
|
||||
|
||||
Because this re-render is so fast (around 1ms for TodoMVC), the developer
|
||||
|
||||
@@ -47,7 +47,7 @@ Over the past several weeks, members of our team, [Pete Hunt](http://www.petehun
|
||||
|
||||
[Pete Hunt](http://www.petehunt.net/) recorded himself implementing a simple `<Blink>` tag in React.
|
||||
|
||||
<figure><iframe src="https://player.vimeo.com/video/67248575" width="500" height="340" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe></figure>
|
||||
<figure><iframe src="https://player.vimeo.com/video/67248575" width="100%" height="340" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe></figure>
|
||||
|
||||
## Snake in React
|
||||
|
||||
|
||||
@@ -68,14 +68,14 @@ React.renderComponent(
|
||||
|
||||
[Domenic Denicola](http://domenicdenicola.com/) wrote a slide deck about the great applications of ES6 features and one slide shows how we could use Template Strings to compile JSX at run-time without the need for a pre-processing phase.
|
||||
|
||||
<figure><iframe src="https://www.slideshare.net/slideshow/embed_code/24187146?rel=0&startSlide=36" width="600" height="356" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC;border-width:1px 1px 0;margin-bottom:5px" allowfullscreen webkitallowfullscreen mozallowfullscreen> </iframe></figure>
|
||||
<figure><iframe src="https://www.slideshare.net/slideshow/embed_code/24187146?rel=0&startSlide=36" width="100%" height="356" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC;border-width:1px 1px 0;margin-bottom:5px" allowfullscreen webkitallowfullscreen mozallowfullscreen> </iframe></figure>
|
||||
|
||||
|
||||
## React Presentation
|
||||
|
||||
[Tom Occhino](http://tomocchino.com/) and [Jordan Walke](https://github.com/jordwalke), React developers, did a presentation of React at Facebook Seattle's office. Check out the first 25 minutes for the presentation and the remaining 45 for a Q&A. I highly recommend you watching this video.
|
||||
|
||||
<figure><iframe width="650" height="400" src="//www.youtube-nocookie.com/embed/XxVg_s8xAms" frameborder="0" allowfullscreen></iframe></figure>
|
||||
<figure><iframe width="100%" height="400" src="//www.youtube-nocookie.com/embed/XxVg_s8xAms" frameborder="0" allowfullscreen></iframe></figure>
|
||||
|
||||
|
||||
## Docs
|
||||
|
||||
@@ -29,7 +29,7 @@ We organized a React hackathon last week-end in the Facebook Seattle office. 50
|
||||
|
||||
The video will be available soon on the [JSConf EU website](http://2013.jsconf.eu/speakers/pete-hunt-react-rethinking-best-practices.html), but in the meantime, here are Pete's slides:
|
||||
|
||||
<figure><iframe src="https://www.slideshare.net/slideshow/embed_code/26589373" width="550" height="450" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" allowfullscreen></iframe></figure>
|
||||
<figure><iframe src="https://www.slideshare.net/slideshow/embed_code/26589373" width="100%" height="450" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" allowfullscreen></iframe></figure>
|
||||
|
||||
|
||||
## Pump - Clojure bindings for React
|
||||
@@ -96,4 +96,3 @@ var Table = React.createClass({
|
||||
> You see that React components are defined using a regular JS object. Some properties and methods of the object such as render() have special meanings, the rest is upforgrabs.
|
||||
>
|
||||
> [Read the full article...](http://www.phpied.com/reactive-table/)
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ The best part is that no drastic changes have been required to support all those
|
||||
|
||||
[Pete Hunt](http://www.petehunt.net/)'s talk at JSConf EU 2013 is now available in video.
|
||||
|
||||
<figure><iframe width="600" height="370" src="//www.youtube-nocookie.com/embed/x7cQ3mrcKaY" frameborder="0" allowfullscreen></iframe></figure>
|
||||
<figure><iframe width="100%" height="370" src="//www.youtube-nocookie.com/embed/x7cQ3mrcKaY" frameborder="0" allowfullscreen></iframe></figure>
|
||||
|
||||
|
||||
## Server-side React with PHP
|
||||
|
||||
@@ -9,7 +9,7 @@ This round-up is the proof that React has taken off from its Facebook's root: it
|
||||
|
||||
[Steve Luscher](https://github.com/steveluscher) working at [LeanPub](https://leanpub.com/) made a 30 min talk at [Super VanJS](https://twitter.com/vanjs). He does a remarkable job at explaining why React is so fast with very exciting demos using the HTML5 Audio API.
|
||||
|
||||
<figure><iframe width="600" height="338" src="//www.youtube-nocookie.com/embed/1OeXsL5mr4g" frameborder="0" allowfullscreen></iframe></figure>
|
||||
<figure><iframe width="100%" height="338" src="//www.youtube-nocookie.com/embed/1OeXsL5mr4g" frameborder="0" allowfullscreen></iframe></figure>
|
||||
|
||||
|
||||
## React Tips
|
||||
@@ -64,7 +64,7 @@ This round-up is the proof that React has taken off from its Facebook's root: it
|
||||
>
|
||||
> [Read the full article...](http://rz.scale-it.pl/2013/10/20/frontend_components_in_react.html)
|
||||
|
||||
<figure><iframe src="https://docs.google.com/presentation/d/1JSFbjCuuexwOHCeHWBMNRIJdyfD2Z0ZQwX65WOWkfaI/embed?start=false" frameborder="0" width="600" height="468" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"> </iframe></figure>
|
||||
<figure><iframe src="https://docs.google.com/presentation/d/1JSFbjCuuexwOHCeHWBMNRIJdyfD2Z0ZQwX65WOWkfaI/embed?start=false" frameborder="0" width="100%" height="468" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"> </iframe></figure>
|
||||
|
||||
|
||||
## JSX
|
||||
|
||||
@@ -10,7 +10,7 @@ Happy holidays! This blog post is a little-late Christmas present for all the Re
|
||||
|
||||
[Pete Hunt](http://www.petehunt.net/) wrote three demos showing that React can be used to run 60fps native-like experiences on mobile web. A frosted glass effect, an image gallery with 3d animations and an infinite scroll view.
|
||||
|
||||
<figure><iframe src="//player.vimeo.com/video/79659941" width="220" height="400" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe></figure>
|
||||
<figure><iframe src="//player.vimeo.com/video/79659941" width="100%" height="400" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe></figure>
|
||||
|
||||
[Try out the demos!](https://petehunt.github.io/react-touch/)
|
||||
|
||||
@@ -19,7 +19,7 @@ Happy holidays! This blog post is a little-late Christmas present for all the Re
|
||||
|
||||
[Stoyan Stefanov](http://www.phpied.com/) talked at Joe Dev On Tech about React. He goes over all the features of the library and ends with a concrete example.
|
||||
|
||||
<figure><iframe width="560" height="315" src="//www.youtube-nocookie.com/embed/SMMRJif5QW0" frameborder="0" allowfullscreen></iframe></figure>
|
||||
<figure><iframe width="100%" height="315" src="//www.youtube-nocookie.com/embed/SMMRJif5QW0" frameborder="0" allowfullscreen></iframe></figure>
|
||||
|
||||
|
||||
## JSX: E4X The Good Parts
|
||||
@@ -115,4 +115,3 @@ var MyComponent = React.createClass({
|
||||
## Random Tweet
|
||||
|
||||
<center><blockquote class="twitter-tweet" lang="en"><p>I may be starting to get annoying with this, but ReactJS is really exciting. I truly feel the virtual DOM is a game changer.</p>— Eric Florenzano (@ericflo) <a href="https://twitter.com/ericflo/statuses/413842834974732288">December 20, 2013</a></blockquote></center>
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ author: sebmarkbage
|
||||
|
||||
With the new year, we thought you'd enjoy some new tools for debugging React code. Today we're releasing the [React Developer Tools](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi), an extension to the Chrome Developer Tools. [Download them from the Chrome Web Store](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi).
|
||||
|
||||
<figure><iframe width="560" height="315" src="//www.youtube-nocookie.com/embed/Cey7BS6dE0M" frameborder="0" allowfullscreen></iframe></figure>
|
||||
<figure><iframe width="100%" height="315" src="//www.youtube-nocookie.com/embed/Cey7BS6dE0M" frameborder="0" allowfullscreen></iframe></figure>
|
||||
|
||||
You will get a new tab titled "React" in your Chrome DevTools. This tab shows you a list of the root React Components that are rendered on the page as well as the subcomponents that each root renders.
|
||||
|
||||
@@ -15,4 +15,3 @@ When you inspect a DOM element using the regular Elements tab, you can switch ov
|
||||
<figure>[](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi)</figure>
|
||||
|
||||
We hope these tools will help your team better understand your component hierarchy and track down bugs. We're very excited about this initial launch and appreciate any feedback you may have. As always, we also accept [pull requests on GitHub](https://github.com/facebook/react-devtools).
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ React is only one-piece of your web application stack. [Mark Lussier](https://gi
|
||||
|
||||
## React Rails Tutorial
|
||||
|
||||
[Selem Delul](http://selem.im) bundled the [React Tutorial](/react/docs/tutorial.html) into a rails app. This is a good example on how to get started with a rails project.
|
||||
[Selem Delul](http://selem.im) bundled the [React Tutorial](/react/tutorial/tutorial.html) into a rails app. This is a good example on how to get started with a rails project.
|
||||
|
||||
> ```
|
||||
git clone https://github.com/necrodome/react-rails-tutorial
|
||||
|
||||
@@ -34,7 +34,7 @@ React's one-way data-binding naturally lends itself to a functional programming
|
||||
|
||||
Pete also explains this in detail at his #MeteorDevShop talk (about 30 Minutes):
|
||||
|
||||
<iframe width="560" height="315" src="//www.youtube-nocookie.com/embed/Lqcs6hPOcFw?start=2963" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="315" src="//www.youtube-nocookie.com/embed/Lqcs6hPOcFw?start=2963" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ There have been many posts recently covering the <i>why</i> and <i>how</i> of Re
|
||||
## React in a nutshell
|
||||
Got five minutes to pitch React to your coworkers? John Lynch ([@johnrlynch](https://twitter.com/johnrlynch)) put together [this excellent and refreshing slideshow](http://slid.es/johnlynch/reactjs):
|
||||
|
||||
<iframe src="//slid.es/johnlynch/reactjs/embed" width="576" height="420" scrolling="no" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
|
||||
<iframe src="//slid.es/johnlynch/reactjs/embed" width="100%" height="420" scrolling="no" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ Rafał Cieślak ([@Ravicious](https://twitter.com/Ravicious)) wrote a [React ver
|
||||
|
||||
Emanuele shared this awesome demo video with us:
|
||||
|
||||
<iframe width="560" height="315" src="//www.youtube-nocookie.com/embed/jYcpaemt90M" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="315" src="//www.youtube-nocookie.com/embed/jYcpaemt90M" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ Ian Bicking ([@ianbicking](https://twitter.com/ianbicking)) of Mozilla Labs [exp
|
||||
|
||||
React was also recently mentioned at ng-conf, where the Angular team commented on React's concept of the virtual DOM:
|
||||
|
||||
<iframe width="560" height="315" src="//www.youtube-nocookie.com/embed/srt3OBP2kGc?start=113" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="315" src="//www.youtube-nocookie.com/embed/srt3OBP2kGc?start=113" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
## React and Web Components
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ author: [fisherwebdev, jingc]
|
||||
|
||||
We recently spoke at one of f8's breakout session about Flux, a data flow architecture that works well with React. Check out the video here:
|
||||
|
||||
<figure><iframe width="560" height="315" src="//www.youtube-nocookie.com/embed/nYkdrAPrdcw?list=PLb0IAmt7-GS188xDYE-u1ShQmFFGbrk0v&start=621" frameborder="0" allowfullscreen></iframe></figure>
|
||||
<figure><iframe width="100%" height="315" src="//www.youtube-nocookie.com/embed/nYkdrAPrdcw?list=PLb0IAmt7-GS188xDYE-u1ShQmFFGbrk0v&start=621" frameborder="0" allowfullscreen></iframe></figure>
|
||||
|
||||
To summarize, Flux works well for us because the single directional data flow makes it easy to understand and modify an application as it becomes more complicated. We found that two-way data bindings lead to cascading updates, where changing one data model led to another data model updating, making it very difficult to predict what would change as the result of a single user interaction.
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ These are some of the links that often pop up on the #reactjs IRC channel. If yo
|
||||
|
||||
The core concepts React themselves is something very valuable that the community is exploring and pushing further. A year ago, we wouldn't have imagined something like [Bruce Hauman](http://rigsomelight.com)'s [Flappy Bird ClojureScript port](http://rigsomelight.com/2014/05/01/interactive-programming-flappy-bird-clojurescript.html), whose interactive programming has been made possible through React:
|
||||
|
||||
<iframe width="560" height="315" src="//www.youtube-nocookie.com/embed/KZjFVdU8VLI" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="315" src="//www.youtube-nocookie.com/embed/KZjFVdU8VLI" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
And don't forget [Pete Hunt](https://github.com/petehunt)'s Wolfenstein 3D rendering engine in React ([source code](https://github.com/petehunt/wolfenstein3D-react/blob/master/js/renderer.js#L183)). While it's nearly a year old, it's still a nice demo.
|
||||
|
||||
|
||||
@@ -16,14 +16,14 @@ It's an exciting time for React as there are now more commits from open source c
|
||||
|
||||
At the last [JSConf.us](http://2014.jsconf.us/), Vjeux talked about the design decisions made in the API that allows it to scale to a large number of developers. If you don't have 20 minutes, take a look at the [annotated slides](https://speakerdeck.com/vjeux/why-does-react-scale-jsconf-2014).
|
||||
|
||||
<iframe width="650" height="315" src="//www.youtube-nocookie.com/embed/D-ioDiacTm8" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="315" src="//www.youtube-nocookie.com/embed/D-ioDiacTm8" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
|
||||
## Live Editing
|
||||
|
||||
One of the best features of React is that it provides the foundations to implement concepts that were otherwise extremely difficult, like server-side rendering, undo-redo, rendering to non-DOM environments like canvas... [Dan Abramov](https://twitter.com/dan_abramov) got hot code reloading working with webpack in order to [live edit a React project](https://gaearon.github.io/react-hot-loader/)!
|
||||
|
||||
<iframe src="//player.vimeo.com/video/100010922" width="650" height="315" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
|
||||
<iframe src="//player.vimeo.com/video/100010922" width="100%" height="315" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
|
||||
|
||||
|
||||
## ReactIntl Mixin by Yahoo
|
||||
@@ -63,7 +63,7 @@ If you missed the last [London React Meetup](http://www.meetup.com/London-React-
|
||||
- React on Rails - How to use React with Ruby on Rails to build isomorphic apps
|
||||
- Building an isomorphic, real-time to-do list with moped and node.js
|
||||
|
||||
<iframe width="650" height="315" src="//www.youtube-nocookie.com/embed/CP3lvm5Ppqo" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="315" src="//www.youtube-nocookie.com/embed/CP3lvm5Ppqo" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
In related news, the next [React SF Meetup](http://www.meetup.com/ReactJS-San-Francisco/events/195518392/) will be from Prezi: [“Immediate Mode on the Web: How We Implemented the Prezi Viewer in JavaScript”](https://medium.com/prezi-engineering/how-and-why-prezi-turned-to-javascript-56e0ca57d135). While not in React, their tech is really awesome and shares a lot of React's design principles and perf optimizations.
|
||||
|
||||
|
||||
@@ -104,7 +104,7 @@ var parsedComponent = reactParser(html, React);
|
||||
|
||||
If you haven't yet tried out React, Jacob Rios did a Hangout where he covers the most important aspects and thankfully he recorded it!
|
||||
|
||||
<iframe width="650" height="315" src="//www.youtube-nocookie.com/embed/lAn7GVoGlKU" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="315" src="//www.youtube-nocookie.com/embed/lAn7GVoGlKU" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
|
||||
## Random Tweets
|
||||
|
||||
@@ -20,7 +20,7 @@ This has been an exciting summer as four big companies: Yahoo, Mozilla, Airbnb a
|
||||
|
||||
[Vjeux](http://blog.vjeux.com/), from the React team, gave a talk at OSCON on the history of React and the various optimizations strategies that are implemented. You can also check out the [annotated slides](https://speakerdeck.com/vjeux/oscon-react-architecture) or [Chris Dawson](http://thenewstack.io/author/chrisdawson/)'s notes titled [JavaScript’s History and How it Led To React](http://thenewstack.io/javascripts-history-and-how-it-led-to-reactjs/).
|
||||
|
||||
<iframe width="650" height="315" src="//www.youtube-nocookie.com/embed/eCf5CquV_Bw" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="315" src="//www.youtube-nocookie.com/embed/eCf5CquV_Bw" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
|
||||
## v8 optimizations
|
||||
@@ -89,7 +89,7 @@ var Button = React.createClass({
|
||||
|
||||
If you are getting started with React, [Joe Maddalone](http://www.joemaddalone.com/) made a good tutorial on how to build your first component.
|
||||
|
||||
<iframe width="650" height="200" src="//www.youtube-nocookie.com/embed/rFvZydtmsxM" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="200" src="//www.youtube-nocookie.com/embed/rFvZydtmsxM" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
|
||||
## Saving time & staying sane?
|
||||
|
||||
@@ -10,7 +10,7 @@ This round-up is a special edition on [Flux](https://facebook.github.io/flux/).
|
||||
|
||||
Facebook engineers [Jing Chen](https://github.com/jingc) and [Bill Fisher](https://github.com/fisherwebdev) gave a talk about Flux and React at [ForwardJS](http://forwardjs.com/), and how using an application architecture with a unidirectional data flow helped solve recurring bugs.
|
||||
|
||||
<iframe width="650" height="315" src="//www.youtube-nocookie.com/embed/i__969noyAM" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="315" src="//www.youtube-nocookie.com/embed/i__969noyAM" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
# Yahoo
|
||||
|
||||
@@ -102,7 +102,7 @@ undo: function() {
|
||||
|
||||
[Dan Abramov](https://twitter.com/dan_abramov) working at Stampsy made a talk about React and Flux. It's a very good overview of the concepts at play.
|
||||
|
||||
<iframe src="//slides.com/danabramov/components-react-flux-wip/embed" width="650" height="315" scrolling="no" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
|
||||
<iframe src="//slides.com/danabramov/components-react-flux-wip/embed" width="100%" height="315" scrolling="no" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
|
||||
|
||||
|
||||
## React and Flux
|
||||
@@ -144,7 +144,7 @@ undo: function() {
|
||||
|
||||
Last but not least, Flux and React ideas are not limited to JavaScript inside of the browser. The iOS team at Facebook re-implemented Newsfeed using very similar patterns.
|
||||
|
||||
<iframe width="650" height="315" src="//www.youtube-nocookie.com/embed/XhXC4SKOGfQ" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="315" src="//www.youtube-nocookie.com/embed/XhXC4SKOGfQ" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
|
||||
## Random Tweet
|
||||
|
||||
@@ -14,11 +14,11 @@ Murilo Pereira ([mpereira](https://github.com/mpereira)) tussles with the topic
|
||||
|
||||
I ([steveluscher](https://github.com/steveluscher)) spoke at Manning Publications' “Powered By JavaScript” Strangeloop pre-conf in St. Louis. There, I proposed a new notation to talk about development complexity – Big-Coffee Notation ☕(n) – and spoke about the features of React that help keep our Big-Coffee from going quadratic, as our user interfaces get more complex.
|
||||
|
||||
<iframe width="560" height="315" src="//www.youtube-nocookie.com/embed/rI0GQc__0SM" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="315" src="//www.youtube-nocookie.com/embed/rI0GQc__0SM" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
James Pearce ([jamesgpearce](https://github.com/jamesgpearce)) carried Big-Coffee all the way to Raleigh, NC. At the _All Things Open_ conference, he spoke about some of the design decisions that went into React, particularly those that lend themselves to simpler, more reliable code.
|
||||
|
||||
<iframe width="560" height="315" src="//www.youtube-nocookie.com/embed/m2fuO2wl_3c" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="315" src="//www.youtube-nocookie.com/embed/m2fuO2wl_3c" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
## All About Isomorphism
|
||||
|
||||
@@ -38,7 +38,7 @@ Ryan Florence ([rpflorence](https://github.com/rpflorence])) and Michael Jackson
|
||||
|
||||
Jonathan Beebe ([somethingkindawierd](https://github.com/somethingkindawierd)) spoke about how he uses React to build tools that deliver hope to those trying to make the best of a bad situation. Watch his talk from this year's _Nodevember_ conference in Nashville
|
||||
|
||||
<iframe width="420" height="315" src="//www.youtube-nocookie.com/embed/uZgAq1CZ1N8" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="315" src="//www.youtube-nocookie.com/embed/uZgAq1CZ1N8" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
If you take a peek under the covers, you'll find that React powers [Carousel](https://blog.carousel.com/2014/11/introducing-carousel-for-web-ipad-and-android-tablet/), Dropbox's new photo and video gallery app.
|
||||
|
||||
@@ -48,7 +48,7 @@ We enjoyed a cinematic/narrative experience with this React-powered, interactive
|
||||
|
||||
Spend the next 60 seconds watching Daniel Woelfel ([dwwoelfel](https://github.com/dwwoelfel)) serialize a React app's state as a string, then deserialize it to produce a working UI. Read about how he uses this technique to [reproduce bugs](http://blog.circleci.com/local-state-global-concerns/) reported to him by his users.
|
||||
|
||||
<iframe width="420" height="315" src="//www.youtube-nocookie.com/embed/5yHFTN-_mOo" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="315" src="//www.youtube-nocookie.com/embed/5yHFTN-_mOo" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
## Community Components
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ It was a privilege to welcome the React community to Facebook HQ on January 28
|
||||
</p>
|
||||
</div>
|
||||
<div class="skinny-col">
|
||||
<iframe width="305" height="171" src="https://www.youtube-nocookie.com/embed/KVZ-P-ZI6W4" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="171" src="https://www.youtube-nocookie.com/embed/KVZ-P-ZI6W4" frameborder="0" allowfullscreen></iframe>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -28,7 +28,7 @@ It was a privilege to welcome the React community to Facebook HQ on January 28
|
||||
</p>
|
||||
</div>
|
||||
<div class="skinny-col">
|
||||
<iframe width="305" height="171" src="https://www.youtube-nocookie.com/embed/yaymfLj5tjA" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="171" src="https://www.youtube-nocookie.com/embed/yaymfLj5tjA" frameborder="0" allowfullscreen></iframe>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -40,7 +40,7 @@ It was a privilege to welcome the React community to Facebook HQ on January 28
|
||||
</p>
|
||||
</div>
|
||||
<div class="skinny-col">
|
||||
<iframe width="305" height="171" src="https://www.youtube-nocookie.com/embed/OZGgVxFxSIs" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="171" src="https://www.youtube-nocookie.com/embed/OZGgVxFxSIs" frameborder="0" allowfullscreen></iframe>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -52,7 +52,7 @@ It was a privilege to welcome the React community to Facebook HQ on January 28
|
||||
</p>
|
||||
</div>
|
||||
<div class="skinny-col">
|
||||
<iframe width="305" height="171" src="https://www.youtube-nocookie.com/embed/9sc8Pyc51uU" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="171" src="https://www.youtube-nocookie.com/embed/9sc8Pyc51uU" frameborder="0" allowfullscreen></iframe>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -64,7 +64,7 @@ It was a privilege to welcome the React community to Facebook HQ on January 28
|
||||
</p>
|
||||
</div>
|
||||
<div class="skinny-col">
|
||||
<iframe width="305" height="171" src="https://www.youtube-nocookie.com/embed/W2DgDNQZOwo" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="171" src="https://www.youtube-nocookie.com/embed/W2DgDNQZOwo" frameborder="0" allowfullscreen></iframe>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -76,7 +76,7 @@ It was a privilege to welcome the React community to Facebook HQ on January 28
|
||||
</p>
|
||||
</div>
|
||||
<div class="skinny-col">
|
||||
<iframe width="305" height="171" src="https://www.youtube-nocookie.com/embed/XZfvW1a8Xac" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="171" src="https://www.youtube-nocookie.com/embed/XZfvW1a8Xac" frameborder="0" allowfullscreen></iframe>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -88,7 +88,7 @@ It was a privilege to welcome the React community to Facebook HQ on January 28
|
||||
</p>
|
||||
</div>
|
||||
<div class="skinny-col">
|
||||
<iframe width="305" height="171" src="https://www.youtube-nocookie.com/embed/KtmjkCuV-EU" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="171" src="https://www.youtube-nocookie.com/embed/KtmjkCuV-EU" frameborder="0" allowfullscreen></iframe>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -100,7 +100,7 @@ It was a privilege to welcome the React community to Facebook HQ on January 28
|
||||
</p>
|
||||
</div>
|
||||
<div class="skinny-col">
|
||||
<iframe width="305" height="171" src="https://www.youtube-nocookie.com/embed/KYzlpRvWZ6c" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="171" src="https://www.youtube-nocookie.com/embed/KYzlpRvWZ6c" frameborder="0" allowfullscreen></iframe>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -112,7 +112,7 @@ It was a privilege to welcome the React community to Facebook HQ on January 28
|
||||
</p>
|
||||
</div>
|
||||
<div class="skinny-col">
|
||||
<iframe width="305" height="171" src="https://www.youtube-nocookie.com/embed/Sla-DkvmIHY" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="171" src="https://www.youtube-nocookie.com/embed/Sla-DkvmIHY" frameborder="0" allowfullscreen></iframe>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -124,7 +124,7 @@ It was a privilege to welcome the React community to Facebook HQ on January 28
|
||||
</p>
|
||||
</div>
|
||||
<div class="skinny-col">
|
||||
<iframe width="305" height="171" src="https://www.youtube-nocookie.com/embed/z5e7kWSHWTg" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="171" src="https://www.youtube-nocookie.com/embed/z5e7kWSHWTg" frameborder="0" allowfullscreen></iframe>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -136,7 +136,7 @@ It was a privilege to welcome the React community to Facebook HQ on January 28
|
||||
</p>
|
||||
</div>
|
||||
<div class="skinny-col">
|
||||
<iframe width="305" height="171" src="https://www.youtube-nocookie.com/embed/7rDsRXj9-cU" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="171" src="https://www.youtube-nocookie.com/embed/7rDsRXj9-cU" frameborder="0" allowfullscreen></iframe>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -148,7 +148,7 @@ It was a privilege to welcome the React community to Facebook HQ on January 28
|
||||
</p>
|
||||
</div>
|
||||
<div class="skinny-col">
|
||||
<iframe width="305" height="171" src="https://www.youtube-nocookie.com/embed/g0TD0efcwVg" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="171" src="https://www.youtube-nocookie.com/embed/g0TD0efcwVg" frameborder="0" allowfullscreen></iframe>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -160,7 +160,7 @@ It was a privilege to welcome the React community to Facebook HQ on January 28
|
||||
</p>
|
||||
</div>
|
||||
<div class="skinny-col">
|
||||
<iframe width="305" height="171" src="https://www.youtube-nocookie.com/embed/I7IdS-PbEgI" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="171" src="https://www.youtube-nocookie.com/embed/I7IdS-PbEgI" frameborder="0" allowfullscreen></iframe>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -171,7 +171,7 @@ It was a privilege to welcome the React community to Facebook HQ on January 28
|
||||
<strong>Jafar Husain</strong> told us a story about how Netflix was able to push React into places where the DOM could not go.
|
||||
</div>
|
||||
<div class="skinny-col">
|
||||
<iframe width="305" height="171" src="https://www.youtube-nocookie.com/embed/eNC0mRYGWgc" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="171" src="https://www.youtube-nocookie.com/embed/eNC0mRYGWgc" frameborder="0" allowfullscreen></iframe>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -182,7 +182,7 @@ It was a privilege to welcome the React community to Facebook HQ on January 28
|
||||
<strong>Zach Nation</strong> showed us how we can produce visualizations from over 45 million data points without breaking a sweat.
|
||||
</div>
|
||||
<div class="skinny-col">
|
||||
<iframe width="305" height="171" src="https://www.youtube-nocookie.com/embed/2ii1lEkIv1s" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="171" src="https://www.youtube-nocookie.com/embed/2ii1lEkIv1s" frameborder="0" allowfullscreen></iframe>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -193,7 +193,7 @@ It was a privilege to welcome the React community to Facebook HQ on January 28
|
||||
<strong>David Nolen</strong> gave us a view of React from a non-JavaScript perspective, challenging some common intuition along the way.
|
||||
</div>
|
||||
<div class="skinny-col">
|
||||
<iframe width="305" height="171" src="https://www.youtube-nocookie.com/embed/5hGHdETNteE" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="171" src="https://www.youtube-nocookie.com/embed/5hGHdETNteE" frameborder="0" allowfullscreen></iframe>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -204,7 +204,7 @@ It was a privilege to welcome the React community to Facebook HQ on January 28
|
||||
<strong>Bill Fisher</strong> coordinated a Flux panel together with <strong>Michael Ridgway</strong>, <strong>Spike Brehm</strong>, <strong>Andres Suarez</strong>, <strong>Jing Chen</strong>, <strong>Ian Obermiller</strong>, and <strong>Kyle Davis</strong>.
|
||||
</div>
|
||||
<div class="skinny-col">
|
||||
<iframe width="305" height="171" src="https://www.youtube-nocookie.com/embed/LTj4O7WJJ98" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="171" src="https://www.youtube-nocookie.com/embed/LTj4O7WJJ98" frameborder="0" allowfullscreen></iframe>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -215,7 +215,7 @@ It was a privilege to welcome the React community to Facebook HQ on January 28
|
||||
<strong>Bonnie Eisenman</strong> led us through the ‘adapter’ approach to inter-component communication taken by her team at Codecademy.
|
||||
</div>
|
||||
<div class="skinny-col">
|
||||
<iframe width="305" height="171" src="https://www.youtube-nocookie.com/embed/ZM6wXoFTY3o" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="171" src="https://www.youtube-nocookie.com/embed/ZM6wXoFTY3o" frameborder="0" allowfullscreen></iframe>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -226,7 +226,7 @@ It was a privilege to welcome the React community to Facebook HQ on January 28
|
||||
<strong>James Brantly</strong> demonstrated how we can reap the benefits of static typing using both Flow and TypeScript.
|
||||
</div>
|
||||
<div class="skinny-col">
|
||||
<iframe width="305" height="171" src="https://www.youtube-nocookie.com/embed/9PTa9-PPVAc" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="171" src="https://www.youtube-nocookie.com/embed/9PTa9-PPVAc" frameborder="0" allowfullscreen></iframe>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -237,7 +237,7 @@ It was a privilege to welcome the React community to Facebook HQ on January 28
|
||||
<strong>Tom Occhino</strong>, <strong>Ben Alpert</strong>, <strong>Lee Byron</strong>, <strong>Christopher Chedeau</strong>, <strong>Sebastian Markbåge</strong>, <strong>Jing Chen</strong>, and <strong>Dan Schafer</strong> closed the conference with a Q&A session.
|
||||
</div>
|
||||
<div class="skinny-col">
|
||||
<iframe width="305" height="171" src="https://www.youtube-nocookie.com/embed/EPpkboSKvPI" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="171" src="https://www.youtube-nocookie.com/embed/EPpkboSKvPI" frameborder="0" allowfullscreen></iframe>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -266,4 +266,4 @@ And, in case you missed a session, you can borrow **Michael Chan’s** [drawings
|
||||
|
||||
**All proceeds from React.js Conf 2015 were donated to the wonderful programs at [code.org](http://code.org)**. These programs aim to increase access to the field of computer science by underrepresented members of our community. Watch this video to learn more.
|
||||
|
||||
<iframe width="305" height="171" src="https://www.youtube-nocookie.com/embed/FC5FbmsH4fw" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="171" src="https://www.youtube-nocookie.com/embed/FC5FbmsH4fw" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
@@ -8,7 +8,7 @@ author: wincent
|
||||
|
||||
There's more to building an application than creating a user interface. Data fetching is still a tricky problem, especially as applications become more complicated. At [React.js Conf](http://conf.reactjs.com/) we announced two projects we've created at Facebook to make data fetching simple for developers, even as a product grows to include dozens of contributors and the application becomes as complex as Facebook itself.
|
||||
|
||||
<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/9sc8Pyc51uU" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="315" src="https://www.youtube-nocookie.com/embed/9sc8Pyc51uU" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
The two projects — Relay and GraphQL — have been in use in production at Facebook for some time, and we're excited to be bringing them to the world as open source in the future. In the meantime, we wanted to share some additional information about the projects here.
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ Interest in React has been exploding recently, so it's a good time to explore so
|
||||
|
||||
[Formidable Labs](https://github.com/FormidableLabs) and [Seattle JS](http://www.meetup.com/seattlejs/) recently hosted a series of React, Flux, and Flow workshops, and the first part is available to watch online:
|
||||
|
||||
<iframe width="650" height="300" src="//www.youtube-nocookie.com/embed/Pd6Ub7Ju2RM" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="300" src="//www.youtube-nocookie.com/embed/Pd6Ub7Ju2RM" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
[AEFlash](https://github.com/aearly) writes up [some best practices and tips](http://aeflash.com/2015-02/react-tips-and-best-practices.html) to help you avoid potential pitfalls when developing with React.
|
||||
|
||||
@@ -20,7 +20,7 @@ Black Mutt Media [takes us through their usage of React](http://blackmuttmedia.c
|
||||
|
||||
Our own [Sebastian Markbåge](https://github.com/sebmarkbage) was on the [Web Platform Podcast](http://thewebplatform.libsyn.com/31-building-with-reactjs) to have a chat about all aspects of React.
|
||||
|
||||
<iframe style="border: none" src="//html5-player.libsyn.com/embed/episode/id/3370114/height/75/width/200/theme/standard-mini/direction/no/autoplay/no/autonext/no/thumbnail/yes/preload/no/no_addthis/no/" height="26" width="650" scrolling="no" allowfullscreen="" webkitallowfullscreen="" mozallowfullscreen="" oallowfullscreen="" msallowfullscreen=""></iframe>
|
||||
<iframe style="border: none" src="//html5-player.libsyn.com/embed/episode/id/3370114/height/75/width/200/theme/standard-mini/direction/no/autoplay/no/autonext/no/thumbnail/yes/preload/no/no_addthis/no/" height="26" width="100%" scrolling="no" allowfullscreen="" webkitallowfullscreen="" mozallowfullscreen="" oallowfullscreen="" msallowfullscreen=""></iframe>
|
||||
|
||||
## Community Additions
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ We open sourced React Native last week and the community reception blew away all
|
||||
|
||||
**Give us 6 months**. At Facebook, we strive to only open-source projects that we are using in production. While the Android backend for React Native is starting to work (see video below at 37min), it hasn't been shipped to any users yet. There's a lot of work that goes into open-sourcing a project, and we want to do it right so that you have a great experience when using it.
|
||||
|
||||
<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/X6YbAKiLCLU?start=2220" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="315" src="https://www.youtube-nocookie.com/embed/X6YbAKiLCLU?start=2220" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
|
||||
## Ray Wenderlich - Property Finder
|
||||
@@ -92,4 +92,3 @@ Clay Allsopp wrote a post about [all the crazy things you could do with a JavaSc
|
||||
We've spent a lot of efforts getting the onboarding as easy as possible and we're really happy that people noticed. We still have a lot of work to do on documentation, stay tuned!
|
||||
|
||||
<blockquote class="twitter-tweet" lang="en"><p>Wow. Getting started with React Native might have been the smoothest experience I’ve ever had with a new developer product.</p>— Andreas Eldh (@eldh) <a href="https://twitter.com/eldh/status/581186172094980096">March 26, 2015</a></blockquote>
|
||||
|
||||
|
||||
@@ -19,4 +19,4 @@ You now have three ways to get React Native. You should chose the one you want b
|
||||
|
||||
If you want more details, I highly recommend this video that explains how Facebook mobile release process works and why it was setup this way.
|
||||
|
||||
<iframe width="650" height="300" src="https://www.youtube.com/embed/mOyoTUETmSM" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="300" src="https://www.youtube.com/embed/mOyoTUETmSM" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
@@ -8,39 +8,39 @@ Last month, the first React.js European conference took place in the city of Par
|
||||
|
||||
[Christopher Chedeau](https://github.com/vjeux) gave the opening keynote to the conference:
|
||||
|
||||
<iframe width="650" height="366" src="//www.youtube.com/embed/PAA9O4E1IM4" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="//www.youtube.com/embed/PAA9O4E1IM4" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
[Spencer Ahrens](https://github.com/sahrens) walks through building an advanced gestural UI leveraging the unique power of the React Native layout and animation systems to build a complex and fluid experience:
|
||||
|
||||
<iframe width="650" height="366" src="//www.youtube.com/embed/xDlfrcM6YBk" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="//www.youtube.com/embed/xDlfrcM6YBk" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
[Lee Byron](https://github.com/leebyron) explores GraphQL, its core principles, how it works, and what makes it a powerful tool:
|
||||
|
||||
<iframe width="650" height="366" src="//www.youtube.com/embed/WQLzZf34FJ8" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="//www.youtube.com/embed/WQLzZf34FJ8" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
[Joseph Savona](https://github.com/josephsavona) explores the problems Relay solves, its architecture and the query lifecycle, and how can you use Relay to build more scalable apps. There are examples of how Relay powers applications as complex as the Facebook News Feed:
|
||||
|
||||
<iframe width="650" height="366" src="//www.youtube.com/embed/IrgHurBjQbg" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="//www.youtube.com/embed/IrgHurBjQbg" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
[Nick Schrock](https://github.com/schrockn) and [Dan Schafer](https://github.com/dschafer) take a deeper dive into putting GraphQL to work. How can we build a GraphQL API to work with an existing REST API or server-side data model? What are best practices when building a GraphQL API, and how do they differ from traditional REST best practices? How does Facebook use GraphQL? Most importantly, what does a complete and coherent GraphQL API looks like, and how can we get started building one?
|
||||
|
||||
<iframe width="650" height="366" src="//www.youtube.com/embed/gY48GW87Feo" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="//www.youtube.com/embed/gY48GW87Feo" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
[Sebastian Markbåge](https://github.com/sebmarkbage) talks about why the DOM is flawed and how it is becoming a second-class citizen in the land of React apps:
|
||||
|
||||
<iframe width="650" height="366" src="//www.youtube.com/embed/Zemce4Y1Y-A" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="//www.youtube.com/embed/Zemce4Y1Y-A" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
[Sebastian McKenzie](https://github.com/sebmck) goes over how existing JSX build pipeline infrastructure can be further utilised to perform even more significant code transformations such as transpilation, optimisation, profiling and more, reducing bugs, making your code faster and you as a developer more productive and happy:
|
||||
|
||||
<iframe width="650" height="366" src="//www.youtube.com/embed/OFuDvqZmUrE" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="//www.youtube.com/embed/OFuDvqZmUrE" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
[Cheng Lou](https://github.com/chenglou) gives a talk on the past, the present and the future of animation, and the place React can potentially take in this:
|
||||
|
||||
<iframe width="650" height="366" src="//www.youtube.com/embed/1tavDv5hXpo" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="//www.youtube.com/embed/1tavDv5hXpo" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
And there was a Q&A session with the whole team covering a range of React topics:
|
||||
|
||||
<iframe width="650" height="366" src="//www.youtube.com/embed/CRJZBZ_-6hQ" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="//www.youtube.com/embed/CRJZBZ_-6hQ" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
And there were lots of great talks from the React community:
|
||||
|
||||
|
||||
230
docs/_posts/2016-09-28-our-first-50000-stars.md
Normal file
230
docs/_posts/2016-09-28-our-first-50000-stars.md
Normal file
@@ -0,0 +1,230 @@
|
||||
---
|
||||
title: "Our First 50,000 Stars"
|
||||
author: vjeux
|
||||
---
|
||||
|
||||
Just three and a half years ago we open sourced a little JavaScript library called React. The journey since that day has been incredibly exciting.
|
||||
|
||||
## Commemorative T-Shirt
|
||||
|
||||
In order to celebrate 50,000 GitHub stars, [Maggie Appleton](http://www.maggieappleton.com/) from [egghead.io](http://egghead.io/) has designed us a special T-shirt, which will be available for purchase from Teespring **only for a week** through Thursday, October 6. Maggie also wrote [a blog post](https://www.behance.net/gallery/43269677/Reacts-50000-Stars-Shirt) showing all the different concepts she came up with before settling on the final design.
|
||||
|
||||
<a target="_blank" href="https://teespring.com/react-50000-stars"><img src="/react/img/blog/react-50k-tshirt.jpg" width="650" height="340" alt="React 50k Tshirt" /></a>
|
||||
|
||||
The T-shirts are super soft using American Apparel's tri-blend fabric; we also have kids and toddler T-shirts and baby onesies available.
|
||||
|
||||
* [Adult T-shirts (straight-cut and fitted)](https://teespring.com/react-50000-stars)
|
||||
* [Kids T-shirts](https://teespring.com/react-50000-stars-kids)
|
||||
* [Toddler T-Shirts](https://teespring.com/react-50000-stars-toddler)
|
||||
* [Baby Onesies](https://teespring.com/react-50000-stars-baby)
|
||||
|
||||
Proceeds from the shirts will be donated to [CODE2040](http://www.code2040.org/), a nonprofit that creates access, awareness, and opportunities in technology for underrepresented minorities with a specific focus on Black and Latinx talent.
|
||||
|
||||
## Archeology
|
||||
|
||||
We've spent a lot of time trying to explain the concepts behind React and the problems it attempts to solve, but we haven't talked much about how React evolved before being open sourced. This milestone seemed like as good a time as any to dig through the earliest commits and share some of the more important moments and fun facts.
|
||||
|
||||
The story begins in our ads org, where we were building incredibly sophisticated client side web apps using an internal MVC framework called [BoltJS](http://web.archive.org/web/20130608154901/http://shaneosullivan.github.io/boltjs/intro.html). Here's a sample of what some Bolt code looked like:
|
||||
|
||||
```js
|
||||
var CarView = require('javelin/core').createClass({
|
||||
name: 'CarView',
|
||||
extend: require('container').Container,
|
||||
properties: {
|
||||
wheels: 4,
|
||||
},
|
||||
declare: function() {
|
||||
return {
|
||||
childViews: [
|
||||
{ content: 'I have ' },
|
||||
{ ref: 'wheelView' },
|
||||
{ content: ' wheels' }
|
||||
]
|
||||
};
|
||||
},
|
||||
setWheels: function(wheels) {
|
||||
this.findRef('wheelView').setContent(wheels);
|
||||
},
|
||||
getWheels: function() {
|
||||
return this.findRef('wheelView').getContent();
|
||||
},
|
||||
});
|
||||
|
||||
var car = new CarView();
|
||||
car.setWheels(3);
|
||||
car.placeIn(document.body);
|
||||
//<div>
|
||||
// <div>I have </div>
|
||||
// <div>3</div>
|
||||
// <div> wheels</div>
|
||||
//</div>
|
||||
```
|
||||
|
||||
Bolt introduced a number of APIs and features that would eventually make their way into React including `render`, `createClass`, and `refs`. Bolt introduced the concept of `refs` as a way to create references to nodes that can be used imperatively. This was relevant for legacy interoperability and incremental adoption, and while React would eventually strive to be a lot more functional, `refs` proved to be a very useful way to break out of the functional paradigm when the need arose.
|
||||
|
||||
But as our applications grew more and more sophisticated, our Bolt codebases got pretty complicated. Recognizing some of the framework's shortcomings, [Jordan Walke](https://twitter.com/jordwalke) started experimenting with a side-project called [FaxJS](https://github.com/jordwalke/FaxJs). His goal was to solve many of the same problems as Bolt, but in a very different way. This is actually where most of React's fundamentals were born, including props, state, re-evaluating large portions of the tree to “diff” the UI, server-side rendering, and a basic concept of components.
|
||||
|
||||
```js
|
||||
TestProject.PersonDisplayer = {
|
||||
structure : function() {
|
||||
return Div({
|
||||
classSet: { personDisplayerContainer: true },
|
||||
titleDiv: Div({
|
||||
classSet: { personNameTitle: true },
|
||||
content: this.props.name
|
||||
}),
|
||||
nestedAgeDiv: Div({
|
||||
content: 'Interests: ' + this.props.interests
|
||||
})
|
||||
});
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
## FBolt is Born
|
||||
|
||||
Through his FaxJS experiment, Jordan became convinced that functional APIs — which discouraged mutation — offered a better, more scalable way to build user interfaces. He imported his library into Facebook's codebase in March of 2012 and renamed it “FBolt”, signifying an extension of Bolt where components are written in a functional programming style. Or maybe “FBolt” was a nod to FaxJS – he didn't tell us! ;)
|
||||
|
||||
The interoperability between FBolt and Bolt allowed us to experiment with replacing just one component at a time with more functional component APIs. We could test the waters of this new functional paradigm, without having to go all in. We started with the components that were clearly best expressed functionally and then we would later continue to push the boundaries of what we could express as functions.
|
||||
|
||||
Realizing that FBolt wouldn't be a great name for the library when used on its own, Jordan Walke and [Tom Occhino](https://twitter.com/tomocchino) decided on a new name: “React.” After Tom sent out the diff to rename everything to React, Jordan commented:
|
||||
|
||||
|
||||
> Jordan Walke:
|
||||
I might add for the sake of discussion, that many systems advertise some kind of reactivity, but they usually require that you set up some kind of point-to-point listeners and won't work on structured data. This API reacts to any state or property changes, and works with data of any form (as deeply structured as the graph itself) so I think the name is fitting.
|
||||
|
||||
|
||||
Most of Tom's other commits at the time were on the first version of [GraphiQL](https://github.com/graphql/graphiql), a project which was recently open sourced.
|
||||
|
||||
## Adding JSX
|
||||
|
||||
Since about 2010 Facebook has been using an extension of PHP called [XHP](https://www.facebook.com/notes/facebook-engineering/xhp-a-new-way-to-write-php/294003943919/), which enables engineers to create UIs using XML literals right inside their PHP code. It was first introduced to help prevent XSS holes but ended up being an excellent way to structure applications with custom components.
|
||||
|
||||
```js
|
||||
final class :a:post extends :x:element {
|
||||
attribute :a;
|
||||
protected function render(): XHPRoot {
|
||||
$anchor = <a>{$this->getChildren()}</a>;
|
||||
$form = (
|
||||
<form
|
||||
method="post"
|
||||
action={$this->:href}
|
||||
target={$this->:target}
|
||||
class="postLink"
|
||||
>{$anchor}</form>
|
||||
);
|
||||
$this->transferAllAttributes($anchor);
|
||||
return $form;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Before Jordan's work had even made its way into the Facebook codebase, Adam Hupp implemented an XHP-like concept for JavaScript, written in Haskell. This system enabled you to write the following inside a JavaScript file:
|
||||
|
||||
```js
|
||||
function :example:hello(attrib, children) {
|
||||
return (
|
||||
<div class="special">
|
||||
<h1>Hello, World!</h1>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
It would compile the above into the following normal ES3-compatible JavaScript:
|
||||
|
||||
```js
|
||||
function jsx_example_hello(attrib, children) {
|
||||
return (
|
||||
S.create("div", {"class": "special"}, [
|
||||
S.create("h1", {}, ["Hello, World!"]),
|
||||
children
|
||||
]
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
In this prototype, `S.create` would immediately create and return a DOM node. Most of the conversations on this prototype revolved around the performance characteristics of `innerHTML` versus creating DOM nodes directly. At the time, it would have been less than ideal to push developers universally in the direction of creating DOM nodes directly since it did not perform as well, especially in Firefox and IE. Facebook's then-CTO [Bret Taylor](https://twitter.com/btaylor) chimed in on the discussion at the time in favor of `innerHTML` over `document.createElement`:
|
||||
|
||||
|
||||
> Bret Taylor:
|
||||
If you are not convinced about innerHTML, here is a small microbenchmark. It is about the same in Chrome. innerHTML is about 30% faster in the latest version of Firefox (much more in previous versions), and about 90% faster in IE8.
|
||||
|
||||
|
||||
This work was eventually abandoned but was revived after React made its way into the codebase. Jordan sidelined the previous performance discussions by introducing the concept of a “Virtual DOM,” though its eventual name didn't exist yet.
|
||||
|
||||
|
||||
> Jordan Walke:
|
||||
> For the first step, I propose that we do the easiest, yet most general transformation possible. My suggestion is to simply map xml expressions to function call expressions.
|
||||
>
|
||||
> - `<x></x>` becomes `x( )`
|
||||
> - `<x height=12></x>` becomes `x( {height:12} )`
|
||||
> - `<x> <y> </y> </x>` becomes `x({ childList: [y( )] })`
|
||||
>
|
||||
> At this point, JSX doesn't need to know about React - it's just a convenient way to write function calls. Coincidentally, React's primary abstraction is the function. Okay maybe it's not so coincidental ;)
|
||||
|
||||
|
||||
Adam made a very insightful comment, which is now the default way we write lists in React with JSX.
|
||||
|
||||
|
||||
> Adam Hupp:
|
||||
> I think we should just treat arrays of elements as a frag. This is useful for constructs like:
|
||||
>
|
||||
> ```js
|
||||
<ul>{foo.map(function(i) { return <li>{i.data}</li>; })}</ul>
|
||||
```
|
||||
>
|
||||
> In this case the ul(..) will get a childList with a single child, which is itself a list.
|
||||
|
||||
|
||||
React didn't end up using Adam's implementation directly. Instead, we created JSX by forking [js-xml-literal](https://github.com/laverdet/js-xml-literal), a side project by XHP creator Marcel Laverdet. JSX took its name from js-xml-literal, which Jordan modified to just be syntactic sugar for deeply nested function calls.
|
||||
|
||||
## API Churn
|
||||
|
||||
During the first year of React, internal adoption was growing quickly but there was quite a lot of churn in the component APIs and naming conventions:
|
||||
|
||||
* `project` was renamed to `declare` then to `structure` and finally to `render`.
|
||||
* `Componentize` was renamed to `createComponent` and finally to `createClass`.
|
||||
|
||||
As the project was about to be open sourced, [Lee Byron](https://twitter.com/leeb) sat down with Jordan Walke, Tom Occhino and Sebastian Markbåge in order to refactor, reimplement, and rename one of React's most beloved features – the lifecycle API. Lee [came up with a well-designed API](https://gist.github.com/vjeux/f2b015d230cc1ab18ed1df30550495ed) that is still in place today.
|
||||
|
||||
* Concepts
|
||||
* component - a ReactComponent instance
|
||||
* state - internal state to a component
|
||||
* props - external state to a component
|
||||
* markup - the stringy HTML-ish stuff components generate
|
||||
* DOM - the document and elements within the document
|
||||
* Actions
|
||||
* mount - to put a component into a DOM
|
||||
* initialize - to prepare a component for rendering
|
||||
* update - a transition of state (and props) resulting a render.
|
||||
* render - a side-effect-free process to get the representation (markup) of a component.
|
||||
* validate - make assertions about something created and provided
|
||||
* destroy - opposite of initialize
|
||||
* Operands
|
||||
* create - make a new thing
|
||||
* get - get an existing thing
|
||||
* set - merge into existing
|
||||
* replace - replace existing
|
||||
* receive - respond to new data
|
||||
* force - skip checks to do action
|
||||
* Notifications
|
||||
* shouldObjectAction
|
||||
* objectWillAction
|
||||
* objectDidAction
|
||||
|
||||
## Instagram
|
||||
|
||||
In 2012, Instagram got acquired by Facebook. [Pete Hunt](https://twitter.com/floydophone), who was working on Facebook photos and videos at the time, joined their newly formed web team. He wanted to build their website completely in React, which was in stark contrast with the incremental adoption model that had been used at Facebook.
|
||||
|
||||
To make this happen, React had to be decoupled from Facebook's infrastructure, since Instagram didn't use any of it. This project acted as a forcing function to do the work needed to open source React. In the process, Pete also discovered and promoted a little project called Webpack. He also implemented the `renderToString` primitive which was needed to do server-side rendering.
|
||||
|
||||
As we started to prepare for the open source launch, [Maykel Loomans](https://twitter.com/miekd), a designer on Instagram, made a mock of what the website could look like. The header ended up defining the visual identity of React: its logo and the electric blue color!
|
||||
|
||||
<center><a target="_blank" href="/react/img/blog/react-50k-mock-full.jpg"><img src="/react/img/blog/react-50k-mock.jpg" width="400" height="410" alt="React website mock" /></a></center>
|
||||
|
||||
In its earliest days, React benefitted tremendously from feedback, ideas, and technical contributions of early adopters and collaborators all over the company. While it might look like an overnight success in hindsight, the story of React is actually a great example of how new ideas often need to go through several rounds of refinement, iteration, and course correction over a long period of time before reaching their full potential.
|
||||
|
||||
React's approach to building user interfaces with functional programming principles has changed the way we do things in just a few short years. It goes without saying, but React would be nothing without the amazing open source community that's built up around it!
|
||||
|
||||
@@ -11,7 +11,7 @@ next: videos-it-IT.html
|
||||
|
||||
[Sito web](http://conf.reactjs.com/) - [Agenda](http://conf.reactjs.com/schedule.html) - [Video](https://www.youtube-nocookie.com/playlist?list=PLb0IAmt7-GS1cbw4qonlQztYV1TAW0sCr)
|
||||
|
||||
<iframe width="650" height="315" src="//www.youtube-nocookie.com/embed/KVZ-P-ZI6W4?list=PLb0IAmt7-GS1cbw4qonlQztYV1TAW0sCr" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="315" src="//www.youtube-nocookie.com/embed/KVZ-P-ZI6W4?list=PLb0IAmt7-GS1cbw4qonlQztYV1TAW0sCr" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
### ReactEurope 2015
|
||||
2 e 3 Luglio
|
||||
@@ -11,7 +11,7 @@ next: videos-ko-KR.html
|
||||
|
||||
[웹사이트](http://conf.reactjs.com/) - [스케줄](http://conf.reactjs.com/schedule.html) - [비디오들](https://www.youtube-nocookie.com/playlist?list=PLb0IAmt7-GS1cbw4qonlQztYV1TAW0sCr)
|
||||
|
||||
<iframe width="650" height="315" src="//www.youtube-nocookie.com/embed/KVZ-P-ZI6W4?list=PLb0IAmt7-GS1cbw4qonlQztYV1TAW0sCr" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="315" src="//www.youtube-nocookie.com/embed/KVZ-P-ZI6W4?list=PLb0IAmt7-GS1cbw4qonlQztYV1TAW0sCr" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
### ReactEurope 2015
|
||||
7월 2일 & 3일
|
||||
95
docs/community/conferences.md
Normal file
95
docs/community/conferences.md
Normal file
@@ -0,0 +1,95 @@
|
||||
---
|
||||
id: conferences
|
||||
title: Conferences
|
||||
layout: community
|
||||
sectionid: community
|
||||
permalink: community/conferences.html
|
||||
redirect_from: "docs/conferences.html"
|
||||
---
|
||||
|
||||
## Upcoming Conferences
|
||||
|
||||
### Agent Conference 2017
|
||||
January 20-21 in Dornbirn, Austria
|
||||
|
||||
[Website](http://agent.sh/)
|
||||
|
||||
### ReactEurope 2017
|
||||
May 18th & 19th in Paris, France
|
||||
|
||||
[Website](http://www.react-europe.org/) - [Schedule](http://www.react-europe.org/#schedule)
|
||||
|
||||
### React Amsterdam 2017
|
||||
April 21st in Amsterdam, The Netherlands
|
||||
|
||||
[Website](https://react.amsterdam) - [Twitter](https://twitter.com/reactamsterdam)
|
||||
|
||||
### Chain React 2017
|
||||
Summer 2017, Portland, Oregon USA
|
||||
|
||||
[Website](https://infinite.red/ChainReactConf) - [Twitter](https://twitter.com/chainreactconf)
|
||||
|
||||
### React Native EU 2017
|
||||
Fall 2017, Poland
|
||||
|
||||
[Website](http://react-native.eu/)
|
||||
|
||||
|
||||
## Past Conferences
|
||||
|
||||
### React.js Conf 2015
|
||||
January 28 & 29 in Facebook HQ, CA
|
||||
|
||||
[Website](http://conf2015.reactjs.org/) - [Schedule](http://conf2015.reactjs.org/schedule.html) - [Videos](https://www.youtube.com/playlist?list=PLb0IAmt7-GS1cbw4qonlQztYV1TAW0sCr)
|
||||
|
||||
<iframe width="100%" height="315" src="//www.youtube-nocookie.com/embed/KVZ-P-ZI6W4?list=PLb0IAmt7-GS1cbw4qonlQztYV1TAW0sCr" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
### ReactEurope 2015
|
||||
July 2 & 3 in Paris, France
|
||||
|
||||
[Website](http://www.react-europe.org/) - [Schedule](http://www.react-europe.org/#schedule) - [Videos](https://www.youtube.com/channel/UCorlLn2oZfgOJ-FUcF2eZ1A/playlists)
|
||||
|
||||
### Reactive 2015
|
||||
November 2-4 in Bratislava, Slovakia
|
||||
|
||||
[Website](https://reactive2015.com/) - [Schedule](https://reactive2015.com/schedule_speakers.html#schedule)
|
||||
|
||||
### React.js Conf 2016
|
||||
February 22 & 23 in San Francisco, CA
|
||||
|
||||
[Website](http://conf.reactjs.com/) - [Schedule](http://conf.reactjs.com/schedule.html) - [Videos](https://www.youtube.com/playlist?list=PLb0IAmt7-GS0M8Q95RIc2lOM6nc77q1IY)
|
||||
|
||||
### React Amsterdam 2016
|
||||
April 16 in Amsterdam, The Netherlands
|
||||
|
||||
[Website](https://react.amsterdam/2016) - [Videos](https://youtu.be/sXDZBxbRRag?list=PLNBNS7NRGKMG3uLrm5fgY02hJ87Wzb4IU)
|
||||
|
||||
### ReactEurope 2016
|
||||
June 2 & 3 in Paris, France
|
||||
|
||||
[Website](http://www.react-europe.org/) - [Schedule](http://www.react-europe.org/#schedule) - [Videos](https://www.youtube.com/channel/UCorlLn2oZfgOJ-FUcF2eZ1A/playlists)
|
||||
|
||||
### ReactRally 2016
|
||||
August 25-26 in Salt Lake City, UT
|
||||
|
||||
[Website](http://www.reactrally.com/) - [Schedule](http://www.reactrally.com/#/schedule) - [Videos](https://www.youtube.com/playlist?list=PLUD4kD-wL_zYSfU3tIYsb4WqfFQzO_EjQ)
|
||||
|
||||
### ReactNext 2016
|
||||
September 15 in Tel Aviv, Israel
|
||||
|
||||
[Website](http://react-next.com/) - [Schedule](http://react-next.com/#schedule) - [Videos](https://www.youtube.com/channel/UC3BT8hh3yTTYxbLQy_wbk2w)
|
||||
|
||||
### ReactNL 2016
|
||||
October 13 in Amsterdam, The Netherlands - [Schedule](http://reactnl.org/#program)
|
||||
|
||||
[Website](http://reactnl.org/)
|
||||
|
||||
### Reactive 2016
|
||||
October 26-28 in Bratislava, Slovakia
|
||||
|
||||
[Website](https://reactiveconf.com/)
|
||||
|
||||
### React Remote Conf 2016
|
||||
October 26-28 online
|
||||
|
||||
[Website](https://allremoteconfs.com/react-2016) - [Schedule](https://allremoteconfs.com/react-2016#schedule)
|
||||
@@ -11,7 +11,7 @@ next: videos-zh-CN.html
|
||||
|
||||
[Website](http://conf.reactjs.com/) - [Schedule](http://conf.reactjs.com/schedule.html) - [Videos](https://www.youtube-nocookie.com/playlist?list=PLb0IAmt7-GS1cbw4qonlQztYV1TAW0sCr)
|
||||
|
||||
<iframe width="650" height="315" src="//www.youtube-nocookie.com/embed/KVZ-P-ZI6W4?list=PLb0IAmt7-GS1cbw4qonlQztYV1TAW0sCr" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="315" src="//www.youtube-nocookie.com/embed/KVZ-P-ZI6W4?list=PLb0IAmt7-GS1cbw4qonlQztYV1TAW0sCr" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
### ReactEurope 2015
|
||||
七月 2 & 3
|
||||
@@ -1,8 +1,10 @@
|
||||
---
|
||||
title: Need help?
|
||||
layout: single
|
||||
id: support
|
||||
permalink: support.html
|
||||
title: Where To Get Support
|
||||
layout: community
|
||||
sectionid: community
|
||||
permalink: community/support.html
|
||||
redirect_from: "support.html"
|
||||
---
|
||||
|
||||
**React** is worked on full-time by Facebook's product infrastructure and Instagram's user interface engineering teams. They're often around and available for questions.
|
||||
@@ -17,12 +19,12 @@ For longer-form conversations about React, we've set up a [discussion forum at *
|
||||
|
||||
In the forum there's also a category for job posts and a category for discussion of our weekly meeting notes.
|
||||
|
||||
## IRC
|
||||
## Reactiflux Chat
|
||||
|
||||
Many developers and users idle on Freenode.net's IRC network in **[#reactjs on freenode](irc://chat.freenode.net/reactjs)**.
|
||||
If you need an answer right away, check out the [Reactiflux Discord](https://discord.gg/0ZcbPKXt5bZjGY5n) community. There are usually a number of React experts there who can help out or point you to somewhere you might want to look.
|
||||
|
||||
## Twitter
|
||||
## Facebook and Twitter
|
||||
|
||||
For the latest news about React, [follow **@reactjs** on Twitter](https://twitter.com/reactjs). In addition, you can use the #reactjs hashtag to see what others are saying or add to the conversation.
|
||||
For the latest news about React, [like us on Facebook](https://facebook.com/react) and [follow **@reactjs** on Twitter](https://twitter.com/reactjs). In addition, you can use the [#reactjs](https://twitter.com/hashtag/reactjs) hashtag to see what others are saying or add to the conversation.
|
||||
|
||||
<div><a class="twitter-timeline" data-dnt="true" data-chrome="nofooter noheader transparent" href="https://twitter.com/search?q=%23reactjs" data-widget-id="342522405270470656"></a></div>
|
||||
@@ -8,7 +8,7 @@ next: complementary-tools-it-IT.html
|
||||
|
||||
### Riconsiderare le best practice - JSConf.eu
|
||||
|
||||
<iframe width="650" height="366" src="https://www.youtube-nocookie.com/embed/x7cQ3mrcKaY" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/x7cQ3mrcKaY" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
"A Facebook e Instagram, con React stiamo provando a spingerci oltre i limiti di ciò che è possibile realizzare sul web. Il mio talk comincerà con una breve introduzione al framework, e poi approfondirà tre argomenti controversi: Gettare via la nozione dei template e costruire le viste con JavaScript, effettuare il “ri-rendering” dell'intera applicazione quando i dati cambiano, e un'implementazione leggera del DOM e degli eventi." -- [Pete Hunt](http://www.petehunt.net/)
|
||||
|
||||
@@ -23,7 +23,7 @@ Un video di [tagtree.tv](http://tagtree.tv/) che espone i principi di [Pensare i
|
||||
|
||||
### I Segreti del DOM Virtuale - MtnWest JS
|
||||
|
||||
<iframe width="650" height="366" src="https://www.youtube-nocookie.com/embed/h3KksH8gfcQ" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/h3KksH8gfcQ" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
"In questo talk discuterò perché abbiamo costruito un DOM virtuale, i vantaggi rispetto ad altri sistemi, e la sua rilevanza per il futuro della tecnologia dei browser." -- [Pete Hunt](http://www.petehunt.net/)
|
||||
|
||||
@@ -99,14 +99,14 @@ Un video di [tagtree.tv](http://tagtree.tv/) che espone i principi di [Pensare i
|
||||
|
||||
### Introduzione a React.js - Facebook Seattle
|
||||
|
||||
<iframe width="650" height="366" src="https://www.youtube-nocookie.com/embed/XxVg_s8xAms" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/XxVg_s8xAms" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
Di [Tom Occhino](http://tomocchino.com/) e [Jordan Walke](https://github.com/jordwalke)
|
||||
|
||||
* * *
|
||||
|
||||
### Backbone + React + Middleman Screencast
|
||||
<iframe width="650" height="488" src="https://www.youtube-nocookie.com/embed/iul1fWHVU6A" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="488" src="https://www.youtube-nocookie.com/embed/iul1fWHVU6A" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
Backbone è una grande maniera di interfacciare una API REST con React. Questo screencast mostra come integrare i due usando [Backbone-React-Component](https://github.com/magalhas/backbone-react-component). Middleman è il framework utilizzato in questo esempio, ma può essere facilmente sostituito con altri framework. Si può trovare un template supportato per questo esempio [qui](https://github.com/jbhatab/middleman-backbone-react-template). -- [Open Minded Innovations](http://www.openmindedinnovations.com/)
|
||||
|
||||
@@ -114,7 +114,7 @@ Backbone è una grande maniera di interfacciare una API REST con React. Questo s
|
||||
|
||||
### Sviluppare Interfacce Utente Con React - Super VanJS
|
||||
|
||||
<iframe width="650" height="366" src="https://www.youtube-nocookie.com/embed/1OeXsL5mr4g" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/1OeXsL5mr4g" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
Di [Steven Luscher](https://github.com/steveluscher)
|
||||
|
||||
@@ -122,7 +122,7 @@ Di [Steven Luscher](https://github.com/steveluscher)
|
||||
|
||||
### Introduzione a React - LAWebSpeed meetup
|
||||
|
||||
<iframe width="650" height="366" src="https://www.youtube-nocookie.com/embed/SMMRJif5QW0" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/SMMRJif5QW0" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
Di [Stoyan Stefanov](http://www.phpied.com/)
|
||||
|
||||
@@ -130,7 +130,7 @@ Di [Stoyan Stefanov](http://www.phpied.com/)
|
||||
|
||||
### React, o come rendere la vita più semplice - FrontEnd Dev Conf '14
|
||||
|
||||
<iframe width="650" height="366" src="https://www.youtube-nocookie.com/embed/YJNUK0EA_Jo" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/YJNUK0EA_Jo" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
**In Russo** di [Alexander Solovyov](http://solovyov.net/)
|
||||
|
||||
@@ -138,19 +138,19 @@ Di [Stoyan Stefanov](http://www.phpied.com/)
|
||||
|
||||
### "Programmazione funzionale del DOM" - Meteor DevShop 11
|
||||
|
||||
<iframe width="650" height="366" src="https://www.youtube-nocookie.com/embed/qqVbr_LaCIo" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/qqVbr_LaCIo" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
* * *
|
||||
|
||||
### "Ripensare lo Sviluppo di Applicazioni Web a Facebook" - Facebook F8 Conference 2014
|
||||
|
||||
<iframe width="650" height="366" src="https://www.youtube-nocookie.com/embed/nYkdrAPrdcw" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/nYkdrAPrdcw" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
* * *
|
||||
|
||||
### React e Flux: Costruire Applicazioni con un Flusso Dati Unidirezionale - Forward JS 2014
|
||||
|
||||
<iframe width="650" height="366" src="https://www.youtube-nocookie.com/embed/i__969noyAM" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/i__969noyAM" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
Gli ingegneri di Facebook [Bill Fisher](https://twitter.com/fisherwebdev) e [Jing Chen](https://twitter.com/jingc) parlano di Flux e React, e di come usare un'architettura dell'applicazione con un flusso di dati unidirezionale rende gran parte del loro codice più pulito.
|
||||
|
||||
@@ -158,7 +158,7 @@ Gli ingegneri di Facebook [Bill Fisher](https://twitter.com/fisherwebdev) e [Jin
|
||||
|
||||
### Rendering Lato Server di Applicazioni Isomorfiche a SoundCloud
|
||||
|
||||
<iframe src="https://player.vimeo.com/video/108488724" width="650" height="365" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
|
||||
<iframe src="https://player.vimeo.com/video/108488724" width="100%" height="365" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
|
||||
|
||||
[Andres Suarez](https://github.com/zertosh) ci accompagna alla scoperta di come [SoundCloud](https://developers.soundcloud.com/blog/) usa React e Flux per il rendering lato server.
|
||||
|
||||
@@ -168,6 +168,6 @@ Gli ingegneri di Facebook [Bill Fisher](https://twitter.com/fisherwebdev) e [Jin
|
||||
|
||||
### Introduzione a React Native (+Playlist) - React.js Conf 2015
|
||||
|
||||
<iframe width="650" height="366" src="https://www.youtube-nocookie.com/embed/KVZ-P-ZI6W4?list=PLb0IAmt7-GS1cbw4qonlQztYV1TAW0sCr" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/KVZ-P-ZI6W4?list=PLb0IAmt7-GS1cbw4qonlQztYV1TAW0sCr" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
[Tom Occhino](https://twitter.com/tomocchino) ripercorre il passato e il presente di React nel 2015, e ci mostra dove è diretto nell'immediato futuro.
|
||||
@@ -8,7 +8,7 @@ next: complementary-tools-ko-KR.html
|
||||
|
||||
### Rethinking best practices - JSConf.eu
|
||||
|
||||
<iframe width="650" height="366" src="https://www.youtube-nocookie.com/embed/x7cQ3mrcKaY" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/x7cQ3mrcKaY" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
"페이스북과 인스타그램에서, 우리는 React 를 이용해 웹에서 벌어질 수 있는 한계를 뛰어넘으려 노력하고 있습니다. 저는 프레임워크에 대한 짤막한 소개로 시작해서, 논쟁이 벌어질 수 있는 다음의 세가지 주제로 넘어갈겁니다. 템플릿의 개념을 버리고 JavaScript 를 이용해 View 를 구축하기, 자료가 변할때 전체 어플리케이션을 다시 그리기(“re-rendering”), 그리고 DOM과 events의 경량화된 구현 입니다." -- [Pete Hunt](http://www.petehunt.net/)
|
||||
|
||||
@@ -23,7 +23,7 @@ next: complementary-tools-ko-KR.html
|
||||
|
||||
### Secrets of the Virtual DOM - MtnWest JS
|
||||
|
||||
<iframe width="650" height="366" src="https://www.youtube-nocookie.com/embed/h3KksH8gfcQ" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/h3KksH8gfcQ" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
"이번에는 왜 우리가 virtual DOM을 만들었는지, 이것이 다른 시스템들과는 어떻게 다른지, 그리고 브라우져 기술들의 미래와 어떻게 관련이 있는지에 대해서 이야기 해 볼 겁니다." -- [Pete Hunt](http://www.petehunt.net/)
|
||||
|
||||
@@ -101,14 +101,14 @@ JavaScript Jabber 73에서 [Pete Hunt](http://www.petehunt.net/)와 [Jordan Walk
|
||||
|
||||
### Introduction to React.js - Facebook Seattle
|
||||
|
||||
<iframe width="650" height="366" src="https://www.youtube-nocookie.com/embed/XxVg_s8xAms" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/XxVg_s8xAms" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
By [Tom Occhino](http://tomocchino.com/), [Jordan Walke](https://github.com/jordwalke)
|
||||
|
||||
* * *
|
||||
|
||||
### Backbone + React + Middleman Screencast
|
||||
<iframe width="650" height="488" src="https://www.youtube-nocookie.com/embed/iul1fWHVU6A" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="488" src="https://www.youtube-nocookie.com/embed/iul1fWHVU6A" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
Backbone은 React로 REST API를 제공하기 위한 아주 좋은 방법입니다. 이 화면중개는 [Backbone-React-Component](https://github.com/magalhas/backbone-react-component)을 이용해서 어떻게 이 두가지를 연동하는지 보여줍니다. Middleman은 이 예제에서 사용되는 프레임워크이지만, 쉽게 다른 프레임워크로 대체하실 수 있습니다. 지원되는 템플릿은 [이곳](https://github.com/jbhatab/middleman-backbone-react-template)에서 찾으실 수 있습니다. -- [열린 마음의 혁명들](http://www.openmindedinnovations.com/)
|
||||
|
||||
@@ -116,7 +116,7 @@ Backbone은 React로 REST API를 제공하기 위한 아주 좋은 방법입니
|
||||
|
||||
### Developing User Interfaces With React - Super VanJS
|
||||
|
||||
<iframe width="650" height="366" src="https://www.youtube-nocookie.com/embed/1OeXsL5mr4g" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/1OeXsL5mr4g" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
By [Steven Luscher](https://github.com/steveluscher)
|
||||
|
||||
@@ -124,7 +124,7 @@ By [Steven Luscher](https://github.com/steveluscher)
|
||||
|
||||
### Introduction to React - LAWebSpeed meetup
|
||||
|
||||
<iframe width="650" height="366" src="https://www.youtube-nocookie.com/embed/SMMRJif5QW0" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/SMMRJif5QW0" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
by [Stoyan Stefanov](http://www.phpied.com/)
|
||||
|
||||
@@ -132,7 +132,7 @@ by [Stoyan Stefanov](http://www.phpied.com/)
|
||||
|
||||
### React, or how to make life simpler - FrontEnd Dev Conf '14
|
||||
|
||||
<iframe width="560" height="366" src="https://www.youtube-nocookie.com/embed/YJNUK0EA_Jo" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/YJNUK0EA_Jo" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
**러시아어** by [Alexander Solovyov](http://solovyov.net/)
|
||||
|
||||
@@ -140,19 +140,19 @@ by [Stoyan Stefanov](http://www.phpied.com/)
|
||||
|
||||
### "Functional DOM programming" - Meteor DevShop 11
|
||||
|
||||
<iframe width="650" height="366" src="https://www.youtube-nocookie.com/embed/qqVbr_LaCIo" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/qqVbr_LaCIo" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
* * *
|
||||
|
||||
### "Rethinking Web App Development at Facebook" - Facebook F8 Conference 2014
|
||||
|
||||
<iframe width="650" height="366" src="https://www.youtube-nocookie.com/embed/nYkdrAPrdcw" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/nYkdrAPrdcw" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
* * *
|
||||
|
||||
### React and Flux: Building Applications with a Unidirectional Data Flow - Forward JS 2014
|
||||
|
||||
<iframe width="650" height="366" src="https://www.youtube-nocookie.com/embed/i__969noyAM" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/i__969noyAM" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
Facebook 개발자 [Bill Fisher](https://twitter.com/fisherwebdev)와 [Jing Chen](https://twitter.com/jingc)가 Flux 와 React 에 대해서 이야기합니다. 그리고 어떻게 단일 방향의 자료흐름을 사용하는 어플리케이션 구조가 방대한 코드를 정리하는지에 대해서 이야기합니다."
|
||||
|
||||
@@ -160,7 +160,7 @@ Facebook 개발자 [Bill Fisher](https://twitter.com/fisherwebdev)와 [Jing Chen
|
||||
|
||||
### Server-Side Rendering of Isomorphic Apps at SoundCloud
|
||||
|
||||
<iframe src="https://player.vimeo.com/video/108488724" width="650" height="365" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe src="https://player.vimeo.com/video/108488724" width="100%" height="365" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
Server-side rendering을 위해 [SoundCloud](https://developers.soundcloud.com/blog/)가 React 와 Flux를 사용하는지 by [Andres Suarez](https://github.com/zertosh)
|
||||
[발표 자료와 예제 코드](https://github.com/zertosh/ssr-demo-kit)
|
||||
@@ -169,6 +169,6 @@ Server-side rendering을 위해 [SoundCloud](https://developers.soundcloud.com/b
|
||||
|
||||
### Introducing React Native (+Playlist) - React.js Conf 2015
|
||||
|
||||
<iframe width="650" height="366" src="https://www.youtube-nocookie.com/v/KVZ-P-ZI6W4&index=1&list=PLb0IAmt7-GS1cbw4qonlQztYV1TAW0sCr" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/v/KVZ-P-ZI6W4&index=1&list=PLb0IAmt7-GS1cbw4qonlQztYV1TAW0sCr" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
2015년에 [Tom Occhino](https://twitter.com/tomocchino)님이 React의 과거와 현재를 리뷰하고 나아갈 방향을 제시했습니다.
|
||||
180
docs/community/videos.md
Normal file
180
docs/community/videos.md
Normal file
@@ -0,0 +1,180 @@
|
||||
---
|
||||
id: videos
|
||||
title: Videos
|
||||
layout: community
|
||||
sectionid: community
|
||||
permalink: community/videos.html
|
||||
redirect_from: "docs/videos.html"
|
||||
---
|
||||
|
||||
### Introduction to React
|
||||
|
||||
[Tom Occhino](http://tomocchino.com/) and [Jordan Walke](https://github.com/jordwalke) introduce React at Facebook Seattle.
|
||||
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/XxVg_s8xAms" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
### Introducing React Native
|
||||
|
||||
[Tom Occhino](https://twitter.com/tomocchino) reviews the past and present of React in 2015, and teases where it's going next.
|
||||
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/KVZ-P-ZI6W4?list=PLb0IAmt7-GS1cbw4qonlQztYV1TAW0sCr" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
### Rethinking Web App Development at Facebook
|
||||
|
||||
Delivering reliable, high-performance web experiences at Facebook's scale has required us to challenge some long-held assumptions about software development. Watch this Facebook F8 2014 talk to learn how we abandoned the traditional MVC paradigm in favor of a more functional application architecture.
|
||||
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/nYkdrAPrdcw" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
### Secrets of the Virtual DOM
|
||||
|
||||
[Pete Hunt](http://www.petehunt.net/) at Mountain West JavaScript 2014 discusses why a virtual DOM was built for React, how it compares to other systems, and its relevance to the future of browser technologies.
|
||||
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/h3KksH8gfcQ" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
### Rethinking Best Practices
|
||||
|
||||
[Pete Hunt](http://www.petehunt.net/)'s talk at JSConf EU 2013 covers three topics: throwing out the notion of templates and building views with JavaScript, “re-rendering” your entire application when your data changes, and a lightweight implementation of the DOM and events.
|
||||
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/x7cQ3mrcKaY" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
|
||||
### High performance functional DOM programming
|
||||
|
||||
Tech Talk by [Pete Hunt](http://www.petehunt.net/) at Meteor DevShop 11.
|
||||
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/qqVbr_LaCIo" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
|
||||
### Developing User Interfaces With React
|
||||
|
||||
[Steven Luscher](https://github.com/steveluscher) at Super VanJS 2013.
|
||||
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/1OeXsL5mr4g" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
|
||||
### Introduction to React
|
||||
|
||||
[Stoyan Stefanov](http://www.phpied.com/) at LAWebSpeed meetup.
|
||||
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/SMMRJif5QW0" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
### Going big with React
|
||||
|
||||
Areeb Malik investigates how React performs in a high stress situation, and how it helped his team build safe code on a massive scale.
|
||||
|
||||
[](https://skillsmatter.com/skillscasts/5429-going-big-with-react#video)
|
||||
|
||||
### Backbone + React + Middleman Screencast
|
||||
|
||||
This screencast shows how to integrate Backbone with React using [Backbone-React-Component](https://github.com/magalhas/backbone-react-component).
|
||||
|
||||
<iframe width="100%" height="488" src="https://www.youtube-nocookie.com/embed/iul1fWHVU6A" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
### React, or how to make life simpler
|
||||
|
||||
Tech talk by [Alexander Solovyov](http://solovyov.net/) at FrontEnd Dev Conf '14 (Russian).
|
||||
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/YJNUK0EA_Jo" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
|
||||
### React and Flux: Building Applications with a Unidirectional Data Flow
|
||||
|
||||
Facebook engineers [Bill Fisher](https://twitter.com/fisherwebdev) and [Jing Chen](https://twitter.com/jingc) talk about Flux and React at Forward JS 2014, and how using an application architecture with a unidirectional data flow cleans up a lot of their code.
|
||||
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/i__969noyAM" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
### Server-Side Rendering of Isomorphic Apps at SoundCloud
|
||||
|
||||
Walk-through by [Andres Suarez](https://github.com/zertosh) on how [SoundCloud](https://developers.soundcloud.com/blog/) is using React and Flux for server-side rendering.
|
||||
|
||||
<iframe src="https://player.vimeo.com/video/108488724" width="100%" height="365" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
|
||||
|
||||
> [Slides and sample code](https://github.com/zertosh/ssr-demo-kit)
|
||||
|
||||
### CodeWinds Podcast
|
||||
|
||||
[Pete Hunt](http://www.petehunt.net/) talked with [Jeff Barczewski](http://jeff.barczewski.com/) about React in [CodeWinds Episode 4](http://codewinds.com/podcast/004.html).
|
||||
<figure>[](http://codewinds.com/4)</figure>
|
||||
|
||||
<table width="100%">
|
||||
<tr>
|
||||
<th>02:08</th><td>What is React and why use it?</td>
|
||||
<th>27:17</th><td>Rendering HTML on the server with Node.js. Rendering backends</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>03:08</th><td>The symbiotic relationship of ClojureScript and React</td>
|
||||
<th>29:20</th><td>React evolved through survival of the fittest at Facebook</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>04:54</th><td>The history of React and why it was created</td>
|
||||
<th>30:15</th><td>Ideas for having state on server and client, using web sockets.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>09:43</th><td>Updating web page with React without using data binding</td>
|
||||
<th>32:05</th><td>React-multiuser - distributed shared mutable state using Firebase</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>13:11</th><td>Using the virtual DOM to change the browser DOM</td>
|
||||
<th>33:03</th><td>Better debugging with React using the state transitions, replaying events</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>13:57</th><td>Programming with React, render targets HTML, canvas, other</td>
|
||||
<th>34:08</th><td>Differences from Web Components</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>16:45</th><td>Working with designers. Contrasted with Ember and AngularJS</td>
|
||||
<th>34:25</th><td>Notable companies using React</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>21:45</th><td>JSX Compiler bridging HTML and React javascript</td>
|
||||
<th>35:16</th><td>Could a React backend plugin be created to target PDF?</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>23:50</th><td>Autobuilding JSX and in browser tools for React</td>
|
||||
<th>36:30</th><td>Future of React, what's next?</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>24:50</th><td>Tips and tricks to working with React, getting started</td>
|
||||
<th>39:38</th><td>Contributing and getting help</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
### JavaScript Jabber Podcast
|
||||
|
||||
[Pete Hunt](http://www.petehunt.net/) and [Jordan Walke](https://github.com/jordwalke) talked about React in [JavaScript Jabber 73](https://devchat.tv/js-jabber/073-jsj-react-with-pete-hunt-and-jordan-walke).
|
||||
<figure>[](http://javascriptjabber.com/073-jsj-react-with-pete-hunt-and-jordan-walke/#content)</figure>
|
||||
|
||||
<table width="100%">
|
||||
<tr>
|
||||
<th>01:34</th><td>Pete Hunt Introduction</td>
|
||||
<th>23:06</th><td>Supporting Node.js</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>02:45</th><td>Jordan Walke Introduction</td>
|
||||
<th>24:03</th><td>rendr</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>04:15</th><td>React</td>
|
||||
<th>26:02</th><td>JSX</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>06:38</th><td>60 Frames Per Second</td>
|
||||
<th>30:31</th><td>requestAnimationFrame</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>09:34</th><td>Data Binding</td>
|
||||
<th>34:15</th><td>React and Applications</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>12:31</th><td>Performance</td>
|
||||
<th>38:12</th><td>React Users Khan Academy</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>17:39</th><td>Diffing Algorithm</td>
|
||||
<th>39:53</th><td>Making it work</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>19:36</th><td>DOM Manipulation</td>
|
||||
<th></th><td></td>
|
||||
</tr>
|
||||
</table>
|
||||
@@ -8,7 +8,7 @@ next: complementary-tools-zh-CN.html
|
||||
|
||||
### Rethinking best practices - JSConf.eu
|
||||
|
||||
<iframe width="650" height="366" src="https://www.youtube-nocookie.com/embed/x7cQ3mrcKaY" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/x7cQ3mrcKaY" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
"在 Facebook 和 Instagram, 我们正在努力挑战React在web上能达到的极限。我的讲话会从对框架的简单介绍开始,然后深入三个有争议的话题:扔掉模板的概念并用JavaScript构建views, 当数据改变 “re-rendering” 你的整个应用,以及一个DOM和events的轻量级实现。" -- [Pete Hunt](http://www.petehunt.net/)
|
||||
|
||||
@@ -23,7 +23,7 @@ next: complementary-tools-zh-CN.html
|
||||
|
||||
### Secrets of the Virtual DOM - MtnWest JS
|
||||
|
||||
<iframe width="650" height="366" src="https://www.youtube-nocookie.com/embed/h3KksH8gfcQ" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/h3KksH8gfcQ" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
"在这次讲座里,我会讨论为什么我们构建了一个虚拟 DOM,它比起其他系统如何,以及它与未来浏览器技术的关系。" -- [Pete Hunt](http://www.petehunt.net/)
|
||||
|
||||
@@ -99,14 +99,14 @@ next: complementary-tools-zh-CN.html
|
||||
|
||||
### Introduction to React.js - Facebook Seattle
|
||||
|
||||
<iframe width="650" height="366" src="https://www.youtube-nocookie.com/embed/XxVg_s8xAms" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/XxVg_s8xAms" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
由 [Tom Occhino](http://tomocchino.com/) 和 [Jordan Walke](https://github.com/jordwalke)
|
||||
|
||||
* * *
|
||||
|
||||
### Backbone + React + Middleman Screencast
|
||||
<iframe width="650" height="488" src="https://www.youtube-nocookie.com/embed/iul1fWHVU6A" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="488" src="https://www.youtube-nocookie.com/embed/iul1fWHVU6A" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
Backbone 是一个在用React实现 REST API 接口的极好方法。这个屏博展示了用 [Backbone-React-Component](https://github.com/magalhas/backbone-react-component)如何整合两者. Middleman 是在本例中使用的框架但很容易被替换成其他框架。对此可支持的template可以在[这里](https://github.com/jbhatab/middleman-backbone-react-template) 找到. -- [Open Minded Innovations](http://www.openmindedinnovations.com/)
|
||||
|
||||
@@ -114,7 +114,7 @@ Backbone 是一个在用React实现 REST API 接口的极好方法。这个屏
|
||||
|
||||
### Developing User Interfaces With React - Super VanJS
|
||||
|
||||
<iframe width="650" height="366" src="https://www.youtube-nocookie.com/embed/1OeXsL5mr4g" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/1OeXsL5mr4g" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
来自 [Steven Luscher](https://github.com/steveluscher)
|
||||
|
||||
@@ -122,7 +122,7 @@ Backbone 是一个在用React实现 REST API 接口的极好方法。这个屏
|
||||
|
||||
### Introduction to React - LAWebSpeed meetup
|
||||
|
||||
<iframe width="650" height="366" src="https://www.youtube-nocookie.com/embed/SMMRJif5QW0" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/SMMRJif5QW0" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
来自 [Stoyan Stefanov](http://www.phpied.com/)
|
||||
|
||||
@@ -130,7 +130,7 @@ Backbone 是一个在用React实现 REST API 接口的极好方法。这个屏
|
||||
|
||||
### React, or how to make life simpler - FrontEnd Dev Conf '14
|
||||
|
||||
<iframe width="650" height="366" src="https://www.youtube-nocookie.com/embed/YJNUK0EA_Jo" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/YJNUK0EA_Jo" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
**俄语** by [Alexander Solovyov](http://solovyov.net/)
|
||||
|
||||
@@ -138,19 +138,19 @@ Backbone 是一个在用React实现 REST API 接口的极好方法。这个屏
|
||||
|
||||
### "Functional DOM programming" - Meteor DevShop 11
|
||||
|
||||
<iframe width="650" height="366" src="https://www.youtube-nocookie.com/embed/qqVbr_LaCIo" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/qqVbr_LaCIo" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
* * *
|
||||
|
||||
### "Rethinking Web App Development at Facebook" - Facebook F8 Conference 2014
|
||||
|
||||
<iframe width="650" height="366" src="https://www.youtube-nocookie.com/embed/nYkdrAPrdcw" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/nYkdrAPrdcw" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
* * *
|
||||
|
||||
### React and Flux: Building Applications with a Unidirectional Data Flow - Forward JS 2014
|
||||
|
||||
<iframe width="650" height="366" src="https://www.youtube-nocookie.com/embed/i__969noyAM" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/i__969noyAM" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
Facebook 工程师 [Bill Fisher](https://twitter.com/fisherwebdev) 和 [Jing Chen](https://twitter.com/jingc) 谈论 Flux 和 React, 以及如何使用单向数据流的程序架构清理他们的代码 .
|
||||
|
||||
@@ -158,7 +158,7 @@ Facebook 工程师 [Bill Fisher](https://twitter.com/fisherwebdev) 和 [Jing Che
|
||||
|
||||
### Server-Side Rendering of Isomorphic Apps at SoundCloud
|
||||
|
||||
<iframe src="https://player.vimeo.com/video/108488724" width="650" height="365" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
|
||||
<iframe src="https://player.vimeo.com/video/108488724" width="100%" height="365" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
|
||||
|
||||
来自 [Andres Suarez](https://github.com/zertosh) 的演练,关于 [SoundCloud](https://developers.soundcloud.com/blog/) 如何使用 React 和 Flux 在服务器端渲染.
|
||||
|
||||
@@ -168,6 +168,6 @@ Facebook 工程师 [Bill Fisher](https://twitter.com/fisherwebdev) 和 [Jing Che
|
||||
|
||||
### Introducing React Native (+Playlist) - React.js Conf 2015
|
||||
|
||||
<iframe width="650" height="366" src="https://www.youtube-nocookie.com/embed/KVZ-P-ZI6W4?list=PLb0IAmt7-GS1cbw4qonlQztYV1TAW0sCr" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="100%" height="366" src="https://www.youtube-nocookie.com/embed/KVZ-P-ZI6W4?list=PLb0IAmt7-GS1cbw4qonlQztYV1TAW0sCr" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
[Tom Occhino](https://twitter.com/tomocchino) 回顾了React的过去和现在,在2015年。梳理了下一步要做什么。
|
||||
412
docs/contributing/codebase-overview.md
Normal file
412
docs/contributing/codebase-overview.md
Normal file
@@ -0,0 +1,412 @@
|
||||
---
|
||||
id: codebase-overview
|
||||
title: Codebase Overview
|
||||
layout: contributing
|
||||
permalink: contributing/codebase-overview.html
|
||||
prev: how-to-contribute.html
|
||||
next: implementation-notes.html
|
||||
---
|
||||
|
||||
This section will give you an overview of the React codebase organization, its conventions, and the implementation.
|
||||
|
||||
If you want to [contribute to React](/react/contributing/how-to-contribute.html) we hope that this guide will help you feel more comfortable making changes.
|
||||
|
||||
We don't necessarily recommend any of these conventions in React apps. Many of them exist for historical reasons and might change with time.
|
||||
|
||||
### Custom Module System
|
||||
|
||||
At Facebook, internally we use a custom module system called "Haste". It is similar to [CommonJS](https://nodejs.org/docs/latest/api/modules.html) and also uses `require()` but has a few important differences that often confuse outside contributors.
|
||||
|
||||
In CommonJS, when you import a module, you need to specify its relative path:
|
||||
|
||||
```js
|
||||
// Importing from the same folder:
|
||||
var setInnerHTML = require('./setInnerHTML');
|
||||
|
||||
// Importing from a different folder:
|
||||
var setInnerHTML = require('../utils/setInnerHTML');
|
||||
|
||||
// Importing from a deeply nested folder:
|
||||
var setInnerHTML = require('../client/utils/setInnerHTML');
|
||||
```
|
||||
|
||||
However, with Haste **all filenames are globally unique.** In the React codebase, you can import any module from any other module by its name alone:
|
||||
|
||||
```js
|
||||
var setInnerHTML = require('setInnerHTML');
|
||||
```
|
||||
|
||||
Haste was originally developed for giant apps like Facebook. It's easy to move files to different folders and import them without worrying about relative paths. The fuzzy file search in any editor always takes you to the correct place thanks to globally unique names.
|
||||
|
||||
React itself was extracted from the Facebook codebase and uses Haste for historical reasons. In the future, we will probably [migrate React to use CommonJS or ES Modules](https://github.com/facebook/react/issues/6336) to be more aligned with the community. However, this requires changes in Facebook internal infrastructure so it is unlikely to happen very soon.
|
||||
|
||||
**Haste will make more sense to you if you remember a few rules:**
|
||||
|
||||
* All filenames in the React source code are unique. This is why they're sometimes verbose.
|
||||
* When you add a new file, make sure you include a [license header](https://github.com/facebook/react/blob/87724bd87506325fcaf2648c70fc1f43411a87be/src/renderers/dom/client/utils/setInnerHTML.js#L1-L10). You can copy it from any existing file. A license header always includes [a line like this](https://github.com/facebook/react/blob/87724bd87506325fcaf2648c70fc1f43411a87be/src/renderers/dom/client/utils/setInnerHTML.js#L9). Change it to match the name of the file you created.
|
||||
* Don’t use relative paths when importing. Instead of `require('./setInnerHTML')`, write `require('setInnerHTML')`.
|
||||
|
||||
When we compile React for npm, a script copies all the modules into [a single flat directory called `lib`](https://unpkg.com/react@15/lib/) and prepends all `require()` paths with `./`. This way Node, Browserify, Webpack, and other tools can understand React build output without being aware of Haste.
|
||||
|
||||
**If you're reading React source on GitHub and want to jump to a file, press "t".**
|
||||
|
||||
This is a GitHub shortcut for searching the current repo for fuzzy filename matches. Start typing the name of the file you are looking for, and it will show up as the first match.
|
||||
|
||||
### External Dependencies
|
||||
|
||||
React has almost no external dependencies. Usually, a `require()` points to a file in React's own codebase. However, there are a few relatively rare exceptions.
|
||||
|
||||
If you see a `require()` that does not correspond to a file in the React repository, you can look in a special repository called [fbjs](https://github.com/facebook/fbjs). For example, `require('warning')` will resolve to the [`warning` module from fbjs](https://github.com/facebook/fbjs/blob/df9047fec0bbd1e64635ae369c045975777cba7c/packages/fbjs/src/__forks__/warning.js).
|
||||
|
||||
The [fbjs repository](https://github.com/facebook/fbjs) exists because React shares some small utilities with libraries like [Relay](https://github.com/facebook/relay), and we keep them in sync. We don't depend on equivalent small modules in the Node ecosystem because we want Facebook engineers to be able to make changes to them whenever necessary. None of the utilities inside fbjs are considered to be public API, and they are only intended for use by Facebook projects such as React.
|
||||
|
||||
### Top-Level Folders
|
||||
|
||||
After cloning the [React repository](https://github.com/facebook/react), you will see a few top-level folders in it:
|
||||
|
||||
* [`src`](https://github.com/facebook/react/tree/master/src) is the source code of React. **If your change is related to the code, `src` is where you'll spend most of your time.**
|
||||
* [`docs`](https://github.com/facebook/react/tree/master/docs) is the React documentation website. When you change APIs, make sure to update the relevant Markdown files.
|
||||
* [`examples`](https://github.com/facebook/react/tree/master/examples) contains a few small React demos with different build setups.
|
||||
* [`packages`](https://github.com/facebook/react/tree/master/packages) contains metadata (such as `package.json`) for all packages in the React repository. Nevertheless, their source code is still located inside [`src`](https://github.com/facebook/react/tree/master/src).
|
||||
* `build` is the build output of React. It is not in the repository but it will appear in your React clone after you [build it](/react/contributing/how-to-contribute.html#development-workflow) for the first time.
|
||||
|
||||
There are a few other top-level folders but they are mostly used for the tooling and you likely won't ever encounter them when contributing.
|
||||
|
||||
### Colocated Tests
|
||||
|
||||
We don't have a top-level directory for unit tests. Instead, we put them into a directory called `__tests__` relative to the files that they test.
|
||||
|
||||
For example, a test for [`setInnerHTML.js`](https://github.com/facebook/react/blob/87724bd87506325fcaf2648c70fc1f43411a87be/src/renderers/dom/client/utils/setInnerHTML.js) is located in [`__tests__/setInnerHTML-test.js`](https://github.com/facebook/react/blob/87724bd87506325fcaf2648c70fc1f43411a87be/src/renderers/dom/client/utils/__tests__/setInnerHTML-test.js) right next to it.
|
||||
|
||||
### Shared Code
|
||||
|
||||
Even though Haste allows us to import any module from anywhere in the repository, we follow a convention to avoid cyclic dependencies and other unpleasant surprises. By convention, a file may only import files in the same folder or in subfolders below.
|
||||
|
||||
For example, files inside [`src/renderers/dom/client`](https://github.com/facebook/react/tree/master/src/renderers/dom/client) may import other files in the same folder or any folder below.
|
||||
|
||||
However they can't import modules from [`src/renderers/dom/server`](https://github.com/facebook/react/tree/master/src/renderers/dom/server) because it is not a child directory of [`src/renderers/dom/client`](https://github.com/facebook/react/tree/master/src/renderers/dom/client).
|
||||
|
||||
There is an exception to this rule. Sometimes we *do* need to share functionality between two groups of modules. In this case, we hoist the shared module up to a folder called `shared` inside the closest common ancestor folder of the modules that need to rely on it.
|
||||
|
||||
For example, code shared between [`src/renderers/dom/client`](https://github.com/facebook/react/tree/master/src/renderers/dom/client) and [`src/renderers/dom/server`](https://github.com/facebook/react/tree/master/src/renderers/dom/server) lives in [`src/renderers/dom/shared`](https://github.com/facebook/react/tree/master/src/renderers/dom/shared).
|
||||
|
||||
By the same logic, if [`src/renderers/dom/client`](https://github.com/facebook/react/tree/master/src/renderers/dom/client) needs to share a utility with something in [`src/renderers/native`](https://github.com/facebook/react/tree/master/src/renderers/native), this utility would be in [`src/renderers/shared`](https://github.com/facebook/react/tree/master/src/renderers/shared).
|
||||
|
||||
This convention is not enforced but we check for it during a pull request review.
|
||||
|
||||
### Warnings and Invariants
|
||||
|
||||
The React codebase uses the `warning` module to display warnings:
|
||||
|
||||
```js
|
||||
var warning = require('warning');
|
||||
|
||||
warning(
|
||||
2 + 2 === 4,
|
||||
'Math is not working today.'
|
||||
);
|
||||
```
|
||||
|
||||
**The warning is shown when the `warning` condition is `false`.**
|
||||
|
||||
One way to think about it is that the condition should reflect the normal situation rather than the exceptional one.
|
||||
|
||||
It is a good idea to avoid spamming the console with duplicate warnings:
|
||||
|
||||
````js
|
||||
var warning = require('warning');
|
||||
|
||||
var didWarnAboutMath = false;
|
||||
if (!didWarnAboutMath) {
|
||||
warning(
|
||||
2 + 2 === 4,
|
||||
'Math is not working today.'
|
||||
);
|
||||
didWarnAboutMath = true;
|
||||
}
|
||||
```
|
||||
|
||||
Warnings are only enabled in development. In production, they are completely stripped out. If you need to forbid some code path from executing, use `invariant` module instead:
|
||||
|
||||
```js
|
||||
var invariant = require('invariant');
|
||||
|
||||
invariant(
|
||||
2 + 2 === 4,
|
||||
'You shall not pass!'
|
||||
);
|
||||
```
|
||||
|
||||
**The invariant is thrown when the `invariant` condition is `false`.**
|
||||
|
||||
"Invariant" is just a way of saying "this condition always holds true". You can think about it as making an assertion.
|
||||
|
||||
It is important to keep development and production behavior similar, so `invariant` throws both in development and in production. The error messages are automatically replaced with error codes in production to avoid negatively affecting the byte size.
|
||||
|
||||
### Development and Production
|
||||
|
||||
You can use `__DEV__` pseudo-global variable in the codebase to guard development-only blocks of code.
|
||||
|
||||
It is inlined during the compile step, and turns into `process.env.NODE_ENV !== 'production'` checks in the CommonJS builds.
|
||||
|
||||
For standalone builds, it becomes `true` in the unminified build, and gets completely stripped out with the `if` blocks it guards in the minified build.
|
||||
|
||||
```js
|
||||
if (__DEV__) {
|
||||
// This code will only run in development.
|
||||
}
|
||||
```
|
||||
|
||||
### JSDoc
|
||||
|
||||
Some of the internal and public methods are annotated with [JSDoc annotations](http://usejsdoc.org/):
|
||||
|
||||
```js
|
||||
/**
|
||||
* Updates this component by updating the text content.
|
||||
*
|
||||
* @param {ReactText} nextText The next text content
|
||||
* @param {ReactReconcileTransaction} transaction
|
||||
* @internal
|
||||
*/
|
||||
receiveComponent: function(nextText, transaction) {
|
||||
// ...
|
||||
},
|
||||
```
|
||||
|
||||
We try to keep existing annotations up-to-date but we don't enforce them. We don't use JSDoc in the newly written code, and instead use Flow to document and enforce types.
|
||||
|
||||
### Flow
|
||||
|
||||
We recently started introducing [Flow](https://flowtype.org/) checks to the codebase. Files marked with the `@flow` annotation in the license header comment are being typechecked.
|
||||
|
||||
We accept pull requests [adding Flow annotations to existing code](https://github.com/facebook/react/pull/7600/files). Flow annotations look like this:
|
||||
|
||||
```js
|
||||
ReactRef.detachRefs = function(
|
||||
instance: ReactInstance,
|
||||
element: ReactElement | string | number | null | false,
|
||||
): void {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
When possible, new code should use Flow annotations.
|
||||
You can run `npm run flow` locally to check your code with Flow.
|
||||
|
||||
### Classes and Mixins
|
||||
|
||||
React was originally written in ES5. We have since enabled ES6 features with [Babel](http://babeljs.io/), including classes. However, most of React code is still written in ES5.
|
||||
|
||||
In particular, you might see the following pattern quite often:
|
||||
|
||||
```js
|
||||
// Constructor
|
||||
function ReactDOMComponent(element) {
|
||||
this._currentElement = element;
|
||||
}
|
||||
|
||||
// Methods
|
||||
ReactDOMComponent.Mixin = {
|
||||
mountComponent: function() {
|
||||
// ...
|
||||
}
|
||||
};
|
||||
|
||||
// Put methods on the prototype
|
||||
Object.assign(
|
||||
ReactDOMComponent.prototype,
|
||||
ReactDOMComponent.Mixin
|
||||
);
|
||||
|
||||
module.exports = ReactDOMComponent;
|
||||
```
|
||||
|
||||
The `Mixin` in this code has no relation to React `mixins` feature. It is just a way of grouping a few methods under an object. Those methods may later get attached to some other class. We use this pattern in a few places although we try to avoid it in the new code.
|
||||
|
||||
Equivalent code in ES6 would like this:
|
||||
|
||||
```js
|
||||
class ReactDOMComponent {
|
||||
constructor(element) {
|
||||
this._currentElement = element;
|
||||
}
|
||||
|
||||
mountComponent() {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ReactDOMComponent;
|
||||
```
|
||||
|
||||
Sometimes we [convert old code to ES6 classes](https://github.com/facebook/react/pull/7647/files). However, this is not very important to us because there is an [ongoing effort](#fiber-reconciler) to replace the React reconciler implementation with a less object-oriented approach which wouldn't use classes at all.
|
||||
|
||||
### Dynamic Injection
|
||||
|
||||
React uses dynamic injection in some modules. While it is always explicit, it is still unfortunate because it hinders understanding of the code. The main reason it exists is because React originally only supported DOM as a target. React Native started as a React fork. We had to add dynamic injection to let React Native override some behaviors.
|
||||
|
||||
You may see modules declaring their dynamic dependencies like this:
|
||||
|
||||
```js
|
||||
// Dynamically injected
|
||||
var textComponentClass = null;
|
||||
|
||||
// Relies on dynamically injected value
|
||||
function createInstanceForText(text) {
|
||||
return new textComponentClass(text);
|
||||
}
|
||||
|
||||
var ReactHostComponent = {
|
||||
createInstanceForText,
|
||||
|
||||
// Provides an opportunity for dynamic injection
|
||||
injection: {
|
||||
injectTextComponentClass: function(componentClass) {
|
||||
textComponentClass = componentClass;
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = ReactHostComponent;
|
||||
```
|
||||
|
||||
The `injection` field is not handled specially in any way. But by convention, it means that this module wants to have some (presumably platform-specific) dependencies injected into it at runtime.
|
||||
|
||||
In React DOM, [`ReactDefaultInjection`](https://github.com/facebook/react/blob/4f345e021a6bd9105f09f3aee6d8762eaa9db3ec/src/renderers/dom/shared/ReactDefaultInjection.js) injects a DOM-specific implementation:
|
||||
|
||||
```js
|
||||
ReactHostComponent.injection.injectTextComponentClass(ReactDOMTextComponent);
|
||||
```
|
||||
|
||||
In React Native, [`ReactNativeDefaultInjection`](https://github.com/facebook/react/blob/4f345e021a6bd9105f09f3aee6d8762eaa9db3ec/src/renderers/native/ReactNativeDefaultInjection.js) injects its own implementation:
|
||||
|
||||
```js
|
||||
ReactHostComponent.injection.injectTextComponentClass(ReactNativeTextComponent);
|
||||
```
|
||||
|
||||
There are multiple injection points in the codebase. In the future, we intend to get rid of the dynamic injection mechanism and wire up all the pieces statically during the build.
|
||||
|
||||
### Multiple Packages
|
||||
|
||||
React is a [monorepo](http://danluu.com/monorepo/). Its repository contains multiple separate packages so that their changes can be coordinated together, and documentation and issues live in one place.
|
||||
|
||||
The npm metadata such as `package.json` files is located in the [`packages`](https://github.com/facebook/react/tree/master/packages) top-level folder. However, there is almost no real code in it.
|
||||
|
||||
For example, [`packages/react/react.js`](https://github.com/facebook/react/blob/87724bd87506325fcaf2648c70fc1f43411a87be/packages/react/react.js) re-exports [`src/isomorphic/React.js`](https://github.com/facebook/react/blob/87724bd87506325fcaf2648c70fc1f43411a87be/src/isomorphic/React.js), the real npm entry point. Other packages mostly repeat this pattern. All the important code lives in [`src`](https://github.com/facebook/react/tree/master/src).
|
||||
|
||||
While the code is separated in the source tree, the exact package boundaries are slightly different for npm packages and standalone browser builds.
|
||||
|
||||
### React Core
|
||||
|
||||
The "core" of React includes all the [top-level `React` APIs](/react/docs/top-level-api.html#react), for example:
|
||||
|
||||
* `React.createElement()`
|
||||
* `React.createClass()`
|
||||
* `React.Component`
|
||||
* `React.Children`
|
||||
* `React.PropTypes`
|
||||
|
||||
**React core only includes the APIs necessary to define components.** It does not include the [reconciliation](/react/docs/reconciliation.html) algorithm or any platform-specific code. It is used both by React DOM and React Native components.
|
||||
|
||||
The code for React core is located in [`src/isomorphic`](https://github.com/facebook/react/tree/master/src/isomorphic) in the source tree. It is available on npm as the [`react`](https://www.npmjs.com/package/react) package. The corresponding standalone browser build is called `react.js`, and it exports a global called `React`.
|
||||
|
||||
>**Note:**
|
||||
>
|
||||
>Until very recently, `react` npm package and `react.js` standalone build contained all React code (including React DOM) rather than just the core. This was done for backward compatibility and historical reasons. Since React 15.4.0, the core is better separated in the build output.
|
||||
>
|
||||
>There is also an additional standalone browser build called `react-with-addons.js` which we will consider separately further below.
|
||||
|
||||
### Renderers
|
||||
|
||||
React was originally created for the DOM but it was later adapted to also support native platforms with [React Native](http://facebook.github.io/react-native/). This introduced the concept of "renderers" to React internals.
|
||||
|
||||
**Renderers manage how a React tree turns into the underlying platform calls.**
|
||||
|
||||
Renderers are located in [`src/renderers`](https://github.com/facebook/react/tree/master/src/renderers/):
|
||||
|
||||
* [React DOM Renderer](https://github.com/facebook/react/tree/master/src/renderers/dom) renders React components to the DOM. It implements [top-level `ReactDOM` APIs](/react/docs/top-level-api.html#reactdom) and is available as [`react-dom`](https://www.npmjs.com/package/react-dom) npm package. It can also be used as standalone browser bundle called `react-dom.js` that exports a `ReactDOM` global.
|
||||
* [React Native Renderer](https://github.com/facebook/react/tree/master/src/renderers/native) renders React components to native views. It is used internally by React Native via [`react-native-renderer`](https://www.npmjs.com/package/react-native-renderer) npm package. In the future a copy of it may get checked into the React Native [repository](https://github.com/facebook/react-native) so that React Native can update React at its own pace.
|
||||
* [React Test Renderer](https://github.com/facebook/react/tree/master/src/renderers/testing) renders React components to JSON trees. It is used by the [Snapshot Testing](https://facebook.github.io/jest/blog/2016/07/27/jest-14.html) feature of [Jest](https://facebook.github.io/jest) and is available as [react-test-renderer](https://www.npmjs.com/package/react-test-renderer) npm package.
|
||||
|
||||
The only other officially supported renderer is [`react-art`](https://github.com/reactjs/react-art). To avoid accidentally breaking it as we make changes to React, we checked it in as [`src/renderers/art`](https://github.com/facebook/react/tree/master/src/renderers/art) and run its test suite. Nevertheless, its [GitHub repository](https://github.com/reactjs/react-art) still acts as the source of truth.
|
||||
|
||||
While it is [technically possible](https://github.com/iamdustan/tiny-react-renderer) to create custom React renderer, this is currently not officially supported. There is no stable public contract for custom renderers yet which is another reason why we keep them all in a single place.
|
||||
|
||||
>**Note:**
|
||||
>
|
||||
>Technically the [`native`](https://github.com/facebook/react/tree/master/src/renderers/native) renderer is a very thin layer that teaches React to interact with React Native implementation. The real platform-specific code managing the native views lives in the [React Native repository](https://github.com/facebook/react-native) together with its components.
|
||||
|
||||
### Reconcilers
|
||||
|
||||
Even vastly different renderers like React DOM and React Native need to share a lot of logic. In particular, the [reconciliation](/react/docs/reconciliation.html) algorithm should be as similar as possible so that declarative rendering, custom components, state, lifecycle methods, and refs work consistently across platforms.
|
||||
|
||||
To solve this, different renderers share some code between them. We call this part of React a "reconciler". When an update such as `setState()` is scheduled, the reconciler calls `render()` on components in the tree and mounts, updates, or unmounts them.
|
||||
|
||||
Reconcilers are not packaged separately because they currently have no public API. Instead, they are exclusively used by renderers such as React DOM and React Native.
|
||||
|
||||
### Stack Reconciler
|
||||
|
||||
The "stack" reconciler is the one powering all React production code today. It is located in [`src/renderers/shared/stack/reconciler`](https://github.com/facebook/react/tree/master/src/renderers/shared/stack) and is used by both React DOM and React Native.
|
||||
|
||||
It is written in an [object-oriented way](https://en.wikipedia.org/wiki/Composite_pattern) and maintains a separate tree of "internal instances" for all React components. The internal instances exist both for user-defined ("composite") and platform-specific ("host") components. The internal instances are inaccessible directly to the user, and their tree is never exposed.
|
||||
|
||||
When a component mounts, updates, or unmounts, the stack reconciler calls a method on that internal instance. The methods are called `mountComponent(element)`, `receiveComponent(nextElement)`, and `unmountComponent(element)`.
|
||||
|
||||
#### Host Components
|
||||
|
||||
Platform-specific ("host") components, such as `<div>` or a `<View>`, run platform-specific code. For example, React DOM instructs the stack reconciler to use [`ReactDOMComponent`](https://github.com/facebook/react/blob/87724bd87506325fcaf2648c70fc1f43411a87be/src/renderers/dom/shared/ReactDOMComponent.js) to handle [mounting](https://github.com/facebook/react/blob/87724bd87506325fcaf2648c70fc1f43411a87be/src/renderers/dom/shared/ReactDOMComponent.js#L517), [updates](https://github.com/facebook/react/blob/87724bd87506325fcaf2648c70fc1f43411a87be/src/renderers/dom/shared/ReactDOMComponent.js#L865), and [unmounting](https://github.com/facebook/react/blob/87724bd87506325fcaf2648c70fc1f43411a87be/src/renderers/dom/shared/ReactDOMComponent.js#L1140) of DOM components.
|
||||
|
||||
Regardless of the platform, both `<div>` and `<View>` handle managing multiple children in a similar way. For convenience, the stack reconciler provides a helper called [`ReactMultiChild`](https://github.com/facebook/react/blob/87724bd87506325fcaf2648c70fc1f43411a87be/src/renderers/shared/stack/reconciler/ReactMultiChild.js) that both DOM and Native renderers [use](https://github.com/facebook/react/blob/87724bd87506325fcaf2648c70fc1f43411a87be/src/renderers/dom/shared/ReactDOMComponent.js#L1203).
|
||||
|
||||
#### Composite Components
|
||||
|
||||
User-defined ("composite") components should behave the same way with all renderers. This is why the stack reconciler provides a shared implementation in [`ReactCompositeComponent`](https://github.com/facebook/react/blob/87724bd87506325fcaf2648c70fc1f43411a87be/src/renderers/shared/stack/reconciler/ReactCompositeComponent.js). It is always the same regardless of the renderer.
|
||||
|
||||
Composite components also implement [mounting](https://github.com/facebook/react/blob/87724bd87506325fcaf2648c70fc1f43411a87be/src/renderers/shared/stack/reconciler/ReactCompositeComponent.js#L181), [updating](https://github.com/facebook/react/blob/87724bd87506325fcaf2648c70fc1f43411a87be/src/renderers/shared/stack/reconciler/ReactCompositeComponent.js#L703), and [unmounting](https://github.com/facebook/react/blob/87724bd87506325fcaf2648c70fc1f43411a87be/src/renderers/shared/stack/reconciler/ReactCompositeComponent.js#L524). However, unlike host components, `ReactCompositeComponent` needs to behave differently depending on user's code. This is why it calls methods, such as `render()` and `componentDidMount()`, on the user-supplied class.
|
||||
|
||||
During an update, `ReactCompositeComponent` checks whether the `render()` output has a different `type` or `key` than the last time. If neither `type` nor `key` has changed, it delegates the update to the existing child internal instance. Otherwise, it unmounts the old child instance and mounts a new one. This is described in the [reconciliation algorithm](/react/docs/reconciliation.html).
|
||||
|
||||
#### Recursion
|
||||
|
||||
During an update, the stack reconciler "drills down" through composite components, runs their `render()` methods, and decides whether to update or replace their single child instance. It executes platform-specific code as it passes through the host components like `<div>` and `<View>`. Host components may have multiple children which are also processed recursively.
|
||||
|
||||
It is important to understand that the stack reconciler always processes the component tree synchronously in a single pass. While individual tree branches may [bail out of reconciliation](/react/docs/advanced-performance.html#avoiding-reconciling-the-dom), the stack reconciler can't pause, and so it is suboptimal when the updates are deep and the available CPU time is limited.
|
||||
|
||||
#### Learn More
|
||||
|
||||
**The [next section](/react/contributing/implementation-notes.html) describes the current implementation in more details.**
|
||||
|
||||
### Fiber Reconciler
|
||||
|
||||
The "fiber" reconciler is a new effort aiming to resolve the problems inherent in the stack reconciler and fix a few long-standing issues.
|
||||
|
||||
It is a complete rewrite of the reconciler and is currently [in active development](https://github.com/facebook/react/pulls?utf8=%E2%9C%93&q=is%3Apr%20is%3Aopen%20fiber).
|
||||
|
||||
Its main goals are:
|
||||
|
||||
* Ability to split interruptible work in chunks.
|
||||
* Ability to prioritize, rebase and reuse work in progress.
|
||||
* Ability to yield back and forth between parents and children to support layout in React.
|
||||
* Ability to return multiple elements from `render()`.
|
||||
* Better support for error boundaries.
|
||||
|
||||
You can read more about it in [React Fiber Architecture](https://github.com/acdlite/react-fiber-architecture). At this moment, it is still very experimental, and far from feature parity with the stack reconciler.
|
||||
|
||||
Its source code is located in [`src/renderers/shared/fiber`](https://github.com/facebook/react/tree/master/src/renderers/shared/fiber).
|
||||
|
||||
### Event System
|
||||
|
||||
React implements a synthetic event system which is agnostic of the renderers and works both with React DOM and React Native. Its source code is located in [`src/renderers/shared/shared/event`](https://github.com/facebook/react/tree/master/src/renderers/shared/shared/event).
|
||||
|
||||
There is a [video with a deep code dive into it](https://www.youtube.com/watch?v=dRo_egw7tBc) (66 mins).
|
||||
|
||||
### Add-ons
|
||||
|
||||
Each of the [React add-ons](/react/docs/addons.html) ships as a separate package on npm with a `react-addons-` prefix. Their source is located in [`src/addons`](https://github.com/facebook/react/tree/master/src/addons) with the exception of [`ReactPerf`](https://github.com/facebook/react/blob/master/src/renderers/shared/ReactPerf.js) and [`ReactTestUtils`](https://github.com/facebook/react/blob/master/src/test/ReactTestUtils.js).
|
||||
|
||||
Additionally, we provide a standalone build called `react-with-addons.js` which includes React core *and* all add-ons exposed on the `addons` field of the `React` global object.
|
||||
|
||||
### What Next?
|
||||
|
||||
Read the [next section](/react/contributing/implementation-notes.html) to learn about the current implementation of reconciler in more detail.
|
||||
@@ -3,10 +3,9 @@ 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:**
|
||||
@@ -125,7 +124,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 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.
|
||||
We see the value of React in the way it allows us to write components that have fewer bugs and compose together well. DOM is the original rendering target for React but [React Native](http://facebook.github.io/react-native/) is just as important both to Facebook and the community.
|
||||
|
||||
Being renderer-agnostic is an important design constraint of React. It adds some overhead in the internal representations. On the other hand, any improvements to the core translate across platforms.
|
||||
|
||||
|
||||
162
docs/contributing/how-to-contribute.md
Normal file
162
docs/contributing/how-to-contribute.md
Normal file
@@ -0,0 +1,162 @@
|
||||
---
|
||||
id: how-to-contribute
|
||||
title: How to Contribute
|
||||
layout: contributing
|
||||
permalink: contributing/how-to-contribute.html
|
||||
next: codebase-overview.html
|
||||
redirect_from: "tips/introduction.html"
|
||||
---
|
||||
|
||||
React is one of Facebook's first open source projects that is both under very active development and is also being used to ship code to everybody on [facebook.com](https://www.facebook.com). We're still working out the kinks to make contributing to this project as easy and transparent as possible, but we're not quite there yet. Hopefully this document makes the process for contributing clear and answers some questions that you may have.
|
||||
|
||||
### [Code of Conduct](https://code.facebook.com/codeofconduct)
|
||||
|
||||
Facebook has adopted a Code of Conduct that we expect project participants to adhere to. Please read [the full text](https://code.facebook.com/codeofconduct) so that you can understand what actions will and will not be tolerated.
|
||||
|
||||
### Open Development
|
||||
|
||||
All work on React happens directly on [GitHub](https://github.com/facebook/react). Both core team members and external contributors send pull requests which go through the same review process.
|
||||
|
||||
### Branch Organization
|
||||
|
||||
We will do our best to keep the [`master` branch](https://github.com/facebook/react/tree/master) in good shape, with tests passing at all times. But in order to move fast, we will make API changes that your application might not be compatible with. We recommend that you use [the latest stable version of React](/react/downloads.html).
|
||||
|
||||
If you send a pull request, please do it against the `master` branch. We maintain stable branches for major versions separately but we don't accept pull requests to them directly. Instead, we cherry-pick non-breaking changes from master to the latest stable major version.
|
||||
|
||||
### Semantic Versioning
|
||||
|
||||
React follows [semantic versioning](http://semver.org/). We release patch versions for bugfixes, minor versions for new features, and major versions for any breaking changes. When we make breaking changes, we also introduce deprecation warnings in a minor version so that our users learn about the upcoming changes and migrate their code in advance.
|
||||
|
||||
We tag every pull request with a label marking whether the change should go in the next [patch](https://github.com/facebook/react/pulls?q=is%3Aopen+is%3Apr+label%3Asemver-patch), [minor](https://github.com/facebook/react/pulls?q=is%3Aopen+is%3Apr+label%3Asemver-minor), or a [major](https://github.com/facebook/react/pulls?q=is%3Aopen+is%3Apr+label%3Asemver-major) version. We release new patch versions every few weeks, minor versions every few months, and major versions one or two times a year.
|
||||
|
||||
Every significant change is documented in the [changelog file](https://github.com/facebook/react/blob/master/CHANGELOG.md).
|
||||
|
||||
### Bugs
|
||||
|
||||
#### Where to Find Known Issues
|
||||
|
||||
We are using [GitHub Issues](https://github.com/facebook/react/issues) for our public bugs. We keep a close eye on this and try to make it clear when we have an internal fix in progress. Before filing a new task, try to make sure your problem doesn't already exist.
|
||||
|
||||
#### Reporting New Issues
|
||||
|
||||
The best way to get your bug fixed is to provide a reduced test case. This [JSFiddle template](https://jsfiddle.net/reactjs/69z2wepo/) is a great starting point.
|
||||
|
||||
#### Security Bugs
|
||||
|
||||
Facebook has a [bounty program](https://www.facebook.com/whitehat/) for the safe disclosure of security bugs. With that in mind, please do not file public issues; go through the process outlined on that page.
|
||||
|
||||
### How to Get in Touch
|
||||
|
||||
* IRC: [#reactjs on freenode](https://webchat.freenode.net/?channels=reactjs)
|
||||
* Discussion forum: [discuss.reactjs.org](https://discuss.reactjs.org/)
|
||||
|
||||
There is also [an active community of React users on the Discord chat platform](http://www.reactiflux.com/) in case you need help with React.
|
||||
|
||||
### Proposing a Change
|
||||
|
||||
If you intend to change to the public API, or make any non-trivial changes to the implementation, we recommend [filing an issue](https://github.com/facebook/react/issues/new). This lets us reach an agreement on your proposal before you put significant effort into it.
|
||||
|
||||
If you're only fixing a bug, it's fine to submit a pull request right away but we still recommend to file an issue detailing what you're fixing. This is helpful in case we don't accept that specific fix but want to keep track of the issue.
|
||||
|
||||
### Your First Pull Request
|
||||
|
||||
Working on your first Pull Request? You can learn how from this free video series:
|
||||
|
||||
**[How to Contribute to an Open Source Project on GitHub](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github)**
|
||||
|
||||
To help you get your feet wet and get you familiar with our contribution process, we have a list of **[good first bugs](https://github.com/facebook/react/labels/good%20first%20bug)** that contain bugs which are fairly easy to fix. This is a great place to get started.
|
||||
|
||||
If you decide to fix an issue, please be sure to check the comment thread in case somebody is already working on a fix. If nobody is working on it at the moment, please leave a comment stating that you intend to work on it so other people don't accidentally duplicate your effort.
|
||||
|
||||
If somebody claims an issue but doesn't follow up for more than two weeks, it's fine to take over it but you should still leave a comment.
|
||||
|
||||
### Sending a Pull Request
|
||||
|
||||
The core team is monitoring for pull requests. We will review your pull request and either merge it, request changes to it, or close it with an explanation. For API changes we may need to fix our internal uses at Facebook.com, which could cause some delay. We'll do our best to provide updates and feedback throughout the process.
|
||||
|
||||
**Before submitting a pull request,** please make sure the following is done:
|
||||
|
||||
1. Fork [the repository](https://github.com/facebook/react) and create your branch from `master`.
|
||||
2. If you've added code that should be tested, add tests!
|
||||
3. If you've changed APIs, update the documentation.
|
||||
4. Ensure the test suite passes (`npm test`).
|
||||
5. Make sure your code lints (`npm run lint`).
|
||||
6. Run the [Flow](https://flowtype.org/) typechecks (`npm run flow`).
|
||||
7. If you haven't already, complete the CLA.
|
||||
|
||||
### Contributor License Agreement (CLA)
|
||||
|
||||
In order to accept your pull request, we need you to submit a CLA. You only need to do this once, so if you've done this for another Facebook open source project, you're good to go. If you are submitting a pull request for the first time, just let us know that you have completed the CLA and we can cross-check with your GitHub username.
|
||||
|
||||
**[Complete your CLA here.](https://code.facebook.com/cla)**
|
||||
|
||||
### Contribution Prerequisites
|
||||
|
||||
* You have `node` installed at v4.0.0+ and `npm` at v2.0.0+.
|
||||
* You have `gcc` installed or are comfortable installing a compiler if needed. Some of our `npm` dependencies may require a compilation step. On OS X, the Xcode Command Line Tools will cover this. On Ubuntu, `apt-get install build-essential` will install the required packages. Similar commands should work on other Linux distros. Windows will require some additional steps, see the [`node-gyp` installation instructions](https://github.com/nodejs/node-gyp#installation) for details.
|
||||
* You are familiar with `npm` and know whether or not you need to use `sudo` when installing packages globally.
|
||||
* You are familiar with `git`.
|
||||
|
||||
### Development Workflow
|
||||
|
||||
After cloning React, run `npm install` to fetch its dependencies.
|
||||
Then, you can run several commands:
|
||||
|
||||
* `npm run lint` checks the code style.
|
||||
* `npm test` runs the complete test suite.
|
||||
* `npm test -- --watch` runs an interactive test watcher.
|
||||
* `npm test <pattern>` runs tests with matching filenames.
|
||||
* `npm run flow` runs the [Flow](https://flowtype.org/) typechecks.
|
||||
* `npm run build` creates a `build` folder with all the packages.
|
||||
|
||||
We recommend running `npm test` (or its variations above) to make sure you don't introduce any regressions as you work on your change. However it can be handy to try your build of React in a real project.
|
||||
|
||||
First, run `npm run build`. This will produce pre-built bundles in `build` folder, as well as prepare npm packages inside `build/packages`.
|
||||
|
||||
The easiest way to try your changes is to open and modify `examples/basic/index.html`. This file already uses `react.js` from the `build` folder so it will pick up your changes. Please make sure to rollback any unintentional changes in `examples` before sending a pull request.
|
||||
|
||||
If you want to try your changes in your existing React project, you may copy `build/react.js`, `build/react-dom.js`, or any other build products into your app and use them instead of the stable version. If your project uses React from npm, you may delete `react` and `react-dom` in its dependencies and use `npm link` to point them to your local `build` folder:
|
||||
|
||||
```sh
|
||||
cd your_project
|
||||
npm link ~/path_to_your_react_clone/build/packages/react
|
||||
npm link ~/path_to_your_react_clone/build/packages/react-dom
|
||||
```
|
||||
|
||||
Every time you run `npm run build` in the React folder, the updated versions will appear in your project's `node_modules`. You can then rebuild your project to try your changes.
|
||||
|
||||
We still require that your pull request contains unit tests for any new functionality. This way we can ensure that we don't break your code in the future.
|
||||
|
||||
### Style Guide
|
||||
|
||||
Our linter will catch most styling issues that may exist in your code.
|
||||
You can check the status of your code styling by simply running `npm run lint`.
|
||||
|
||||
However, there are still some styles that the linter cannot pick up. If you are unsure about something, looking at [Airbnb's Style Guide](https://github.com/airbnb/javascript) will guide you in the right direction.
|
||||
|
||||
### Code Conventions
|
||||
|
||||
* Use semicolons `;`
|
||||
* Commas last `,`
|
||||
* 2 spaces for indentation (no tabs)
|
||||
* Prefer `'` over `"`
|
||||
* `'use strict';`
|
||||
* 80 character line length (**except documentation**)
|
||||
* Write "attractive" code
|
||||
* Do not use the optional parameters of `setTimeout` and `setInterval`
|
||||
|
||||
### Introductory Video
|
||||
|
||||
You may be interested in watching [this short video](https://www.youtube.com/watch?v=wUpPsEcGsg8) (26 mins) which gives an introduction on how to contribute to React.
|
||||
|
||||
### Meeting Notes
|
||||
|
||||
React team meets once a week to discuss the development of React, future plans, and priorities. You can find the meeting notes in a [dedicated repository](https://github.com/reactjs/core-notes/).
|
||||
|
||||
### License
|
||||
|
||||
By contributing to React, you agree that your contributions will be licensed under its BSD license.
|
||||
|
||||
### What Next?
|
||||
|
||||
Read the [next section](/react/contributing/codebase-overview.html) to learn how the codebase is organized.
|
||||
894
docs/contributing/implementation-notes.md
Normal file
894
docs/contributing/implementation-notes.md
Normal file
@@ -0,0 +1,894 @@
|
||||
---
|
||||
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.
|
||||
|
||||
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 what 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(prevProps);
|
||||
}
|
||||
// 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,8 +7,9 @@
|
||||
|
||||
@mixin code-typography {
|
||||
font-family: 'source-code-pro', Menlo, Consolas, 'Courier New', monospace;
|
||||
font-size: 13px;
|
||||
line-height: 1.5;
|
||||
font-size: 13px;
|
||||
-webkit-text-size-adjust: none;
|
||||
}
|
||||
|
||||
$skinnyContentWidth: 650px;
|
||||
@@ -19,7 +20,28 @@ $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
|
||||
* {
|
||||
@@ -46,15 +68,20 @@ html {
|
||||
|
||||
.container {
|
||||
padding-top: $navHeight;
|
||||
min-width: $contentWidth + (2 * $contentPadding);
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.wrap {
|
||||
width: $contentWidth + (2 * $contentPadding);
|
||||
max-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 {
|
||||
@@ -110,21 +137,19 @@ h1, h2, h3, h4, h5, h6 {
|
||||
width: 100%;
|
||||
z-index: 100;
|
||||
|
||||
@include bp-large {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
a {
|
||||
color: $lightColor;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.nav-site-internal {
|
||||
margin: 0 0 0 20px;
|
||||
}
|
||||
|
||||
.nav-site-external {
|
||||
float: right;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.nav-site {
|
||||
display: inline-flex;
|
||||
flex: 1;
|
||||
|
||||
li {
|
||||
margin: 0;
|
||||
}
|
||||
@@ -136,17 +161,81 @@ h1, h2, h3, h4, h5, h6 {
|
||||
display: inline-block;
|
||||
height: $navHeight;
|
||||
color: #ddd;
|
||||
white-space: nowrap;
|
||||
|
||||
@include bp-large {
|
||||
display: 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 {
|
||||
@@ -155,11 +244,20 @@ 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 {
|
||||
@@ -172,10 +270,35 @@ h1, h2, h3, h4, h5, h6 {
|
||||
}
|
||||
}
|
||||
|
||||
.nav-lists {
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
width: calc(100% - 120px);
|
||||
|
||||
@include bp-large {
|
||||
display: flex;
|
||||
width: calc(100% + 20px);
|
||||
margin: 0 -10px;
|
||||
font-size: 0.9em;
|
||||
|
||||
li {
|
||||
display: flex;
|
||||
flex: 1 0 auto;
|
||||
align-items: center;
|
||||
|
||||
a {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
line-height: 1.2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Hero!
|
||||
|
||||
.hero {
|
||||
height: 300px;
|
||||
min-height: 300px;
|
||||
// background: $darkColor url(../img/header.png) no-repeat center;
|
||||
background: $darkColor;
|
||||
padding-top: 50px;
|
||||
@@ -200,8 +323,12 @@ h1, h2, h3, h4, h5, h6 {
|
||||
}
|
||||
|
||||
.buttons-unit {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
margin-top: 60px;
|
||||
text-align: center;
|
||||
font-size: 1em;
|
||||
|
||||
a {
|
||||
color: $blueColor;
|
||||
@@ -215,6 +342,11 @@ h1, h2, h3, h4, h5, h6 {
|
||||
&:active {
|
||||
background: darken($primary, 5%);
|
||||
}
|
||||
|
||||
@include bp-large {
|
||||
margin: 5px;
|
||||
font-size: 1em;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,12 +365,17 @@ 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: 6px 0 0 20px;
|
||||
margin: 0 0 6px 20px;
|
||||
}
|
||||
li {
|
||||
line-height: 16px;
|
||||
@@ -292,6 +429,25 @@ 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -311,7 +467,8 @@ h1, h2, h3, h4, h5, h6 {
|
||||
.home-divider {
|
||||
border-top-color: #bbb;
|
||||
margin: 0 auto;
|
||||
width: 400px;
|
||||
width: 100%;
|
||||
max-width: 400px;
|
||||
}
|
||||
|
||||
.skinny-row {
|
||||
@@ -337,6 +494,11 @@ h1, h2, h3, h4, h5, h6 {
|
||||
margin-left: 40px;
|
||||
width: $columnWidth;
|
||||
|
||||
@include bp-large {
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
h3 {
|
||||
color: $darkColor;
|
||||
font-size: 24px;
|
||||
@@ -447,14 +609,6 @@ 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;
|
||||
}
|
||||
@@ -467,6 +621,10 @@ section.black content {
|
||||
@include clearfix;
|
||||
|
||||
padding-top: 20px;
|
||||
padding-bottom: 80px;
|
||||
@include bp-medium {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
padding: 5px 15px;
|
||||
@@ -501,13 +659,17 @@ 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(204, 122, 111, 0.09999999999999998);
|
||||
border-left: 5px solid rgba(191, 87, 73, 0.19999999999999996);
|
||||
background-color: rgba(248, 245, 236, 0.5);
|
||||
border-left: 5px solid rgba(191, 87, 73, 0.2);
|
||||
h4 {
|
||||
margin-top: 0;
|
||||
}
|
||||
@@ -608,7 +770,17 @@ figure {
|
||||
|
||||
.inner-content {
|
||||
float: right;
|
||||
width: $skinnyContentWidth;
|
||||
width: 100%;
|
||||
max-width: $skinnyContentWidth;
|
||||
|
||||
@include bp-large {
|
||||
width: calc(100% - 240px);
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
@include bp-medium {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.nosidebar .inner-content {
|
||||
@@ -627,8 +799,48 @@ 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 {
|
||||
@@ -702,7 +914,8 @@ p a code {
|
||||
border-radius: 0 3px 3px 3px;
|
||||
float: left;
|
||||
overflow: hidden;
|
||||
width: $twoColumnWidth;
|
||||
width: 100%;
|
||||
max-width: $twoColumnWidth;
|
||||
}
|
||||
|
||||
.playgroundPreview {
|
||||
@@ -711,6 +924,7 @@ p a code {
|
||||
float: right;
|
||||
padding: 15px 20px;
|
||||
width: $columnWidth;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.playgroundError {
|
||||
@@ -725,6 +939,7 @@ p a code {
|
||||
|
||||
.MarkdownEditor .content {
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.hll {
|
||||
@@ -806,9 +1021,9 @@ p a code {
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 960px) {
|
||||
@include bp-large {
|
||||
.nav-main {
|
||||
position: static;
|
||||
position: relative;
|
||||
}
|
||||
.container {
|
||||
padding-top: 0;
|
||||
@@ -821,6 +1036,7 @@ p a code {
|
||||
|
||||
.post img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.pagination {
|
||||
@@ -841,6 +1057,20 @@ 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 {
|
||||
@@ -860,12 +1090,6 @@ 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;
|
||||
@@ -886,10 +1110,21 @@ input#algolia-doc-search {
|
||||
width: 170px;
|
||||
|
||||
transition: width .2s ease;
|
||||
}
|
||||
|
||||
input#algolia-doc-search:focus {
|
||||
width: 240px;
|
||||
&:focus {
|
||||
width: 240px;
|
||||
}
|
||||
|
||||
@include bp-large {
|
||||
background-color: transparent;
|
||||
width: 0;
|
||||
cursor: pointer;
|
||||
|
||||
&:focus {
|
||||
width: 200px;
|
||||
background-color: #333;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.algolia-autocomplete .aa-dropdown-menu {
|
||||
@@ -925,3 +1160,94 @@ input#algolia-doc-search:focus {
|
||||
.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;
|
||||
justify-content: space-between;
|
||||
max-width: 1080px;
|
||||
margin: 0 auto 3em;
|
||||
}
|
||||
footer .sitemap div {
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
---
|
||||
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).
|
||||
@@ -1,29 +0,0 @@
|
||||
---
|
||||
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).
|
||||
@@ -1,29 +0,0 @@
|
||||
---
|
||||
id: why-react-ja-JP
|
||||
title: なぜReactを使うのでしょうか?
|
||||
permalink: docs/why-react-ja-JP.html
|
||||
next: displaying-data-ja-JP.html
|
||||
|
||||
---
|
||||
ReactはFacebookとInstagramによって作られたユーザーインターフェイスを構築するためのJavaScriptのライブラリです。
|
||||
多くの人がReactを **[MVC](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller)** の **V** だと考えています。
|
||||
私たちはReactをある1つの問題を解決するために使います。それは、 **絶えず変化していくデータとともに大きなアプリケーションを構築する** ことです。それを行うために、Reactは2つの主要な考えを持っています。
|
||||
|
||||
## 単純さ
|
||||
|
||||
どのタイミングにおいても、アプリケーションがどのように見えるべきかを単純に表現し、Reactは根底にあるデータの変更があった場合に自動的に全てのUIを管理します。
|
||||
|
||||
## 叙述的
|
||||
|
||||
データが変わった時、Reactは概念的に「リフレッシュ」ボタンを押し、変わった箇所のみを検知します。
|
||||
|
||||
## コンポーザブルなコンポーネントの構築
|
||||
Reactは再利用可能なコンポーネントを構築するものです。実際、Reactを用いてあなたがする *ただ1つの* ことは、コンポーネントを構築することです。Reactは無駄な部分を省いてあるので、コンポーネントはコードの再利用、テスト、関心の分離を可能にします。
|
||||
|
||||
## 5分ください
|
||||
|
||||
Reactは型にはまった知識にも挑戦し、ちらっと見ただけではおかしく見えるアイディアもあるでしょう。このガイドを読むのに[5分ください](https://signalvnoise.com/posts/3124-give-it-five-minutes) 。それらのおかしく見えるアイディアはFacebookやInstagramの中と外の両方で何千ものコンポーネントを構築するために動いています。
|
||||
|
||||
## 更なる学習
|
||||
|
||||
[このブログの投稿](/react/blog/2013/06/05/why-react.html)で、私たちがReactを構築するモチベーションについて更に学習することができます。
|
||||
@@ -1,30 +0,0 @@
|
||||
---
|
||||
id: why-react-ko-KR
|
||||
title: 왜 React인가?
|
||||
permalink: docs/why-react-ko-KR.html
|
||||
next: displaying-data-ko-KR.html
|
||||
---
|
||||
|
||||
React는 페이스북과 인스타그램에서 사용자 인터페이스를 구성하기 위해 만들어진 라이브러리입니다. 많은 사람들은 React를 **[MVC](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller)** 에서의 **V** 로 생각하는 경향이 있습니다.
|
||||
|
||||
우리는 단 하나의 문제를 해결하기 위해 React를 만들었습니다: **지속해서 데이터가 변화하는 대규모 애플리케이션을 구축하기.** 이 문제를 해결하기 위해, React는 두가지 컨셉을 도입했습니다.
|
||||
|
||||
## 단순함
|
||||
|
||||
당신의 애플리케이션이 특정 시점에 어떻게 보여야 할지를 단순히 표현하는 것만으로, 데이터가 변할 때 React는 자동으로 모든 UI 업데이트를 관리해줍니다.
|
||||
|
||||
## 선언적 문법
|
||||
|
||||
데이터가 변할 때 React는 "새로 고침" 버튼을 누르듯이 작동하며, 데이터의 바뀐 부분만을 업데이트할 수 있습니다.
|
||||
|
||||
## 구성적인 컴포넌트를 만드세요
|
||||
|
||||
React는 재사용 가능한 컴포넌트들을 만드는 데에 도움이 됩니다. 사실, React를 사용하면 *단지* 컴포넌트를 만드는 일만 하게 됩니다. 컴포넌트들은 잘 캡슐화되어 되어 있기 때문에, 컴포넌트들은 코드의 재사용성을 높이고, 테스트를 쉽게 해 주며, 관심 분리의 원칙(separation of concerns)을 지키게 해 줍니다.
|
||||
|
||||
## 5분만 투자하세요
|
||||
|
||||
React는 많은 관습적인 사고에 도전하며, 첫눈에 볼 때는 이상한 아이디어들의 모음이라고 생각할 수도 있습니다. 이 가이드를 읽기 위해 [5분만 투자하세요](https://signalvnoise.com/posts/3124-give-it-five-minutes); 그 이상한 아이디어들은 페이스북과 인스타그램 안팎의 수천 개의 컴포넌트들을 만드는 데에 사용되었기 때문입니다.
|
||||
|
||||
## 더 알아보기
|
||||
|
||||
[이 블로그 포스트](/react/blog/2013/06/05/why-react.html)에서 React를 만든 우리의 동기에 대해 알아볼 수 있습니다.
|
||||
@@ -1,29 +0,0 @@
|
||||
---
|
||||
id: why-react
|
||||
title: Why React?
|
||||
permalink: docs/why-react.html
|
||||
next: displaying-data.html
|
||||
---
|
||||
React is a JavaScript library for creating user interfaces by Facebook and Instagram. Many people choose to think of React as the **V** in **[MVC](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller)**.
|
||||
|
||||
We built React to solve one problem: **building large applications with data that changes over time**.
|
||||
|
||||
## Simple
|
||||
|
||||
Simply express how your app should look at any given point in time, and React will automatically manage all UI updates when your underlying data changes.
|
||||
|
||||
## Declarative
|
||||
|
||||
When the data changes, React conceptually hits the "refresh" button, and knows to only update the changed parts.
|
||||
|
||||
## Build Composable Components
|
||||
|
||||
React is all about building reusable components. In fact, with React the *only* thing you do is build components. Since they're so encapsulated, components make code reuse, testing, and separation of concerns easy.
|
||||
|
||||
## Give It Five Minutes
|
||||
|
||||
React challenges a lot of conventional wisdom, and at first glance some of the ideas may seem crazy. [Give it five minutes](https://signalvnoise.com/posts/3124-give-it-five-minutes) while reading this guide; those crazy ideas have worked for building thousands of components both inside and outside of Facebook and Instagram.
|
||||
|
||||
## Learn More
|
||||
|
||||
You can learn more about our motivations behind building React in [this blog post](/react/blog/2013/06/05/why-react.html).
|
||||
@@ -1,29 +0,0 @@
|
||||
---
|
||||
id: why-react-ru-RU
|
||||
title: Почему именно React?
|
||||
permalink: docs/why-react-ru-RU.html
|
||||
next: displaying-data-ru-RU.html
|
||||
---
|
||||
React — библиотека JavaScript для создания интерфейсов от команд Facebook и Instagram. Многие ассоциируют React с понятием **View** в паттерне **[MVC](https://ru.wikipedia.org/wiki/Model-View-Controller)**.
|
||||
|
||||
Мы делали React, чтобы решить одну важную задачу: **создавать действительно большие приложения с постоянно меняющимися данными**.
|
||||
|
||||
## Простота
|
||||
|
||||
С React вы всегда точно знаете как будет выглядеть ваше приложение, ведь как только изменятся данные, он мгновенно отобразит эти изменения в интерфейсе.
|
||||
|
||||
## Декларативность
|
||||
|
||||
Как только состояние приложения изменится, React будто нажимает кнопку "обновить" и точно знает, какие части интерфейса надо поменять, а какие нет. Никаких дополнительных инструкций и команд, React сам отслеживает изменения данных и реагирует на них.
|
||||
|
||||
## Создание компонентов, как строительных блоков приложения
|
||||
|
||||
По сути, разработка на React целиком состоит в создании таких компонентов. С React вы *только* тем и занимаетесь, что пишете новые компоненты, те самые строительные блоки, из которых будет строиться приложение. А поскольку они хорошо инскапсулированы, их удобно использовать повторно даже в других проектах, плюс такой код проще тестировать.
|
||||
|
||||
## Уделите этому 5 минут
|
||||
|
||||
React бросает вызов многим устоявшимся идеям и правилам, и на первый взгляд, некоторые из его идей выглядят по меньшей мере странными. [Уделите этому 5 минут](https://signalvnoise.com/posts/3124-give-it-five-minutes) пока читаете эту статью; эти безумные идеи нашли свое применение при создании тысяч компонентов не только для Facebook и Instagram, но и в других крупных проектах.
|
||||
|
||||
## Узнай больше
|
||||
|
||||
Вы можете больше узнать о причинах создания React [отсюда](/react/blog/2013/06/05/why-react.html).
|
||||
@@ -1,29 +0,0 @@
|
||||
---
|
||||
id: why-react-zh-CN
|
||||
title: 为什么使用 React?
|
||||
permalink: docs/why-react-zh-CN.html
|
||||
next: displaying-data-zh-CN.html
|
||||
---
|
||||
React 是一个 Facebook 和 Instagram 用来创建用户界面的 JavaScript 库。很多人选择将 React 认为是 **[MVC](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller)** 中的 **V**(视图)。
|
||||
|
||||
我们创造 React 是为了解决一个问题:**构建随着时间数据不断变化的大规模应用程序**。
|
||||
|
||||
### 简单
|
||||
|
||||
仅仅只要表达出你的应用程序在任一个时间点应该呈现的样子,然后当底层的数据变了,React 会自动处理所有用户界面的更新。
|
||||
|
||||
### 声明式 (Declarative)
|
||||
|
||||
数据变化后,React 概念上与点击“刷新”按钮类似,但仅会更新变化的部分。
|
||||
|
||||
## 构建可组合的组件
|
||||
|
||||
React 都是关于构建可复用的组件。事实上,通过 React 你*唯一*要做的事情就是构建组件。得益于其良好的封装性,组件使代码复用、测试和关注分离(separation of concerns)更加简单。
|
||||
|
||||
## 给它5分钟的时间
|
||||
|
||||
React挑战了很多传统的知识,第一眼看上去可能很多想法有点疯狂。当你阅读这篇指南,请[给它5分钟的时间](https://signalvnoise.com/posts/3124-give-it-five-minutes);那些疯狂的想法已经帮助 Facebook 和 Instagram 从里到外创建了上千的组件了。
|
||||
|
||||
## 了解更多
|
||||
|
||||
你可以从这篇[博客](/react/blog/2013/06/05/why-react.html)了解更多我们创造 React 的动机。
|
||||
@@ -1,29 +0,0 @@
|
||||
---
|
||||
id: why-react-zh-TW
|
||||
title: Why React?
|
||||
permalink: docs/why-react-zh-TW.html
|
||||
next: displaying-data.html
|
||||
---
|
||||
React是Facebook和Instagram用來建立使用者介面的JavaScript函式庫. 很多人認為React就是處理 **[MVC](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller)**架構中 **V** 的部份.
|
||||
|
||||
我們建造React用來解決一個問題: **開發資料能隨時間頻繁更新的大型應用程式**.
|
||||
|
||||
## 簡單(Simple)
|
||||
|
||||
簡單意味著你所開發的應用程式外觀任何一部分都要能即時呈現, 並且當資料有所變動時React能自動管理所有UI的更新.
|
||||
|
||||
## 陳述(Declarative)
|
||||
|
||||
當資料改變時, React概念上就像是點擊了 "刷新" 的按鈕, 並且知道只需更新有改變的部份.
|
||||
|
||||
## 建立可組合的元件(Composable Components)
|
||||
|
||||
React就是在建造可重用的元件(Components). 事實上, 當你使用React時 *唯一* 在做的事就是建立元件(Components). 由於它們封裝性高,元件使得程式碼能夠易於重複使用, 測試, 並且容易做到讓關注點分離(separation of concerns easy).
|
||||
|
||||
## 指引(Give It Five Minutes)
|
||||
|
||||
React挑戰了許多傳統的觀念, 第一次乍看之下這些構想可能看起來有點瘋狂. [Give it five minutes](https://signalvnoise.com/posts/3124-give-it-five-minutes) 而當閱讀完這篇指引; 這些瘋狂的構想在Facebook和Instagram裡裡外外建立了數以千計的元件(components)之後被證明是可實行的.
|
||||
|
||||
## 更多學習資源
|
||||
|
||||
從這裡你能學習到更多建造React背後的動機 [this blog post](/react/blog/2013/06/05/why-react.html).
|
||||
@@ -1,129 +0,0 @@
|
||||
---
|
||||
id: displaying-data-it-IT
|
||||
title: Visualizzare Dati
|
||||
permalink: docs/displaying-data-it-IT.html
|
||||
prev: why-react-it-IT.html
|
||||
next: jsx-in-depth-it-IT.html
|
||||
---
|
||||
|
||||
L'attività più basilare che puoi effettuare con una UI è mostrare dei dati. React rende visualizzare dati semplice e mantiene automaticamente l'interfaccia aggiornata quando i dati cambiano.
|
||||
|
||||
|
||||
## Per Cominciare
|
||||
|
||||
Diamo un'occhiata ad un esempio davvero semplice. Creiamo un file dal nome `hello-react.html` con il codice seguente:
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Hello React</title>
|
||||
<script src="https://npmcdn.com/react@{{site.react_version}}/dist/react.js"></script>
|
||||
<script src="https://npmcdn.com/react-dom@{{site.react_version}}/dist/react-dom.js"></script>
|
||||
<script src="https://npmcdn.com/babel-core@5.8.38/browser.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="example"></div>
|
||||
<script type="text/babel">
|
||||
|
||||
// ** Il tuo codice va qui! **
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
Nel resto della documentazione, ci concentreremo soltanto sul codice JavaScript e assumeremo che sia inserito in un modello come quello qui sopra. Sostituisci il commento segnaposto qui sopra con il seguente codice JSX:
|
||||
|
||||
```javascript
|
||||
var HelloWorld = React.createClass({
|
||||
render: function() {
|
||||
return (
|
||||
<p>
|
||||
Ciao, <input type="text" placeholder="Scrivi il tuo nome" />!
|
||||
È il {this.props.date.toTimeString()}
|
||||
</p>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
setInterval(function() {
|
||||
ReactDOM.render(
|
||||
<HelloWorld date={new Date()} />,
|
||||
document.getElementById('example')
|
||||
);
|
||||
}, 500);
|
||||
```
|
||||
|
||||
|
||||
## Aggiornamenti Reattivi
|
||||
|
||||
Apri `hello-react.html` in un browser web e scrivi il tuo nome nel campo di testo. Osserva che React cambia soltanto la stringa di testo dell'ora nella UI — ogni input che inserisci nel campo di testo rimane, anche se non hai scritto alcun codice che gestisce questo comportamento. React lo capisce da solo al tuo posto e fa la cosa giusta.
|
||||
|
||||
La maniera in cui siamo in grado di capirlo è che React non manipola il DOM a meno che non sia necessario. **Utilizza un DOM interno fittizio e veloce per effettuare confronti ed effettuare le mutazioni del DOM più efficienti al tuo posto.**
|
||||
|
||||
Gli input di questo componente sono chiamati `props` — breve per "properties". Sono passati come attributi nella sintassi JSX. Puoi pensare ad essi come immutabili nel contesto del componente, ovvero, **non assegnare mai `this.props`**.
|
||||
|
||||
|
||||
## I Componenti Sono Come Funzioni
|
||||
|
||||
I componenti React sono molto semplici. Puoi immaginarli come semplici funzioni che ricevono in ingresso `props` e `state` (discusso in seguito) e rendono HTML. Fatta questa premessa, i componenti sono molto semplici da descrivere.
|
||||
|
||||
> Nota:
|
||||
>
|
||||
> **Una limitazione**: i componenti React possono rendere soltanto un singolo nodo radice. Se desideri restituire nodi multipli, essi *devono* essere avvolti in un singolo nodo radice.
|
||||
|
||||
|
||||
## Sintassi JSX
|
||||
|
||||
Crediamo fermamente che i componenti sono la maniera corretta di separare i concetti anziché i "modelli" e la "logica di presentazione." Pensiamo che il markup e il codice che lo genera siano intimamente collegati. Inoltre, la logica di presentazione è solitamente molto complessa e usare un linguaggio di modello per esprimerla risulta dispendioso.
|
||||
|
||||
Abbiamo scoperto che la migliore soluzione a questo problema è generare HTML e un albero di componenti direttamente dal codice JavaScript in maniera da poter utilizzare tutta la potenza espressiva di un vero linguaggio di programmazione per costruire UI.
|
||||
|
||||
Per rendere il compito più facile, abbiamo aggiunto una semplice e **opzionale** sintassi simile all'HTML per creare questi nodi di albero React.
|
||||
|
||||
**JSX ti permette di creare oggetti JavaScript usando una sintassi HTML.** Per generare un collegamento in React usando puro JavaScript puoi scrivere:
|
||||
|
||||
`React.createElement('a', {href: 'https://facebook.github.io/react/'}, 'Ciao!')`
|
||||
|
||||
Con JSX ciò diventa:
|
||||
|
||||
`<a href="https://facebook.github.io/react/">Ciao!</a>`
|
||||
|
||||
Abbiamo scoperto che questo ha reso la costruzione di applicazioni React più semplice e i designer tendono a preferire la sintassi, ma ciascuno ha un diverso flusso di lavoro, quindi **JSX non è richiesto per utilizzare React.**
|
||||
|
||||
JSX è di dimensioni contenute. Per maggiori informazioni, consulta [JSX in profondità](/react/docs/jsx-in-depth-it-IT.html). Oppure osserva la trasformazione in tempo reale sulla [REPL di Babel](https://babeljs.io/repl/).
|
||||
|
||||
JSX è simile all'HTML, ma non proprio identico. Consulta la guida [JSX gotchas](/react/docs/jsx-gotchas-it-IT.html) per alcune differenze fondamentali.
|
||||
|
||||
[Babel offre una varietà di strumenti per cominciare a usare JSX](http://babeljs.io/docs/setup/), dagli strumenti a riga di comando alle integrazioni in Ruby on Rails. Scegli lo strumento che funziona meglio per te.
|
||||
|
||||
|
||||
## React senza JSX
|
||||
|
||||
JSX è completamente opzionale; non è necessario utilizzare JSX con React. Puoi creare elementi React in puro JavaScript usando `React.createElement`, che richiede un nome di tag o di componente, un oggetto di proprietà e un numero variabile di argomenti che rappresentano nodi figli opzionali.
|
||||
|
||||
```javascript
|
||||
var child1 = React.createElement('li', null, 'Primo Contenuto di Testo');
|
||||
var child2 = React.createElement('li', null, 'Secondo Contenuto di Testo');
|
||||
var root = React.createElement('ul', { className: 'my-list' }, child1, child2);
|
||||
ReactDOM.render(root, document.getElementById('example'));
|
||||
```
|
||||
|
||||
Per comodità, puoi creare funzioni factory scorciatoia per costruire elementi da componenti personalizzati.
|
||||
|
||||
```javascript
|
||||
var Factory = React.createFactory(ComponentClass);
|
||||
...
|
||||
var root = Factory({ custom: 'prop' });
|
||||
ReactDOM.render(root, document.getElementById('example'));
|
||||
```
|
||||
|
||||
React possiede già delle factory predefinite per i tag HTML comuni:
|
||||
|
||||
```javascript
|
||||
var root = React.DOM.ul({ className: 'my-list' },
|
||||
React.DOM.li(null, 'Contenuto di Testo')
|
||||
);
|
||||
```
|
||||
@@ -1,125 +0,0 @@
|
||||
---
|
||||
id: displaying-data-ja-JP
|
||||
title: データを表示する
|
||||
permalink: docs/displaying-data-ja-JP.html
|
||||
prev: why-react-ja-JP.html
|
||||
next: jsx-in-depth-ja-JP.html
|
||||
|
||||
---
|
||||
|
||||
UIについて、最も基本的なことは、いくつかのデータを表示することです。Reactはデータを表示し、変更された時にはインターフェースを最新の状態に自動的に保つことが簡単にできるようになっています。
|
||||
|
||||
## はじめに
|
||||
|
||||
本当に単純な例を見てみましょう。`hello-react.html` ファイルを以下のようなコードで作成してください。
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Hello React</title>
|
||||
<script src="https://npmcdn.com/react@{{site.react_version}}/dist/react.js"></script>
|
||||
<script src="https://npmcdn.com/react-dom@{{site.react_version}}/dist/react-dom.js"></script>
|
||||
<script src="https://npmcdn.com/babel-core@5.8.38/browser.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="example"></div>
|
||||
<script type="text/babel">
|
||||
|
||||
// ** コードをここに書きます! **
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
このドキュメントの中では、JavaScriptのコードにのみフォーカスします。そして、それが上のようなテンプレートに挿入されていると考えます。
|
||||
|
||||
```javascript
|
||||
var HelloWorld = React.createClass({
|
||||
render: function() {
|
||||
return (
|
||||
<p>
|
||||
Hello, <input type="text" placeholder="Your name here" />!
|
||||
It is {this.props.date.toTimeString()}
|
||||
</p>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
setInterval(function() {
|
||||
ReactDOM.render(
|
||||
<HelloWorld date={new Date()} />,
|
||||
document.getElementById('example')
|
||||
);
|
||||
}, 500);
|
||||
```
|
||||
|
||||
|
||||
## リアクティブなアップデート
|
||||
|
||||
`hello-react.html` をウェブブラウザで開き、テキストフィールドにあなたの名前を入力してください。ReactはUIのうち、時間の文字列しか変更しないことに注意してください。あなたがテキストフィールドに入力したものは残っています。あなたはそういったコードを書いていないのにも関わらずです。Reactはあなたのことを理解しており、正しいことを行います。
|
||||
|
||||
このことについて私たちが理解できる方法は、Reactは必要になるまで、DOMの操作を行わないということです。 **Reactは、DOMの変化を表現し、あなたにもっとも効率的なDOMの変化を見積もるために早い、内部のモックのDOMを使っています。**
|
||||
|
||||
このコンポーネントのインプットは `props` と呼ばれるものです。"properties" の省略形です。それらはJSXシンタックスの中でアトリビュートとして渡されます。それらはコンポーネントの中で不変と考えるべきで、 **`this.props` には書き込まないようにしてください**
|
||||
|
||||
## コンポーネントは関数のようなものです。
|
||||
|
||||
Reactのコンポーネントはとても単純です。それらは `props` や `state` (後述します)を取り、HTMLをレンダリングする単純な関数だと考えることができます。この考えの元、コンポーネントは簡単に理解することができます。
|
||||
|
||||
> 注意:
|
||||
>
|
||||
> **1つの制限**: Reactのコンポーネントは単一の最上位のノードだけをレンダリングします。複数のノードをリターンしたい場合は、単一の最上位のもので *ラップする必要があります* 。
|
||||
|
||||
## JSXシンタックス
|
||||
|
||||
私たちは関心を分離する正しい方法は「テンプレート」と「ディスプレイロジック」ではなくコンポーネントであると強く考えています。ビューを生成するマークアップとコードは密接につながっていると考えています。加えて、ディスプレイロジックはとても複雑になりえますし、ビューを表現するのにテンプレート言語を使うことはとてもややこしくなりえます。
|
||||
|
||||
私たちは、この問題の最適解は、UIを構築するのにリアルなプログラミング言語の表現力の全てを使うことができるように、JavaScriptのコードからHTMLやコンポーネントのツリーを直接生成することだと発見しました。
|
||||
|
||||
上記のことを簡単に行うために、私たちはReactのツリーノードを構築するためのとても単純で、 **オプショナルな** HTMLに似たシンタックスを加えました。
|
||||
|
||||
**JSXはHTMLのシンタックスを使ってJavaScriptのオブジェクトを構築するのを可能にします。** 純粋にJavaScriptを使ってReactでリンクを構築するには、以下のように書きます。
|
||||
|
||||
`React.createElement('a', {href: 'https://facebook.github.io/react/'}, 'Hello!')`
|
||||
|
||||
JSXでは、以下のように変換されます。
|
||||
|
||||
`<a href="https://facebook.github.io/react/">Hello!</a>`
|
||||
|
||||
以上のようなことで、Reactのアプリを作成するのは簡単になりましたし、デザイナーはこのシンタックスを好むようになると発見しました。しかし、人は自分自身のワークフローを持っているものです。 **JSXはReactを使う際に必ずしも必要ではありません。**
|
||||
|
||||
JSXはとても小さいです。さらに学ぶためには、[JSXの深層](/react/docs/jsx-in-depth-ja-JP.html)を参照ください。または、[ライブJSXコンパイラー](/react/jsx-compiler.html)で変換の動作を確認してください。
|
||||
|
||||
JSXはHTMLに似ていますが、正確に同じではありません。いくつかのキーの違いについては[JSXの理解](/react/docs/jsx-gotchas.html) をご覧ください。
|
||||
|
||||
JSXを初めて使う際に最も簡単なのは、ブラウザで `JSXTransformer` を使う方法です。これはプロダクションでは使わないことを強くお勧めします。コードは、コマンドラインの[react-tools](https://www.npmjs.com/package/react-tools)パッケージを使うことでプリコンパイルできます。
|
||||
|
||||
## JSXを使わないReact
|
||||
|
||||
JSXは完全にオプションです。Reactと一緒にJSXを使う必要はありません。`React.createElement` を使って、ただのJavaScriptでReactの要素を作ることもできます。それは、タグの名前やコンポーネント、プロパティのオブジェクト、いくつかのオプションの子要素をとります。
|
||||
|
||||
```javascript
|
||||
var child1 = React.createElement('li', null, 'First Text Content');
|
||||
var child2 = React.createElement('li', null, 'Second Text Content');
|
||||
var root = React.createElement('ul', { className: 'my-list' }, child1, child2);
|
||||
ReactDOM.render(root, document.getElementById('example'));
|
||||
```
|
||||
便利に書くために、カスタムコンポーネントで要素を作るために簡略した記法でファクトリー関数を作ることができます。
|
||||
|
||||
```javascript
|
||||
var Factory = React.createFactory(ComponentClass);
|
||||
...
|
||||
var root = Factory({ custom: 'prop' });
|
||||
ReactDOM.render(root, document.getElementById('example'));
|
||||
```
|
||||
|
||||
Reactはすでに、共通なHTMLのタグについてはビルトインの関数を持っています。
|
||||
|
||||
```javascript
|
||||
var root = React.DOM.ul({ className: 'my-list' },
|
||||
React.DOM.li(null, 'Text Content')
|
||||
);
|
||||
```
|
||||
@@ -1,124 +0,0 @@
|
||||
---
|
||||
id: displaying-data-ko-KR
|
||||
title: 데이터를 표시하기
|
||||
permalink: docs/displaying-data-ko-KR.html
|
||||
prev: why-react-ko-KR.html
|
||||
next: jsx-in-depth-ko-KR.html
|
||||
---
|
||||
|
||||
UI를 가지고 할 수 있는 가장 기초적인 것은 데이터를 표시하는 것입니다. React는 데이터를 표시하고 데이터가 변할 때마다 인터페이스를 최신의 상태로 자동으로 유지하기 쉽게 해 줍니다.
|
||||
|
||||
## 시작하기
|
||||
|
||||
정말 간단한 예제를 보도록 하죠. 다음과 같은 코드의 `hello-react.html` 파일을 만듭시다.
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Hello React</title>
|
||||
<script src="https://npmcdn.com/react@{{site.react_version}}/dist/react.js"></script>
|
||||
<script src="https://npmcdn.com/react-dom@{{site.react_version}}/dist/react-dom.js"></script>
|
||||
<script src="https://npmcdn.com/babel-core@5.8.38/browser.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="example"></div>
|
||||
<script type="text/babel">
|
||||
|
||||
// ** 코드는 여기에 작성하면 됩니다! **
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
문서의 나머지에서, 코드가 위와 같은 HTML 템플릿에 들어갔다고 가정하고 JavaScript 코드에만 집중할 것입니다. 위의 주석 부분을 다음과 같은 JSX 코드로 바꿔 보세요:
|
||||
|
||||
```javascript
|
||||
var HelloWorld = React.createClass({
|
||||
render: function() {
|
||||
return (
|
||||
<p>
|
||||
안녕, <input type="text" placeholder="이름을 여기에 작성하세요" />!
|
||||
지금 시간은 {this.props.date.toTimeString()} 입니다.
|
||||
</p>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
setInterval(function() {
|
||||
ReactDOM.render(
|
||||
<HelloWorld date={new Date()} />,
|
||||
document.getElementById('example')
|
||||
);
|
||||
}, 500);
|
||||
```
|
||||
|
||||
## 반응 적(Reactive) 업데이트
|
||||
|
||||
`hello-react.html` 파일을 웹 브라우저에서 열어 당신의 이름을 텍스트 필드에 써 보세요. React는 단지 시간을 표시하는 부분만을 바꿉니다 — 텍스트 필드 안에 입력한 것은 그대로 남아 있구요, 당신이 이 동작을 관리하는 그 어떤 코드도 쓰지 않았음에도 불구하고 말이죠. React는 그걸 올바른 방법으로 알아서 해줍니다.
|
||||
|
||||
우리가 이걸 할 수 있었던 건, React는 필요한 경우에만 DOM을 조작하기 때문입니다. **React는 빠른 React 내부의 DOM 모형을 이용하여 변경된 부분을 측정하고, 가장 효율적인 DOM 조작 방법을 계산해 줍니다.**
|
||||
|
||||
이 컴포넌트에 대한 입력은 `props` 라고 불립니다 — "properties" 를 줄인 것이죠. 그들은 JSX 문법에서는 어트리뷰트로서 전달됩니다. 당신은 `props` 를 컴포넌트 안에서 불변의(immutable) 엘리먼트로서 생각해야 하고, `this.props` 를 덮어씌우려고 해서는 안됩니다.
|
||||
|
||||
## 컴포넌트들은 함수와 같습니다
|
||||
|
||||
React 컴포넌트들은 매우 단순합니다. 당신은 그것들을 `props` 와 `state` (이것들은 나중에 언급할 것입니다) 를 받고 HTML을 렌더링하는 단순한 함수들로 생각해도 됩니다. 이걸 염두하면, 컴포넌트의 작동을 이해하는 것도 쉽습니다.
|
||||
|
||||
> 주의:
|
||||
>
|
||||
> **한가지 제약이 있습니다**: React 컴포넌트들은 단 하나의 루트 노드(root node)만을 렌더할 수 있습니다. 만약 여러개의 노드들을 리턴하고 싶다면, 그것들은 단 하나의 루트 노드로 싸여져 있어야만 합니다.
|
||||
|
||||
## JSX 문법
|
||||
|
||||
우리는 컴포넌트를 사용하는 것이 "템플릿"과 "디스플레이 로직(display logic)"을 이용하는 것보다 관심을 분리(separate concerns)하는 데에 올바른 방법이라고 강하게 믿고 있습니다. 우리는 마크업과 그것을 만들어내는 코드는 친밀하게 함께 결합되어있다고 생각합니다. 또한, 디스플레이 로직은 종종 매우 복잡하고, 그것을 템플릿 언어를 이용해 표현하는 것은 점점 사용하기 어렵게 됩니다.
|
||||
|
||||
우리는 이 문제를 해결하는 최고의 해결책은, UI를 만드는 진짜 프로그래밍 언어의 표현력을 모두 사용할 수 있는 JavaScript 코드로부터 HTML과 컴포넌트 트리들을 생성하는 것임을 발견했습니다.
|
||||
|
||||
이것을 더 쉽게 하기 위해서, 우리는 매우 간단하고, **선택적인** HTML과 비슷한 문법을 추가하여 이 React 트리 노드들을 만들 수 있게 했습니다.
|
||||
|
||||
**JSX는 당신으로 하여금 HTML 문법을 이용해 JavaScript 객체를 만들게 해줍니다.** React를 이용해 순수한 JavaScript 문법으로 링크를 만드려고 한다면, 코드는 다음과 같습니다:
|
||||
|
||||
`React.createElement('a', {href: 'https://facebook.github.io/react/'}, '안녕하세요!')`
|
||||
|
||||
JSX를 이용하면:
|
||||
|
||||
`<a href="https://facebook.github.io/react/">안녕하세요!</a>`
|
||||
|
||||
우리는 이것이 React 앱들을 만들기 쉽게 하고, 디자이너들이 이 문법을 더 선호하는 것을 발견했습니다, 하지만 모든 사람은 그들만의 선호하는 워크플로우가 있기 마련이므로, **JSX는 React를 사용하기 위해 필수적이지는 않습니다.**
|
||||
|
||||
JSX는 매우 작은 언어입니다. 그것을 배우고 싶다면, [JSX 깊게 살펴보기](/react/docs/jsx-in-depth-ko-KR.html)를 살펴 보시기 바랍니다. 또는, [바벨 REPL](https://babeljs.io/repl/)를 통해 문법이 변환되는 것을 살펴 보시기 바랍니다.
|
||||
|
||||
JSX는 HTML과 비슷하지만, 완전히 똑같지는 않습니다. [JSX의 실수하기 쉬운 부분들](/react/docs/jsx-gotchas-ko-KR.html)에 중요한 차이점들에 대해 설명되어 있습니다.
|
||||
|
||||
[바벨에서 JSX를 시작하는 여러 방법을 제공합니다](http://babeljs.io/docs/setup/). 여기에는 커맨드 라인 툴부터 루비 온 레일스 연동까지 다양한 방법이 있습니다. 가장 편한 툴을 사용하세요.
|
||||
|
||||
## JSX 없이 React 사용하기
|
||||
|
||||
JSX는 완전히 선택적입니다. 당신은 React와 JSX를 함께 사용하지 않아도 상관없습니다. 그냥 JavaScript에서 React 엘리먼트를 `React.createElement`로 만들 수 있습니다. 여기에 태그 이름이나 컴포넌트, 속성 객체, 자식 엘리먼트들을 전달하면 됩니다.
|
||||
|
||||
```javascript
|
||||
var child1 = React.createElement('li', null, 'First Text Content');
|
||||
var child2 = React.createElement('li', null, 'Second Text Content');
|
||||
var root = React.createElement('ul', { className: 'my-list' }, child1, child2);
|
||||
ReactDOM.render(root, document.getElementById('example'));
|
||||
```
|
||||
|
||||
편의를 위하여, 당신은 팩토리 함수 헬퍼들을 이용해 커스텀 컴포넌트로부터 엘리먼트들을 만들 수 있습니다.
|
||||
|
||||
```javascript
|
||||
var Factory = React.createFactory(ComponentClass);
|
||||
...
|
||||
var root = Factory({ custom: 'prop' });
|
||||
ReactDOM.render(root, document.getElementById('example'));
|
||||
```
|
||||
|
||||
React는 이미 일반적인 HTML 태그에 대한 빌트인 팩토리를 가지고 있습니다.
|
||||
|
||||
```javascript
|
||||
var root = React.DOM.ul({ className: 'my-list' },
|
||||
React.DOM.li(null, '텍스트')
|
||||
);
|
||||
```
|
||||
@@ -1,124 +0,0 @@
|
||||
---
|
||||
id: displaying-data
|
||||
title: Displaying Data
|
||||
permalink: docs/displaying-data.html
|
||||
prev: why-react.html
|
||||
next: jsx-in-depth.html
|
||||
---
|
||||
|
||||
The most basic thing you can do with a UI is display some data. React makes it easy to display data and automatically keeps the interface up-to-date when the data changes.
|
||||
|
||||
## Getting Started
|
||||
|
||||
Let's look at a really simple example. Create a `hello-react.html` file with the following code:
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Hello React</title>
|
||||
<script src="https://npmcdn.com/react@{{site.react_version}}/dist/react.js"></script>
|
||||
<script src="https://npmcdn.com/react-dom@{{site.react_version}}/dist/react-dom.js"></script>
|
||||
<script src="https://npmcdn.com/babel-core@5.8.38/browser.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="example"></div>
|
||||
<script type="text/babel">
|
||||
|
||||
// ** Your code goes here! **
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
For the rest of the documentation, we'll just focus on the JavaScript code and assume it's inserted into a template like the one above. Replace the placeholder comment above with the following JSX:
|
||||
|
||||
```javascript
|
||||
var HelloWorld = React.createClass({
|
||||
render: function() {
|
||||
return (
|
||||
<p>
|
||||
Hello, <input type="text" placeholder="Your name here" />!
|
||||
It is {this.props.date.toTimeString()}
|
||||
</p>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
setInterval(function() {
|
||||
ReactDOM.render(
|
||||
<HelloWorld date={new Date()} />,
|
||||
document.getElementById('example')
|
||||
);
|
||||
}, 500);
|
||||
```
|
||||
|
||||
## Reactive Updates
|
||||
|
||||
Open `hello-react.html` in a web browser and type your name into the text field. Notice that React is only changing the time string in the UI — any input you put in the text field remains, even though you haven't written any code to manage this behavior. React figures it out for you and does the right thing.
|
||||
|
||||
The way we are able to figure this out is that React does not manipulate the DOM unless it needs to. **It uses a fast, internal mock DOM to perform diffs and computes the most efficient DOM mutation for you.**
|
||||
|
||||
The inputs to this component are called `props` — short for "properties". They're passed as attributes in JSX syntax. You should think of these as immutable within the component, that is, **never write to `this.props`**.
|
||||
|
||||
## Components are Just Like Functions
|
||||
|
||||
React components are very simple. You can think of them as simple functions that take in `props` and `state` (discussed later) and render HTML. With this in mind, components are easy to reason about.
|
||||
|
||||
> Note:
|
||||
>
|
||||
> **One limitation**: React components can only render a single root node. If you want to return multiple nodes they *must* be wrapped in a single root.
|
||||
|
||||
## JSX Syntax
|
||||
|
||||
We strongly believe that components are the right way to separate concerns rather than "templates" and "display logic." We think that markup and the code that generates it are intimately tied together. Additionally, display logic is often very complex and using template languages to express it becomes cumbersome.
|
||||
|
||||
We've found that the best solution for this problem is to generate HTML and component trees directly from the JavaScript code such that you can use all of the expressive power of a real programming language to build UIs.
|
||||
|
||||
In order to make this easier, we've added a very simple, **optional** HTML-like syntax to create these React tree nodes.
|
||||
|
||||
**JSX lets you create JavaScript objects using HTML syntax.** To generate a link in React using pure JavaScript you'd write:
|
||||
|
||||
`React.createElement('a', {href: 'https://facebook.github.io/react/'}, 'Hello!')`
|
||||
|
||||
With JSX this becomes:
|
||||
|
||||
`<a href="https://facebook.github.io/react/">Hello!</a>`
|
||||
|
||||
We've found this has made building React apps easier and designers tend to prefer the syntax, but everyone has their own workflow, so **JSX is not required to use React.**
|
||||
|
||||
JSX is very small. To learn more about it, see [JSX in depth](/react/docs/jsx-in-depth.html). Or see the transform in action in [the Babel REPL](https://babeljs.io/repl/).
|
||||
|
||||
JSX is similar to HTML, but not exactly the same. See [JSX gotchas](/react/docs/jsx-gotchas.html) for some key differences.
|
||||
|
||||
[Babel exposes a number of ways to get started using JSX](http://babeljs.io/docs/setup/), ranging from command line tools to Ruby on Rails integrations. Choose the tool that works best for you.
|
||||
|
||||
## React without JSX
|
||||
|
||||
JSX is completely optional; you don't have to use JSX with React. You can create React elements in plain JavaScript using `React.createElement`, which takes a tag name or component, a properties object, and variable number of optional child arguments.
|
||||
|
||||
```javascript
|
||||
var child1 = React.createElement('li', null, 'First Text Content');
|
||||
var child2 = React.createElement('li', null, 'Second Text Content');
|
||||
var root = React.createElement('ul', { className: 'my-list' }, child1, child2);
|
||||
ReactDOM.render(root, document.getElementById('example'));
|
||||
```
|
||||
|
||||
For convenience, you can create short-hand factory functions to create elements from custom components.
|
||||
|
||||
```javascript
|
||||
var Factory = React.createFactory(ComponentClass);
|
||||
...
|
||||
var root = Factory({ custom: 'prop' });
|
||||
ReactDOM.render(root, document.getElementById('example'));
|
||||
```
|
||||
|
||||
React already has built-in factories for common HTML tags:
|
||||
|
||||
```javascript
|
||||
var root = React.DOM.ul({ className: 'my-list' },
|
||||
React.DOM.li(null, 'Text Content')
|
||||
);
|
||||
```
|
||||
@@ -1,124 +0,0 @@
|
||||
---
|
||||
id: displaying-data-ru-RU
|
||||
title: Отображение данных
|
||||
permalink: docs/displaying-data-ru-RU.html
|
||||
prev: why-react-ru-RU.html
|
||||
next: jsx-in-depth.html
|
||||
---
|
||||
|
||||
Главная задача интерфейса — это отображать данные. React делает это легко и обновляет интерфейс сразу, как только изменятся данные.
|
||||
|
||||
## Начало
|
||||
|
||||
Давайте рассмотрим простой пример. Создайте файл `hello-react.html` со следующим текстом:
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Hello React</title>
|
||||
<script src="https://npmcdn.com/react@{{site.react_version}}/dist/react.js"></script>
|
||||
<script src="https://npmcdn.com/react-dom@{{site.react_version}}/dist/react-dom.js"></script>
|
||||
<script src="https://npmcdn.com/babel-core@5.8.38/browser.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="example"></div>
|
||||
<script type="text/babel">
|
||||
|
||||
// ** Ваш код будет здесь! **
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
Добавим в этот шаблон немного JavaScript. Замените комментарий на следующий JSX-код:
|
||||
|
||||
```javascript
|
||||
var HelloWorld = React.createClass({
|
||||
render: function() {
|
||||
return (
|
||||
<p>
|
||||
Hello, <input type="text" placeholder="Your name here" />!
|
||||
It is {this.props.date.toTimeString()}
|
||||
</p>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
setInterval(function() {
|
||||
ReactDOM.render(
|
||||
<HelloWorld date={new Date()} />,
|
||||
document.getElementById('example')
|
||||
);
|
||||
}, 500);
|
||||
```
|
||||
|
||||
## Реактивные обновления
|
||||
|
||||
Откройте `hello-react.html` в браузере и введите в текстовое поле свое имя. Что происходит со страницей? Каждые полсекунды обновляется время, остальные же части страницы остаются без изменений. Обратите внимание, что мы не написали ни строчки кода, чтобы управлять этим поведением. React сам отлично понимает что надо делать и обновляет элементы на странице по мере необходимости.
|
||||
|
||||
Суть в том, что React не меняет DOM-дерево до тех пор, пока это не потребуется. **Чтобы отразить изменения, React использует быстрое внутреннее представление DOM-дерева и просчитывает как его изменить наиболее эффективно**.
|
||||
|
||||
Передаваемые в компонент данные называются `props` — сокращенно от "properties". В JSX коде они передаются как атрибуты компонента. Считайте, что компонент получает `props` только для чтения. **Никогда не перезаписывайте значения `this.props` внутри компонента.**
|
||||
|
||||
## Компоненты как функции
|
||||
|
||||
Компоненты React — довольно простые сущности. Можно считать их обыкновенными функциями, которые принимают на входе `props` и `state` (см. далее) и возвращают HTML. Если помнить об этом, то компоненты становятся простыми для понимания.
|
||||
|
||||
> Замечание:
|
||||
>
|
||||
> **Есть одно ограничение**: Компоненты React умеют возвращать только один узел. Если вам надо вернуть сразу несколько, они *должны* быть обернуты в один корневой узел.
|
||||
|
||||
## Синтаксис JSX
|
||||
|
||||
Мы убеждены, что компоненты — самый подходящий способ разделения ответственностей, гораздо более удобный чем "шаблоны" и "вынесение логики на страницу". Мы считаем, что разметка и код, который её генерирует, неотделимы друг от друга. Плюс, логика на странице часто бывает запутанной, и использование шаблонизаторов, чтобы описать её, только затрудняет работу.
|
||||
|
||||
Мы решили, что лучшим вариантом будет генерировать HTML и деревья компонентов прямо из JS кода. Так вы сможете зайдействовать всю выразительную мощь современного языка программирования для создания интерфейсов.
|
||||
|
||||
А чтобы упростить создание узлов дерева, мы ввели **опциональный** HTML-подобный синтаксис.
|
||||
|
||||
**JSX позволяет вам создавать JavaScript объекты используя синтаксис HTML**. Для генерации ссылки в React вы напишете на чистом JavaScript:
|
||||
|
||||
`React.createElement('a', {href: 'https://facebook.github.io/react/'}, 'Hello!')`
|
||||
|
||||
С JSX это станет:
|
||||
|
||||
`<a href="https://facebook.github.io/react/">Hello!</a>`
|
||||
|
||||
Мы установили, что с JSX создавать React приложения проще, и дизайнеров как правило устраивает его синтаксис. Но у разных людей разные предпочтения, поэтому стоит сказать, что **JSX необязателен при работе с React.**
|
||||
|
||||
JSX сам по себе очень прост. Чтобы узнать о нем больше, почитайте [подробно про JSX](/react/docs/jsx-in-depth.html). Или можете попробовать его в [Babel REPL](https://babeljs.io/repl/).
|
||||
|
||||
JSX похож на HTML, но но имеет существенные отличия. Почитайте про [подводные камни JSX](/react/docs/jsx-gotchas.html), чтобы понять их ключевые различия.
|
||||
|
||||
[Babel предлагает несколько способов начать работу с JSX](http://babeljs.io/docs/setup/), от консольных утилит до интеграций с Ruby on Rails. Выберите тот инструмент, который лучше всего вам подходит.
|
||||
|
||||
## React без использования JSX
|
||||
|
||||
JSX полностью опционален; вам совсем необязательно использовать его вместе с React. Вы можете создавать React-элементы на чистом JavaScript используя функцию `React.createElement`, которая принимает имя тега или компонента, объект со свойствами, и набор необязательных дочерних элементов.
|
||||
|
||||
```javascript
|
||||
var child1 = React.createElement('li', null, 'First Text Content');
|
||||
var child2 = React.createElement('li', null, 'Second Text Content');
|
||||
var root = React.createElement('ul', { className: 'my-list' }, child1, child2);
|
||||
ReactDOM.render(root, document.getElementById('example'));
|
||||
```
|
||||
|
||||
Для удобства, вы можете создать сокращенные фабричные функции, чтобы создавать React-элементы из ваших собственных компонентов.
|
||||
|
||||
```javascript
|
||||
var Factory = React.createFactory(ComponentClass);
|
||||
...
|
||||
var root = Factory({ custom: 'prop' });
|
||||
ReactDOM.render(root, document.getElementById('example'));
|
||||
```
|
||||
|
||||
А для базовых HTML тегов в React уже есть встроенные фабрики:
|
||||
|
||||
```javascript
|
||||
var root = React.DOM.ul({ className: 'my-list' },
|
||||
React.DOM.li(null, 'Text Content')
|
||||
);
|
||||
```
|
||||
@@ -1,124 +0,0 @@
|
||||
---
|
||||
id: displaying-data-zh-CN
|
||||
title: 显示数据
|
||||
permalink: docs/displaying-data-zh-CN.html
|
||||
prev: why-react-zh-CN.html
|
||||
next: jsx-in-depth-zh-CN.html
|
||||
---
|
||||
|
||||
用户界面能做的最基础的事就是显示一些数据。React 让显示数据变得简单,当数据变化的时候,用户界面会自动同步更新。
|
||||
|
||||
## 开始
|
||||
|
||||
让我们看一个非常简单的例子。新建一个名为 `hello-react.html` 的文件,代码内容如下:
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Hello React</title>
|
||||
<script src="https://npmcdn.com/react@{{site.react_version}}/dist/react.js"></script>
|
||||
<script src="https://npmcdn.com/react-dom@{{site.react_version}}/dist/react-dom.js"></script>
|
||||
<script src="https://npmcdn.com/babel-core@5.8.38/browser.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="example"></div>
|
||||
<script type="text/babel">
|
||||
|
||||
// ** 在这里替换成你的代码 **
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
在接下去的文档中,我们只关注 JavaScript 代码,假设我们把代码插入到上面那个模板中。用下面的代码替换掉上面用来占位的注释。
|
||||
|
||||
```javascript
|
||||
var HelloWorld = React.createClass({
|
||||
render: function() {
|
||||
return (
|
||||
<p>
|
||||
Hello, <input type="text" placeholder="Your name here" />!
|
||||
It is {this.props.date.toTimeString()}
|
||||
</p>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
setInterval(function() {
|
||||
ReactDOM.render(
|
||||
<HelloWorld date={new Date()} />,
|
||||
document.getElementById('example')
|
||||
);
|
||||
}, 500);
|
||||
```
|
||||
|
||||
## 被动更新 (Reactive Updates)
|
||||
|
||||
在浏览器中打开 `hello-react.html` ,在输入框输入你的名字。你会发现 React 在用户界面中只改变了时间, 任何你在输入框输入的内容一直保留着,即使你没有写任何代码来完成这个功能。React 为你解决了这个问题,做了正确的事。
|
||||
|
||||
我们想到的方法是除非不得不操作 DOM ,React 是不会去操作 DOM 的。**它用一种更快的内置仿造的 DOM 来操作差异,为你计算出出效率最高的 DOM 改变**。
|
||||
|
||||
对这个组件的输入称为 `props` - "properties"的缩写。得益于 JSX 语法,它们通过参数传递。你必须知道在组件里,这些属性是不可改变的,也就是说 **`this.props` 是只读的**。
|
||||
|
||||
## 组件就像是函数
|
||||
|
||||
React 组件非常简单。你可以认为它们就是简单的函数,接受 `props` 和 `state` (后面会讨论) 作为参数,然后渲染出 HTML。正是应为它们是这么的简单,这使得它们非常容易理解。
|
||||
|
||||
> 注意:
|
||||
>
|
||||
> **只有一个限制**: React 组件只能渲染单个根节点。如果你想要返回多个节点,它们*必须*被包含在同一个节点里。
|
||||
|
||||
## JSX 语法
|
||||
|
||||
我们坚信组件是正确方法去做关注分离,而不是通过“模板”和“展示逻辑”。我们认为标签和生成它的代码是紧密相连的。此外,展示逻辑通常是很复杂的,通过模板语言实现这些逻辑会产生大量代码。
|
||||
|
||||
我们得出解决这个问题最好的方案是通过 JavaScript 直接生成模板,这样你就可以用一个真正语言的所有表达能力去构建用户界面。
|
||||
|
||||
为了使这变得更简单,我们做了一个非常简单、**可选**类似 HTML 语法 ,通过函数调用即可生成模板的编译器,称为 JSX。
|
||||
|
||||
**JSX 让你可以用 HTML 语法去写 JavaScript 函数调用** 为了在 React 生成一个链接,通过纯 JavaScript 你可以这么写:
|
||||
|
||||
`React.createElement('a', {href: 'https://facebook.github.io/react/'}, 'Hello React!')`。
|
||||
|
||||
通过 JSX 这就变成了
|
||||
|
||||
`<a href="https://facebook.github.io/react/">Hello React!</a>`。
|
||||
|
||||
我们发现这会使搭建 React 应用更加简单,设计师也偏向用这用语法,但是每个人可以有它们自己的工作流,所以**JSX 不是必须用的。**
|
||||
|
||||
JSX 非常小;上面“hello, world”的例子使用了 JSX 所有的特性。想要了解更多,请看 [深入理解 JSX](/react/docs/jsx-in-depth-zh-CN.html)。或者直接使用[在线 JSX 编译器](/react/jsx-compiler.html)观察变化过程。
|
||||
|
||||
JSX 类似于 HTML,但不是完全一样。参考 [JSX 陷阱](/react/docs/jsx-gotchas-zh-CN.html) 学习关键区别。
|
||||
|
||||
[Babel 公开了一些使用 JSX 的方式],从命令行工具到 Ruby on Rails 集成。选择一个对你来说最合适的工具。
|
||||
|
||||
## 没有 JSX 的 React
|
||||
|
||||
JSX完全是可选的;你无需在 React 中必须使用 JSX。你可以通过 `React.createElement` 来创建一个树。第一个参数是标签,第二个参数是一个属性对象,第三个是子节点。
|
||||
|
||||
```javascript
|
||||
var child1 = React.createElement('li', null, 'First Text Content');
|
||||
var child2 = React.createElement('li', null, 'Second Text Content');
|
||||
var root = React.createElement('ul', { className: 'my-list' }, child1, child2);
|
||||
ReactDOM.render(root, document.getElementById('example'));
|
||||
```
|
||||
|
||||
方便起见,你可以创建基于自定义组件的速记工厂方法。
|
||||
|
||||
```javascript
|
||||
var Factory = React.createFactory(ComponentClass);
|
||||
...
|
||||
var root = Factory({ custom: 'prop' });
|
||||
ReactDOM.render(root, document.getElementById('example'));
|
||||
```
|
||||
|
||||
React 已经为 HTML 标签提供内置工厂方法。
|
||||
|
||||
```javascript
|
||||
var root = React.DOM.ul({ className: 'my-list' },
|
||||
React.DOM.li(null, 'Text Content')
|
||||
);
|
||||
```
|
||||
@@ -1,125 +0,0 @@
|
||||
---
|
||||
id: displaying-data-zh-TW
|
||||
title: Displaying Data
|
||||
permalink: docs/displaying-data-zh-TW.html
|
||||
prev: why-react-zh-TW.html
|
||||
next: jsx-in-depth-zh-TW.html
|
||||
---
|
||||
|
||||
在使用者介面所能做最基本的事情就是呈現資料. React讓呈現資料變得更加容易並且當資料有所變動時也能自動地讓使用者介面保持呈現最新的資料.
|
||||
|
||||
## 入門(Getting Started)
|
||||
|
||||
我們從一個相當簡單的範例開始. 建立一個名為 `hello-react.html` 的檔案裡面包含下列程式碼:
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Hello React</title>
|
||||
<script src="https://npmcdn.com/react@{{site.react_version}}/dist/react.js"></script>
|
||||
<script src="https://npmcdn.com/react-dom@{{site.react_version}}/dist/react-dom.js"></script>
|
||||
<script src="https://npmcdn.com/babel-core@5.8.38/browser.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="example"></div>
|
||||
<script type="text/babel">
|
||||
|
||||
// ** 將你的程式碼放在這裡! **
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
這份文件其他部份,我們將只會專注在JavaScript程式碼解說上,並且假設程式碼會被放置在如上述模板的註解區塊內. 用下列的JSX程式碼取代上述註解區塊:
|
||||
|
||||
```javascript
|
||||
var HelloWorld = React.createClass({
|
||||
render: function() {
|
||||
return (
|
||||
<p>
|
||||
Hello, <input type="text" placeholder="Your name here" />!
|
||||
It is {this.props.date.toTimeString()}
|
||||
</p>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
setInterval(function() {
|
||||
ReactDOM.render(
|
||||
<HelloWorld date={new Date()} />,
|
||||
document.getElementById('example')
|
||||
);
|
||||
}, 500);
|
||||
```
|
||||
|
||||
## 反應性更新(Reactive Updates)
|
||||
|
||||
在一個瀏覽器上開啟檔案 `hello-react.html` 並且在文字區塊填入你的名字. 請注意React僅僅改變UI上的時間字串 — 你在文字區塊輸入的任何文字依舊存在, 即使你並沒有寫任何程式碼來管理這個行為.React可以為你分辨出這樣的行為並且做出正確的回應.
|
||||
|
||||
之所以能夠分辨出這樣的行為是因為React除非在真正有必要的情況下,否則不會對DOM做任何操作. **它使用一個快速的, 內部虛擬的DOM(internal mock DOM)來為你施行比較和計算最有效率的DOM變動(DOM mutation)**
|
||||
|
||||
輸入到元件(component)的內容我們稱為`props` — 是屬性("properties")的簡稱. 他們在JSX語法中作為傳遞屬性之用. 你應該把這些屬性當做元件中不可被改變的, 也就是說, **永遠不要對 `this.props` 做寫入的行為**.
|
||||
|
||||
## 元件就是函數(Components are Just Like Functions)
|
||||
|
||||
React元件(components)是非常簡單的. 你能把它們想成是簡單的函數帶入`props`和`state`(後面會討論這部份)並且呈送給HTML(render HTML). 在心中保持住這個想法, 就能容易理解元件(components).
|
||||
React components are very simple. You can think of them as simple functions that take in `props` and `state` (discussed later) and render HTML. With this in mind, components are easy to reason about.
|
||||
|
||||
> 注意(Note):
|
||||
>
|
||||
> **一個局限性**: React元件(components)只能呈送(render)給一個單一根節點(root node). 如果你想要回傳多個節點(multiple nodes)他們*必須*被包裹在單一根節點內.
|
||||
|
||||
## JSX語法
|
||||
|
||||
我們深信元件(components)才是分離關注點(separate concerns)的正確方法, 而並非傳統的模板("templates")和顯示邏輯("display logic")觀念. 我們認為標記(markup)和產生它的程式碼應當緊密的綁在一起. 另外, 顯示邏輯(display logic)常常是非常複雜的, 若使用模板語言(template languages)來詮釋它就顯得笨重或累贅.
|
||||
|
||||
我們找到解決這個問題的最佳解答就是直接在JavaScript程式內產生HTML和元件樹(component trees)如此一來你就能使用真正的程式語言的表達能力(expressive power)來建立使用者介面(UIs).
|
||||
|
||||
為了能更輕鬆實現, 我們增加了一個非常簡單, **可選擇性使用的** 類似HTML的語法(HTML-like syntax) 來創建這些React樹節點(React tree nodes).
|
||||
|
||||
**JSX能讓你使用HTML語法來創建JavaScript物件.** 在React裡使用純JavaScript來產生一個鏈接(link)你可以這樣寫:
|
||||
|
||||
`React.createElement('a', {href: 'https://facebook.github.io/react/'}, 'Hello!')`
|
||||
|
||||
使用JSX語法則變成:
|
||||
|
||||
`<a href="https://facebook.github.io/react/">Hello!</a>`
|
||||
|
||||
我們發現這麼做能讓建立React apps更加容易並且設計師往往喜歡語法, 但是每個人都有他們自己的工作流程, 所以**在使用React時JSX並非必要.**
|
||||
|
||||
JSX非常簡單易懂. 若想要學習更多關於JSX, 請參閱 [JSX in depth](/react/docs/jsx-in-depth.html). 或是可以使用線上及時轉換工具 [the Babel REPL](https://babeljs.io/repl/).
|
||||
|
||||
JSX類似於HTML, 但不盡然完全相同. 參閱 [JSX gotchas](/react/docs/jsx-gotchas.html) 來比較一些主要的差異點.
|
||||
|
||||
[Babel exposes a number of ways to get started using JSX](http://babeljs.io/docs/setup/), 涵蓋從命令列工具到Ruby on Rails整合. 可以從中選擇最適合你的工具.
|
||||
|
||||
## React不使用JSX的範例(React without JSX)
|
||||
|
||||
JSX完全是可選擇性使用的; 你可以不拿JSX跟React一起使用. 你能在純粹的JavaScript環境中使用`React.createElement`來創建React元素(React elements), 它搭配一個標籤名(tag name)或是元件(component), 一個屬性物件(properties object), 和數個選擇性子參數(child arguments).
|
||||
|
||||
```javascript
|
||||
var child1 = React.createElement('li', null, 'First Text Content');
|
||||
var child2 = React.createElement('li', null, 'Second Text Content');
|
||||
var root = React.createElement('ul', { className: 'my-list' }, child1, child2);
|
||||
ReactDOM.render(root, document.getElementById('example'));
|
||||
```
|
||||
|
||||
為了方便起見, 你能創建速記factory函式(short-hand factory functions)然後從自訂元件(custom components)建立元素(elements).
|
||||
|
||||
```javascript
|
||||
var Factory = React.createFactory(ComponentClass);
|
||||
...
|
||||
var root = Factory({ custom: 'prop' });
|
||||
ReactDOM.render(root, document.getElementById('example'));
|
||||
```
|
||||
|
||||
針對一般的HTML標籤React已經有內建的factories函式:
|
||||
|
||||
```javascript
|
||||
var root = React.DOM.ul({ className: 'my-list' },
|
||||
React.DOM.li(null, 'Text Content')
|
||||
);
|
||||
```
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user