Compare commits

..

111 Commits

Author SHA1 Message Date
Paul O’Shannessy
e278ce4445 v0.14.6 2016-01-06 15:26:33 -08:00
Paul O’Shannessy
06cad05d49 Changelog & Readme for v0.14.6 2016-01-06 15:21:05 -08:00
Paul O’Shannessy
f305deb065 Upgrade to fbjs@^0.6.1 2016-01-06 15:21:05 -08:00
Paul O’Shannessy
9c091afe74 bump version for 0.14.6 dev 2016-01-06 15:02:22 -08:00
Ben Alpert
fb6b3b05f4 Website for 0.14.5 2015-12-29 14:39:05 -08:00
Ben Alpert
575cf6a82e v0.14.5 2015-12-29 14:37:06 -08:00
Ben Alpert
d6a0a083e4 Readme for 0.14.5 2015-12-29 14:36:24 -08:00
Ben Alpert
e7b178390d Changelog for 0.14.5 2015-12-29 14:36:15 -08:00
Ben Alpert
a9732ba548 Upgrade fbjs to 0.6 in npm package too 2015-12-29 14:35:10 -08:00
Ben Alpert
05269bf16b Bump version for 0.14.5 dev 2015-12-29 14:34:38 -08:00
Ben Alpert
093a97c54b 0.14.4 blog post
(cherry picked from commit 2a64098271)
2015-12-29 14:19:27 -08:00
Ben Alpert
0d5d0b2688 Update a few changelog things forgotten in 3f355d99 2015-12-29 14:09:26 -08:00
Ben Alpert
c8398491d8 update website for 0.14.4 2015-12-29 14:01:54 -08:00
Ben Alpert
149613d065 v0.14.4 2015-12-29 13:51:43 -08:00
Ben Alpert
0516e74473 Update readme for 0.14.4 2015-12-29 13:51:43 -08:00
Ben Alpert
3f355d99c5 Changelog for 0.14.4 2015-12-29 13:51:43 -08:00
Ben Alpert
a29b4938a8 Upgrade fbjs to 0.6, shrinkwrap 2015-12-29 13:51:43 -08:00
Timothy Yung
142059d294 Remove "Invariant Violation: " from Invariant Error Messages
(cherry picked from commit cdaea311a3)

Conflicts:
	src/isomorphic/classic/class/__tests__/ReactClassMixin-test.js
	src/isomorphic/modern/element/__tests__/ReactJSXElementValidator-test.js
	src/renderers/dom/server/__tests__/ReactServerRendering-test.js
	src/renderers/shared/reconciler/__tests__/ReactInstanceHandles-test.js
2015-12-29 13:51:43 -08:00
Ben Alpert
d2dde00940 Add shim files for RN in npm package
(cherry picked from commit c29642d6ed)
2015-12-29 13:51:43 -08:00
Ben Alpert
d9bf86e83a Import ResponderEventPlugin changes from RN
(manual cherry-pick of bb11639e25)
2015-12-29 13:51:43 -08:00
Paul O’Shannessy
527d7b154b Merge pull request #5623 from freddyrangel/autocorrect_autocapitalize
Autocorrect and autocapitalize should not be property
(cherry picked from commit eee5d466a6)
2015-12-29 13:51:43 -08:00
Ben Alpert
f8777eea9e Merge pull request #5595 from remko/select-bug
Fix single select incorrectly updating
(cherry picked from commit 2f77367863)

Conflicts:
	src/renderers/dom/client/wrappers/__tests__/ReactDOMSelect-test.js
2015-12-29 13:51:43 -08:00
Jim
6dd8427c20 Merge pull request #5564 from jackiewung/master
Fix file reference typo in starter
(cherry picked from commit 940a75b1fe)
2015-12-29 13:51:43 -08:00
Ben Alpert
33cae8c9b1 Merge pull request #5500 from hejld/master
Update DOM_OPERATION_TYPES mappings for ReactDefaultPerfAnalysis
(cherry picked from commit 812e1a877f)
2015-12-29 13:51:42 -08:00
Ben Alpert
881d023c0e Bump version for 0.14.4 dev 2015-12-29 13:39:40 -08:00
Paul O’Shannessy
926378cacb Merge pull request #5716 from jwworth/pull-request-1450816256
Fix typos in posts
(cherry picked from commit a0741ab468)
2015-12-23 12:53:59 -08:00
Jim
343109e248 Merge pull request #5712 from dortonway/master
Fix misunderstanding in tutorial
(cherry picked from commit 4865ddf7ea)
2015-12-23 12:53:59 -08:00
Paul O’Shannessy
5fd421c996 Merge pull request #5711 from iamchenxin/docs122215
[docs] Update zh-docs with 7e2a7f0
(cherry picked from commit 1d8b816496)
2015-12-23 12:53:59 -08:00
Paul O’Shannessy
1f1a127891 Merge pull request #5709 from zpao/youtubenocookie
[docs] fixup other broken youtube-nocookie uses
(cherry picked from commit 5b98152a3d)
2015-12-23 12:53:58 -08:00
Jim
7bb2119733 Merge pull request #5708 from kchia/patch-4
Corrects grammatical errors in tutorial
(cherry picked from commit 88ce0fc95f)
2015-12-23 12:53:58 -08:00
Jim
a4ad2b4e54 Merge pull request #5701 from cesarwbr/patch-1
Fix typo in youtube url for video in blog post.
(cherry picked from commit 8d0efaf980)
2015-12-23 12:53:58 -08:00
Jim
050b8f1875 Merge pull request #5699 from jwworth/pull-request-1450702663
Fix typo (duplicate word)
(cherry picked from commit 9c57c30049)
2015-12-23 12:53:58 -08:00
Paul O’Shannessy
821104185e Merge pull request #5698 from facebook/Daniel15-patch-1
Remove smart quotes from code snippet in blog post
(cherry picked from commit 1b85c9a6c4)
2015-12-23 12:53:58 -08:00
Jim
dc5411c795 Merge pull request #5599 from zramaekers/shallow-compare-docs
Add documentation for shallowCompare addon
(cherry picked from commit ab37776cc2)
2015-12-23 12:53:58 -08:00
Dan Abramov
a1decaf2a5 Merge pull request #5695 from gaearon/patch-2
Fix children to be a prop in the blog post example
(cherry picked from commit 50af034108)
2015-12-21 20:20:53 +00:00
Paul O’Shannessy
b6dc8681bb Merge pull request #5693 from gaearon/elements-post
Added post about components, elements, and instances
(cherry picked from commit bdca170d2a)
2015-12-18 12:43:53 -08:00
Jim
4588820073 Merge pull request #5587 from jimfb/ismounted-alternatives
Added post about upgrading your code to avoid isMounted()
(cherry picked from commit ccb97d8e59)
2015-12-16 09:57:58 -08:00
Paul O’Shannessy
852a63fe23 Merge pull request #5658 from applegrain/clarify-dependency-installation
Clarify dependency installation
(cherry picked from commit b6a01d7733)
2015-12-16 09:57:58 -08:00
Jim
617cfdd434 Merge pull request #5655 from adraeth/patch-1
Correct highlight in tutorial7.js snippet
(cherry picked from commit 55bd203310)
2015-12-16 09:57:58 -08:00
Jim
85c09e5507 Merge pull request #5605 from thekevlau/patch-1
Adding class->className as a JSX gotcha
(cherry picked from commit 410cc30bf9)
2015-12-16 09:57:58 -08:00
Jim
235b914797 Merge pull request #5609 from vitorbal/patch-1
Clarify usage of `.propTypes` when using functional components
(cherry picked from commit bb084eba24)
2015-12-16 09:57:58 -08:00
Jim
9ed0fdb850 Merge pull request #5643 from koh-taka/patch-1
Fix wrong script name (showdown -> marked)
(cherry picked from commit eeee272268)
2015-12-16 09:57:58 -08:00
Jim
e2e04fdbc3 Merge pull request #5644 from AndrewHenderson/patch-1
Helps avoid a common Issue when following tutorial
(cherry picked from commit f282710072)
2015-12-16 09:57:58 -08:00
Jim
1f41a53d1e Merge pull request #5588 from jimfb/setprops-replaceprops-deprecated
Increase severity of setprops and replaceprops deprecations, since their removal is now imminent.
(cherry picked from commit f4744f3a70)
2015-12-16 09:57:58 -08:00
Jim
3ef0838567 Merge pull request #5589 from wrakky/fix-minlength-docs
Rename minlength to minLength in the tags and attributes documentation page
(cherry picked from commit 526d5c0edc)
2015-12-16 09:57:58 -08:00
Paul O’Shannessy
319a266941 Merge pull request #5559 from shogunsea/docs-add-marked
[docs]Add marked source in tutorial doc
(cherry picked from commit 0be7786e1c)
2015-12-16 09:57:58 -08:00
Paul O’Shannessy
d5f312866b Merge pull request #5584 from zwhitchcox/patch-2
Update ref-10-glossary.md
(cherry picked from commit 3ca15b0090)
2015-12-16 09:57:58 -08:00
Paul O’Shannessy
2c5dadb0c5 [blog] Another typo fix for diversity post 2015-12-04 14:37:14 -08:00
Paul O’Shannessy
0f7fad10d6 [blog] Fix typo in diversity post 2015-12-04 12:53:02 -08:00
Paul O’Shannessy
da7b9043a4 [blog] Diversity Scholarship 2016 2015-12-04 11:55:16 -08:00
Paul O’Shannessy
cc92028f11 Merge pull request #5581 from yuyokk/patch-1
Update 08.1-more-about-refs.md
(cherry picked from commit f5840e685e)
2015-12-01 11:53:06 -08:00
Paul O’Shannessy
969014c832 Merge pull request #5556 from timuric/patch-1
Avoid mutating state in the example code
(cherry picked from commit d54b151bc2)
2015-12-01 11:53:06 -08:00
Paul O’Shannessy
b335180686 Merge pull request #5546 from cody/singlechild
[docs] Single Child
(cherry picked from commit 6b641de6b8)
2015-12-01 11:53:06 -08:00
Ben Alpert
33717bc425 Merge pull request #5543 from spicyj/rt103
Clarify wording in the tutorial
(cherry picked from commit 3722616349)
2015-12-01 11:53:06 -08:00
Paul O’Shannessy
9921659616 Merge pull request #5539 from matthewlooi/addCodeHighlightToTutorialDoc
Add highlight to a line of code to tutorial21.js
(cherry picked from commit e95d3dd812)
2015-12-01 11:53:06 -08:00
Paul O’Shannessy
f974581a6a Merge pull request #5533 from kryogenic/patch-1
Use null instead of '' in ternary expression
(cherry picked from commit d01188133e)
2015-12-01 11:53:06 -08:00
Paul O’Shannessy
ef20f03429 Merge pull request #5526 from yangshun/todo-app-id
[docs] Use id for TodoApp example
(cherry picked from commit 34fbcf20d8)
2015-12-01 11:53:06 -08:00
Paul O’Shannessy
1eed5b0e10 Merge pull request #5523 from hejld/add-selection-and-composition-events-on-reference-page
[docs] Add missing sections to events reference page in IT and CN
(cherry picked from commit 54e6057b1a)
2015-12-01 11:53:06 -08:00
Paul O’Shannessy
934d5b642e Merge pull request #5520 from mhujer/docs-spread-fix-babel
Docs: Transform rest and spread properties using Babel 6
(cherry picked from commit f48bb3a274)
2015-12-01 11:53:06 -08:00
Paul O’Shannessy
40e4655a5e Merge pull request #5518 from mhujer/docs-spread-fix
Docs: Rest and Spread Properties - ECMAScript
(cherry picked from commit c5867ea401)
2015-12-01 11:53:06 -08:00
Paul O’Shannessy
789a9b70cb Merge pull request #5511 from KeweiCodes/patch-1
Typo
(cherry picked from commit 1cdbff26ab)
2015-12-01 11:53:06 -08:00
Paul O’Shannessy
3a793ba27b Merge pull request #5508 from yangshun/patch-1
Add in missing closing </li> for docs template
(cherry picked from commit aa1e58a41b)
2015-12-01 11:53:05 -08:00
Paul O’Shannessy
3f2f763dea update website for 0.14.3 2015-11-18 18:12:07 -08:00
Paul O’Shannessy
c389c1def5 v0.14.3 2015-11-18 18:08:52 -08:00
Paul O’Shannessy
1cef6ebabf Update readme for 0.14.3 2015-11-18 18:03:41 -08:00
Paul O’Shannessy
f92a630737 v0.14.3 blog post 2015-11-18 18:01:07 -08:00
Paul O’Shannessy
55b6839684 Changelog for 0.14.3 2015-11-18 13:18:26 -08:00
Paul O’Shannessy
e6f8ad33cf Merge pull request #5501 from zpao/release-react-dom-server
Make sure react-dom-server is shipped in release process
(cherry picked from commit d1eba1f78c)
2015-11-18 13:18:26 -08:00
Paul O’Shannessy
c806ed1128 Merge pull request #5496 from zpao/reactdomserverfollowup
Followup to #5381
(cherry picked from commit 60cba8fcf7)
2015-11-18 13:18:26 -08:00
Paul O’Shannessy
294b50a695 Merge pull request #5381 from kevinrobinson/react-dom-server-package
Add additional secret property to build artifact for react-dom-server
(cherry picked from commit c07b304c76)
2015-11-18 13:18:26 -08:00
Ben Alpert
22c9562cd9 Merge pull request #5330 from laskos/fix-shallow-rendering-function-refs
Fix shallow renderer with ref as function
(cherry picked from commit 1a6d1e74e0)
2015-11-18 13:18:26 -08:00
Paul O’Shannessy
cde2de3ce7 Merge pull request #5431 from zpao/license-in-packages
Ensure license and patents files are packaged for npm
(cherry picked from commit fc245226f9)
2015-11-18 12:29:36 -08:00
Paul O’Shannessy
061725c9b6 Merge pull request #5417 from zpao/ol-reversed
Support reversed for <ol>s
(cherry picked from commit e7a5a98044)
2015-11-18 12:29:17 -08:00
Paul O’Shannessy
ed11bdc5bf Merge pull request #5442 from nickclaw/patch-1
Allow nonce attribute
(cherry picked from commit 575d1a5093)
2015-11-18 12:19:13 -08:00
Jim
319c5c4453 Merge pull request #5391 from zjjw/transition_timeouts
Clear transition timeouts when component unmounts. Fixes #4876
(cherry picked from commit 59dd7b33ee)
2015-11-18 12:17:38 -08:00
Paul O’Shannessy
19678baa1a Merge pull request #5396 from zpao/packagejsons
Improve npm packages' metadata
(cherry picked from commit 6d5fe44c86)
2015-11-18 12:16:42 -08:00
Paul O’Shannessy
a43dfdc33d Bump version for 0.14.3 dev 2015-11-18 12:08:51 -08:00
Paul O’Shannessy
9265032a12 Merge pull request #5445 from yangshun/controlled-components-in-tutorial
Use controlled components in tutorial
(cherry picked from commit 904e9e3ea6)
2015-11-17 23:01:09 -08:00
Jim
36db2aeeb0 Merge pull request #2774 from jimfb/webcomponents
Added info (example+doc) about react with webcomponents
(cherry picked from commit 80bcc519d7)
2015-11-17 23:00:58 -08:00
Paul O’Shannessy
ca8ad7ff8e [docs] Properly fix Korean docs
(cherry picked from commit 034cfc96c7)
2015-11-12 16:00:57 -08:00
Paul O’Shannessy
30ec56a027 [docs] Use updated Korean translation
See #5456 for details

(cherry picked from commit 72d9a8bc15)
2015-11-12 14:27:31 -08:00
Paul O’Shannessy
5e9f00a4b6 Merge pull request #5456 from hugo-agbonon/fix-classname-manipulation-doc
Revert class name manipulation doc to english
(cherry picked from commit 2d5612913f)
2015-11-12 14:27:26 -08:00
Paul O’Shannessy
a23bab0cf5 Merge pull request #5444 from zpao/tutorial-ids-for-data
[tutorial] Use ids in comments data
(cherry picked from commit 09b7ff1fc4)
2015-11-12 14:27:21 -08:00
Paul O’Shannessy
6bf6beb2d2 Merge pull request #5416 from bbrooks/undo-optimistic-update-on-error
Reset state if comment submit fails
(cherry picked from commit eecd2953cd)
2015-11-12 14:27:17 -08:00
Jim
c796629e66 Merge pull request #5412 from yangshun/document-next-context
Add more documentation to Context page
(cherry picked from commit 4cb210a9da)
2015-11-12 14:27:11 -08:00
Jim
3eed5deead Merge pull request #5403 from yuyokk/patch-1
Clarify note about stable keys
(cherry picked from commit d6a547f793)
2015-11-10 10:44:16 -08:00
Jim
3b97d5e30c Merge pull request #5424 from stowball/animation-docs-whitespace
Removed unnecessary whitespace before closing bracket
(cherry picked from commit a88c39be86)
2015-11-10 10:44:09 -08:00
Ben Alpert
fd05a6ee7d Merge pull request #5287 from benhalpern/patch-1
Updated conference page
(cherry picked from commit 99fbde54a1)
2015-11-10 10:44:05 -08:00
Jim
17761fae9b Merge pull request #5231 from davidkpiano/patch-1
Updating "JSX Gotchas" docs for Custom Attributes
(cherry picked from commit 22b8952fbf)
2015-11-10 10:43:58 -08:00
Jim
34bb99b07f Merge pull request #5385 from marocchino/update-korean
Update korean translation to 84af306
(cherry picked from commit 4fae036269)
2015-11-10 10:43:53 -08:00
Jim
4fda3eb9da Merge pull request #5372 from csbok/patch-1
Update getting-started.ko-KR.md
(cherry picked from commit 84af306044)
2015-11-10 10:43:48 -08:00
Ben Alpert
c6c3c0e255 Merge pull request #5356 from rpominov/patch-1
fix shallowRenderer.getRenderOutput() return type in docs
(cherry picked from commit 17289020f7)
2015-11-10 10:43:41 -08:00
Paul O’Shannessy
807c555c77 Merge pull request #5370 from zpao/babel6docs
Update docs for Babel 6
(cherry picked from commit b9371bc216)
2015-11-02 17:01:35 -08:00
Paul O’Shannessy
fdf6f6bbb0 Update website for 0.14.2 2015-11-02 11:50:20 -08:00
Paul O’Shannessy
5a2312c8e5 v0.14.2 2015-11-02 11:45:57 -08:00
Paul O’Shannessy
01622a4442 Update readme for 0.14.2 2015-11-02 11:38:29 -08:00
Paul O’Shannessy
a4fd08973b Blog post for 0.14.2 2015-11-02 11:34:37 -08:00
Paul O’Shannessy
c2dd57c6a6 Changelog for 0.14.2 2015-11-02 11:34:36 -08:00
Paul O’Shannessy
db23e49467 Update haste package version for branch 2015-11-02 11:27:53 -08:00
Paul O’Shannessy
3117584e0e Merge pull request #5367 from spicyj/haste-manifest
Add package.json for react-haste package
(cherry picked from commit 72a11421d2)
2015-11-02 11:27:53 -08:00
Paul O’Shannessy
26258313cd Merge pull request #5366 from zpao/react-dom-peer-dep
Make React a peerDep of react-dom
(cherry picked from commit a82400faa2)
2015-11-02 11:27:53 -08:00
Jim
d602f1d3fb Merge pull request #5093 from jimfb/avoid-children-to-string-coercion
Should not coerce children prop on custom elements to a string.  Fixes #5088
(cherry picked from commit a2d26c82ea)
2015-11-02 10:08:26 -08:00
Jim
c181b824ca Merge pull request #5341 from zpao/domprop-integrity
Add integrity to HTML property config
(cherry picked from commit 0c790baf31)
2015-11-02 10:04:44 -08:00
Paul O’Shannessy
d6100a703f Merge pull request #5328 from zpao/non-native-event-name-dispatch
Use a custom event type for our event dispatching in ReactErrorUtils
(cherry picked from commit 12c214a992)
2015-11-02 10:04:39 -08:00
Paul O’Shannessy
afef42e377 Merge pull request #5327 from zpao/definepropgetter
Use a getter for canDefineProperty check.
(cherry picked from commit 606aa61209)
2015-11-02 10:04:33 -08:00
Paul O’Shannessy
24059873ac Bump version for 0.14.2-alpha 2015-11-02 10:03:45 -08:00
Paul O’Shannessy
bac2462dd5 Merge pull request #5348 from hzoo/patch-2
add docs for babel 6
(cherry picked from commit 88bae3fb73)
2015-10-31 12:20:24 -07:00
Paul O’Shannessy
878482154e Merge pull request #5235 from wincent/update-blog-syntax
Update syntax in older Relay blog post that may be causing confusion
(cherry picked from commit c35b4384f7)
2015-10-31 12:20:18 -07:00
Jim
bfba064631 Merge pull request #5316 from Third9/master
update Korean docs to 0.14
(cherry picked from commit fbf4cbbae6)
2015-10-31 12:20:13 -07:00
Jim
0f6a151650 Merge pull request #5317 from nickbalestra/patch-1
Update 02.1-jsx-in-depth.md
(cherry picked from commit 01341480c2)
2015-10-31 12:20:03 -07:00
Paul O’Shannessy
f0782e2b2e Update website for 0.14.1 2015-10-28 14:24:49 -07:00
175 changed files with 9344 additions and 1681 deletions

View File

@@ -16,4 +16,4 @@ packages/react-codemod/test/
packages/react-codemod/scripts/
packages/react-codemod/build/
packages/react-codemod/node_modules/
vendor/react-dom.js
vendor/*

View File

@@ -54,6 +54,8 @@ script:
-F "react-with-addons.min=@build/react-with-addons.min.js" \
-F "react-dom=@build/react-dom.js" \
-F "react-dom.min=@build/react-dom.min.js" \
-F "react-dom-server=@build/react-dom-server.js" \
-F "react-dom-server.min=@build/react-dom-server.min.js" \
-F "npm-react=@build/packages/react.tgz" \
-F "npm-react-dom=@build/packages/react-dom.tgz" \
-F "commit=$TRAVIS_COMMIT" \

View File

@@ -1,3 +1,54 @@
## 0.14.6 (January 6, 2015)
### React
- Updated `fbjs` dependency to pick up change affecting handling of undefined document.
## 0.14.5 (December 29, 2015)
### React
- More minor internal changes for better compatibility with React Native
## 0.14.4 (December 29, 2015)
### React
- Minor internal changes for better compatibility with React Native
### React DOM
- The `autoCapitalize` and `autoCorrect` props are now set as attributes in the DOM instead of properties to improve cross-browser compatibility
- Fixed bug with controlled `<select>` elements not handling updates properly
### React Perf Add-on
- Some DOM operation names have been updated for clarity in the output of `.printDOM()`
## 0.14.3 (November 18, 2015)
### React DOM
- Added support for `nonce` attribute for `<script>` and `<style>` elements
- Added support for `reversed` attribute for `<ol>` elements
### React TestUtils Add-on
- Fixed bug with shallow rendering and function refs
### React CSSTransitionGroup Add-on
- Fixed bug resulting in timeouts firing incorrectly when mounting and unmounting rapidly
### React on Bower
- Added `react-dom-server.js` to expose `renderToString` and `renderToStaticMarkup` for usage in the browser
## 0.14.2 (November 2, 2015)
### React DOM
- Fixed bug with development build preventing events from firing in some versions of Internet Explorer & Edge
- Fixed bug with development build when using es5-sham in older versions of Internet Explorer
- Added support for `integrity` attribute
- Fixed bug resulting in `children` prop being coerced to a string for custom elements, which was not the desired behavior
- Moved `react` from `dependencies` to `peerDependencies` to match expectations and align with `react-addons-*` packages
## 0.14.1 (October 28, 2015)
### React DOM

View File

@@ -37,12 +37,12 @@ The fastest way to get started is to serve JavaScript from the CDN (also availab
```html
<!-- The core React library -->
<script src="https://fb.me/react-0.14.1.js"></script>
<script src="https://fb.me/react-0.14.6.js"></script>
<!-- The ReactDOM Library -->
<script src="https://fb.me/react-dom-0.14.1.js"></script>
<script src="https://fb.me/react-dom-0.14.6.js"></script>
```
We've also built a [starter kit](https://facebook.github.io/react/downloads/react-0.14.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-0.14.6.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:

View File

@@ -2,9 +2,9 @@
name: React
description: A JavaScript library for building user interfaces
url: https://facebook.github.io
baseurl: "/react"
permalink: "/blog/:year/:month/:day/:title.html"
paginate_path: "/blog/page:num/"
baseurl: /react
permalink: /blog/:year/:month/:day/:title.html
paginate_path: /blog/page:num/
relative_permalinks: true
paginate: 5
timezone: America/Los_Angeles
@@ -36,4 +36,4 @@ sass:
sass_dir: _css
gems:
- jekyll-redirect-from
react_version: 0.14.0
react_version: 0.14.5

View File

@@ -13,6 +13,9 @@ Daniel15:
fisherwebdev:
name: Bill Fisher
url: https://twitter.com/fisherwebdev
gaearon:
name: Dan Abramov
url: https://twitter.com/dan_abramov
jaredly:
name: Jared Forsyth
url: https://twitter.com/jaredforsyth

View File

@@ -65,6 +65,8 @@
title: PureRenderMixin
- id: perf
title: Performance Tools
- id: shallow-compare
title: Shallow Compare
- id: advanced-performance
title: Advanced Performance
- id: context
@@ -87,6 +89,8 @@
title: Special Non-DOM Attributes
- id: reconciliation
title: Reconciliation
- id: webcomponents
title: Web Components
- id: glossary
title: React (Virtual) DOM Terminology
- title: Flux

View File

@@ -1,8 +1,8 @@
var TODO_COMPONENT = `
var TodoList = React.createClass({
render: function() {
var createItem = function(itemText, index) {
return <li key={index + itemText}>{itemText}</li>;
var createItem = function(item) {
return <li key={item.id}>{item.text}</li>;
};
return <ul>{this.props.items.map(createItem)}</ul>;
}
@@ -16,7 +16,7 @@ var TodoApp = React.createClass({
},
handleSubmit: function(e) {
e.preventDefault();
var nextItems = this.state.items.concat([this.state.text]);
var nextItems = this.state.items.concat([{text: this.state.text, id: Date.now()}]);
var nextText = '';
this.setState({items: nextItems, text: nextText});
},

View File

@@ -53,8 +53,8 @@
</ul>
<ul class="nav-site nav-site-external">
<li><a href="https://github.com/facebook/react">GitHub</a>
<li><a href="https://facebook.github.io/react-native/">React Native</a>
<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>

View File

@@ -54,7 +54,7 @@ It's great to see the React community expand internationally. [This site](http:/
### Egghead.io video tutorials
Joe Maddalone ([@joemaddalone](https://twitter.com/joemaddalone)) of [egghead.io](https://egghead.io/) created a series of React video tutorials, such as [this](http://www.youtube-nocookie.com/watch?v=rFvZydtmsxM&feature=youtu.be&a) introduction to React Components. [[part 1](http://www.youtube-nocookie.com/watch?v=rFvZydtmsxM&feature=youtu.be&a)], [[part 2](http://www.youtube-nocookie.com/watch?v=5yvFLrt7N8M)]
Joe Maddalone ([@joemaddalone](https://twitter.com/joemaddalone)) of [egghead.io](https://egghead.io/) created a series of React video tutorials, such as [this](http://www.youtube-nocookie.com/v/rFvZydtmsxM) introduction to React Components. [[part 1](http://www.youtube-nocookie.com/v/rFvZydtmsxM)], [[part 2](http://www.youtube-nocookie.com/v/5yvFLrt7N8M)]
### "React: Finally, a great server/client web stack"

View File

@@ -41,7 +41,7 @@ We have wanted to do this since before we even open sourced React. No more `/**
The React specific JSX transform no longer transforms to function calls. Instead we use `React.createElement` and pass it arguments. This allows us to make optimizations and better support React as a compile target for things like Om. Read more in the [React Elements introduction](/react/blog/2014/10/14/introducting-react-elements.html).
The result of this change is that we will no longer support arbitrary function calls. We understand that the ability to do was was a convenient shortcut for many people but we believe the gains will be worth it.
The result of this change is that we will no longer support arbitrary function calls. We understand that the ability to do was a convenient shortcut for many people but we believe the gains will be worth it.
### JSX Lower-case Convention

View File

@@ -17,7 +17,7 @@ stick with the originally planned format and venue on Facebook's campus.
Unfortunately, this means that we can only accept a small number of the awesome
conference talk proposals. In order to make sure attendees get a fair shot at
registering, we're going to to sell tickets in three separate first-come,
registering, we're going to sell tickets in three separate first-come,
first-serve phases. **Tickets will cost $200 regardless of which phase they are
purchased from and all proceeds will go to charity**.

View File

@@ -4,7 +4,7 @@ layout: post
author: steveluscher
---
It was a privilege to welcome the React community to Facebook HQ on January 2829 for the first-ever React.js Conf, and a pleasure to be be able to unveil three new technologies that we've been using internally at Facebook for some time: GraphQL, Relay, and React Native.
It was a privilege to welcome the React community to Facebook HQ on January 2829 for the first-ever React.js Conf, and a pleasure to be able to unveil three new technologies that we've been using internally at Facebook for some time: GraphQL, Relay, and React Native.
## The talks

View File

@@ -3,7 +3,7 @@ title: "Building The Facebook News Feed With Relay"
author: josephsavona
---
At React.js Conf in January we gave a preview of Relay, a new framework for building data-driven applications in React. In this post, we'll describe the process of creating a Relay application. This post assumes some familiarity with the concepts of Relay and GraphQL, so if you haven't already we recommend reading [our introductory blog post](/react/blog/2015/02/20/introducing-relay-and-graphql.html) or watching [the conference talk](https://www.youtube-nocookie.com/watch?v=9sc8Pyc51uU).
At React.js Conf in January we gave a preview of Relay, a new framework for building data-driven applications in React. In this post, we'll describe the process of creating a Relay application. This post assumes some familiarity with the concepts of Relay and GraphQL, so if you haven't already we recommend reading [our introductory blog post](/react/blog/2015/02/20/introducing-relay-and-graphql.html) or watching [the conference talk](https://www.youtube-nocookie.com/v/9sc8Pyc51uU).
We're working hard to prepare GraphQL and Relay for public release. In the meantime, we'll continue to provide information about what you can expect.
@@ -40,20 +40,18 @@ The first step is a React `<Story>` component that accepts a `story` prop with t
```javascript
// Story.react.js
class Story extends React.Component {
export default class Story extends React.Component {
render() {
var story = this.props.story;
return (
<View>
<Image uri={story.author.profile_picture.uri} />
<Image uri={story.author.profilePicture.uri} />
<Text>{story.author.name}</Text>
<Text>{story.text}</Text>
</View>
);
}
}
module.exports = Story;
```
<br/>
@@ -66,41 +64,41 @@ Relay automates the process of fetching data for components by wrapping existing
// Story.react.js
class Story extends React.Component { ... }
module.exports = Relay.createContainer(Story, {
queries: {
export default Relay.createContainer(Story, {
fragments: {
story: /* TODO */
}
});
```
Before adding the GraphQL query, let's look at the component hierarchy this creates:
Before adding the GraphQL fragment, let's look at the component hierarchy this creates:
<img src="/react/img/blog/relay-components/relay-containers.png" width="397" alt="React Container Data Flow" />
Most props will be passed through from the container to the original component. However, Relay will return the query results for a prop whenever a query is defined. In this case we'll add a GraphQL query for `story`:
Most props will be passed through from the container to the original component. However, Relay will return the query results for a prop whenever a fragment is defined. In this case we'll add a GraphQL fragment for `story`:
```javascript
// Story.react.js
class Story extends React.Component { ... }
module.exports = Relay.createContainer(Story, {
queries: {
story: graphql`
Story {
export default Relay.createContainer(Story, {
fragments: {
story: () => Relay.QL`
fragment on Story {
author {
name,
profile_picture {
name
profilePicture {
uri
}
},
}
text
}
`
}
`,
},
});
```
Queries use ES6 template literals tagged with the `graphql` function. Similar to how JSX transpiles to plain JavaScript objects and function calls, these template literals transpile to plain objects that describe queries. Note that the query's structure closely matches the object structure that we expected in `<Story>`'s render function.
Queries use ES6 template literals tagged with the `Relay.QL` function. Similar to how JSX transpiles to plain JavaScript objects and function calls, these template literals transpile to plain objects that describe fragments. Note that the fragment's structure closely matches the object structure that we expected in `<Story>`'s render function.
<br/>
@@ -112,7 +110,7 @@ We can render a Relay component by providing Relay with the component (`<Story>`
{
author: {
name: "Greg",
profile_picture: {
profilePicture: {
uri: "https://…"
}
},
@@ -159,35 +157,35 @@ module.exports = NewsFeed;
`<NewsFeed>` has two new requirements: it composes `<Story>` and requests more data at runtime.
Just as React views can be nested, Relay queries can compose queries from child components. Composition in GraphQL uses ES6 template literal substitution: `${Component.getQuery('prop')}`. Pagination can be accomplished with a query parameter, specified with `<param>` (as in `stories(first: <count>)`):
Just as React views can be nested, Relay components can compose query fragments from child components. Composition in GraphQL uses ES6 template literal substitution: `${Component.getFragment('prop')}`. Pagination can be accomplished with a variable, specified with `$variable` (as in `stories(first: $count)`):
```javascript
// NewsFeed.react.js
class NewsFeed extends React.Component { ... }
module.exports = Relay.createContainer(NewsFeed, {
queryParams: {
count: 3 /* default to 3 stories */
export default Relay.createContainer(NewsFeed, {
initialVariables: {
count: 3 /* default to 3 stories */
},
queries: {
viewer: graphql`
Viewer {
stories(first: <count>) { /* fetch viewer's stories */
edges { /* traverse the graph */
fragments: {
viewer: () => Relay.QL`
fragment on Viewer {
stories(first: $count) { /* fetch viewer's stories */
edges { /* traverse the graph */
node {
${Story.getQuery('story')} /* compose child query */
${Story.getFragment('story')} /* compose child fragment */
}
}
}
}
`
}
`,
},
});
```
Whenever `<NewsFeed>` is rendered, Relay will recursively expand all the composed queries and fetch them in a single trip to the server. In this case, the `text` and `author` data will be fetched for each of the 3 story nodes.
Whenever `<NewsFeed>` is rendered, Relay will recursively expand all the composed fragments and fetch the queries in a single trip to the server. In this case, the `text` and `author` data will be fetched for each of the 3 story nodes.
Query parameters are available to components as `props.queryParams` and can be modified with `props.setQueryParams(nextParams)`. We can use these to implement pagination:
Query variables are available to components as `props.relay.variables` and can be modified with `props.relay.setVariables(nextVariables)`. We can use these to implement pagination:
```javascript
// NewsFeed.react.js
@@ -196,16 +194,16 @@ class NewsFeed extends React.Component {
loadMore() {
// read current params
var count = this.props.queryParams.count;
var count = this.props.relay.variables.count;
// update params
this.props.setQueryParams({
count: count + 5
this.props.relay.setVariables({
count: count + 5,
});
}
}
```
Now when `loadMore()` is called, Relay will send a GraphQL request for the additional five stories. When these stories are fetched, the component will re-render with the new stories available in `props.viewer.stories` and the updated count reflected in `props.queryParams.count`.
Now when `loadMore()` is called, Relay will send a GraphQL request for the additional five stories. When these stories are fetched, the component will re-render with the new stories available in `props.viewer.stories` and the updated count reflected in `props.relay.variables.count`.
<br/>

View File

@@ -0,0 +1,31 @@
---
title: "React v0.14.2"
author: zpao
---
We have a quick update following the release of 0.14.1 last week. It turns out we broke a couple things in the development build of React when using Internet Explorer. Luckily it was only the development build, so your production applications were unaffected. This release is mostly to address those issues. There is one notable change if consuming React from npm. For the `react-dom` package, we moved `react` from a regular dependency to a peer dependency. This will impact very few people as these two are typically installed together at the top level, but it will fix some issues with dependencies of installed components also using `react` as a peer dependency.
The release is now available for download:
* **React**
Dev build with warnings: <https://fb.me/react-0.14.2.js>
Minified build for production: <https://fb.me/react-0.14.2.min.js>
* **React with Add-Ons**
Dev build with warnings: <https://fb.me/react-with-addons-0.14.2.js>
Minified build for production: <https://fb.me/react-with-addons-0.14.2.min.js>
* **React DOM** (include React in the page before React DOM)
Dev build with warnings: <https://fb.me/react-dom-0.14.2.js>
Minified build for production: <https://fb.me/react-dom-0.14.2.min.js>
We've also published version `0.14.2` of the `react`, `react-dom`, and addons packages on npm and the `react` package on bower.
- - -
## Changelog
### React DOM
- Fixed bug with development build preventing events from firing in some versions of Internet Explorer & Edge
- Fixed bug with development build when using es5-sham in older versions of Internet Explorer
- Added support for `integrity` attribute
- Fixed bug resulting in `children` prop being coerced to a string for custom elements, which was not the desired behavior.
- Moved `react` from `dependencies` to `peerDependencies` to match expectations and align with `react-addons-*` packages

View File

@@ -0,0 +1,40 @@
---
title: "React v0.14.3"
author: zpao
---
It's time for another installment of React patch releases! We didn't break anything in v0.14.2 but we do have a couple of other bugs we're fixing. The biggest change in this release is actually an addition of a new built file. We heard from a number of people that they still need the ability to use React to render to a string on the client. While the use cases are not common and there are other ways to achieve this, we decided that it's still valuable to support. So we're now building `react-dom-server.js`, which will be shipped to Bower and in the `dist/` directory of the `react-dom` package on npm. This file works the same way as `react-dom.js` and therefore requires that the primary React build has already been included on the page.
The release is now available for download:
* **React**
Dev build with warnings: <https://fb.me/react-0.14.3.js>
Minified build for production: <https://fb.me/react-0.14.3.min.js>
* **React with Add-Ons**
Dev build with warnings: <https://fb.me/react-with-addons-0.14.3.js>
Minified build for production: <https://fb.me/react-with-addons-0.14.3.min.js>
* **React DOM** (include React in the page before React DOM)
Dev build with warnings: <https://fb.me/react-dom-0.14.3.js>
Minified build for production: <https://fb.me/react-dom-0.14.3.min.js>
* **React DOM Server** (include React in the page before React DOM Server)
Dev build with warnings: <https://fb.me/react-dom-server-0.14.3.js>
Minified build for production: <https://fb.me/react-dom-server-0.14.3.min.js>
We've also published version `0.14.3` of the `react`, `react-dom`, and addons packages on npm and the `react` package on bower.
- - -
## Changelog
### React DOM
- Added support for `nonce` attribute for `<script>` and `<style>` elements
- Added support for `reversed` attribute for `<ol>` elements
### React TestUtils Add-on
- Fixed bug with shallow rendering and function refs
### React CSSTransitionGroup Add-on
- Fixed bug resulting in timeouts firing incorrectly when mounting and unmounting rapidly
### React on Bower
- Added `react-dom-server.js` to expose `renderToString` and `renderToStaticMarkup` for usage in the browser

View File

@@ -0,0 +1,45 @@
---
title: React.js Conf 2016 Diversity Scholarship
author: zpao
---
I am thrilled to announced that we will be organizing another diversity scholarship program for the upcoming React.js Conf! The tech industry is suffering from a lack of diversity, but it's important to us that we have a thriving community that is made up of people with a variety of experiences and viewpoints.
When we ran this program last year, we had *over 200* people apply for only 10 tickets. There were so many people that we wanted to bring in but we couldn't. The results were still awesome, and we had bright individuals from around the world attending who would have otherwise been unable to. These attendees took part in discussions at the conference and brought perspectives that we might not have otherwise seen there.
This year we're excited to bring back the scholarship, but we've set aside **40 tickets** because we really believe that it's important to do our best to make sure we have an even more diverse audience.
This is something I'm personally really excited to be a part of. I know the rest of the team is as well. We're really proud to have everyone at Facebook providing support and funding for this.
The details of the scholarship are provided below (or you can [go directly to the application](http://goo.gl/forms/PEmKj8oUp4)). I encourage you to apply! If you don't feel like you are eligible yourself, you can still help send this along to friends, family, coworkers, acquaintances, or anybody who might be interested. And even if you haven't spoken before, please consider [submitting a proposal for a talk](http://conf.reactjs.com/) (either 30 minutes or just 5 minutes) - we're hoping to have a very diverse group of speakers in addition to attendees.
- - -
Facebook is excited to announce that we are now accepting applications for the React.js Conf Diversity Scholarship!
Beginning today, those studying or working in computer science or a related field can apply for a partial scholarship to attend the React.js Conf in San Francisco, CA on February 22 & 23, 2016.
React opens a world of new possibilities such as server-side rendering, real-time updates, different rendering targets like SVG and canvas. React Native makes is easy to use the same concepts and technologies to build native mobile experiences on iOS and Android. Join us at React.js Conf to shape the future of client-side applications! For more information about the React.js conference, please see [the website](http://conf.reactjs.com/).
At Facebook, we believe that anyone anywhere can make a positive impact by developing products to make the world more open and connected to the people and things they care about. Given the current realities of the tech industry and the lack of representation of communities we seek to serve, applicants currently under-represented in Computer Science and related fields are strongly encouraged to apply. Facebook will make determinations on scholarship recipients in its sole discretion. Facebook complies with all equal opportunity laws.
To apply for the scholarship, please visit the application page: **<http://goo.gl/forms/PEmKj8oUp4>**
## Award Includes
* Paid registration fee for the React.js Conf Feburary 22 & 23 in downtown San Francisco, CA
* Paid lodging expenses for February 21, 22, 23
## Important Dates
* Sunday December 13th 2015 - 11:59 PST: Applications for the React.js Conf Scholarship must be submitted in full
* Wednesday, December 16th, 2015: Award recipients will be notified by email of their acceptance
* Monday & Tuesday, February 22 & 23, 2016: React.js Conf
## Eligibility
* Must currently be studying or working in Computer Science or a related field
* International applicants are welcome, but you will be responsible for securing your own visa to attend the conference
* You must be able to provide your own transportation to San Francisco
* You must be available to attend the full duration of React.js Conf on February 22 & 23 in San Francisco, CA

View File

@@ -0,0 +1,77 @@
---
title: "isMounted is an Antipattern"
author: jimfb
---
As we move closer to officially deprecating isMounted, it's worth understanding why the function is an antipattern, and how to write code without the isMounted function.
The primary use case for `isMounted()` is to avoid calling `setState()` after a component has unmounted, because calling `setState()` after a component has unmounted will emit a warning. The “setState warning” exists to help you catch bugs, because calling `setState()` on an unmounted component is an indication that your app/component has somehow failed to clean up properly. Specifically, calling `setState()` in an unmounted component means that your app is still holding a reference to the component after the component has been unmounted - which often indicates a memory leak!
To avoid the error message, people often add lines like this:
```js
if(this.isMounted()) { // This is bad.
this.setState({...});
}
```
Checking `isMounted` before calling `setState()` does eliminate the warning, but it also defeats the purpose of the warning, since now you will never get the warning (even when you should!)
Other uses of `isMounted()` are similarly erroneous; using `isMounted()` is a code smell because the only reason you would check is because you think you might be holding a reference after the component has unmounted.
An easy migration strategy for anyone upgrading their code to avoid `isMounted()` is to track the mounted status yourself. Just set a `_isMounted` property to true in `componentDidMount` and set it to false in `componentWillUnmount`, and use this variable to check your component's status.
An optimal solution would be to find places where `setState()` might be called after a component has unmounted, and fix them. Such situations most commonly occur due to callbacks, when a component is waiting for some data and gets unmounted before the data arrives. Ideally, any callbacks should be canceled in `componentWillUnmount`, prior to unmounting.
For instance, if you are using a Flux store in your component, you must unsubscribe in `componentWillUnmount`:
```javascript{9}
class MyComponent extends React.Component {
componentDidMount() {
mydatastore.subscribe(this);
}
render() {
...
}
componentWillUnmount() {
mydatastore.unsubscribe(this);
}
}
```
If you use ES6 promises, you may need to wrap your promise in order to make it cancelable.
```js
const cancelablePromise = makeCancelable(
new Promise(r => component.setState({...}}))
);
cancelablePromise
.promise
.then(() => console.log('resolved'))
.catch((reason) => console.log('isCanceled', reason.isCanceled));
cancelablePromise.cancel(); // Cancel the promise
```
Where `makeCancelable` is [defined by @istarkov](https://github.com/facebook/react/issues/5465#issuecomment-157888325) as:
```js
const makeCancelable = (promise) => {
let hasCanceled_ = false;
return {
promise: new Promise(
(resolve, reject) => promise
.then(r => hasCanceled_
? reject({isCanceled: true})
: resolve(r)
)
),
cancel() {
hasCanceled_ = true;
},
};
};
```
As an added bonus for getting your code cleaned up early, getting rid of `isMounted()` makes it one step easier for you to upgrade to ES6 classes, where using `isMounted()` is already prohibited. Happy coding!

View File

@@ -0,0 +1,383 @@
---
title: "React Components, Elements, and Instances"
author: gaearon
---
The difference between **components, their instances, and elements** confuses many React beginners. Why are there three different terms to refer to something that is painted on screen?
## Managing the Instances
If youre new to React, you probably only worked with component classes and instances before. For example, you may declare a `Button` *component* by creating a class. When the app is running, you may have several *instances* of this component on screen, each with its own properties and local state. This is the traditional object-oriented UI programming. Why introduce *elements*?
In this traditional UI model, it is up to you to take care of creating and destroying child component instances. If a `Form` component wants to render a `Button` component, it needs to create its instance, and manually keep it up to date with any new information.
```js
class Form extends TraditionalObjectOrientedView {
render() {
// Read some data passed to the view
const { isSubmitted, buttonText } = this.attrs;
if (!isSubmitted && !this.button) {
// Form is not yet submitted. Create the button!
this.button = new Button({
children: buttonText,
color: 'blue'
});
this.el.appendChild(this.button.el);
}
if (this.button) {
// The button is visible. Update its text!
this.button.attrs.children = buttonText;
this.button.render();
}
if (isSubmitted && this.button) {
// Form was submitted. Destroy the button!
this.el.removeChild(this.button.el);
this.button.destroy();
}
if (isSubmitted && !this.message) {
// Form was submitted. Show the success message!
this.message = new Message({ text: 'Success!' });
this.el.appendChild(this.message.el);
}
}
}
```
This is pseudocode, but it is more or less what you end up with when you write composite UI code that behaves consistently in an object-oriented way using a library like Backbone.
Each component instance has to keep references to its DOM node and to the instances of the children components, and create, update, and destroy them when the time is right. The lines of code grow as the square of the number of possible states of the component, and the parents have direct access to their children component instances, making it hard to decouple them in the future.
So how is React different?
## Elements Describe the Tree
In React, this is where the *elements* come to rescue. **An element is a plain object *describing* a component instance or DOM node and its desired properties.** It contains only information about the component type (for example, a `Button`), its properties (for example, its `color`), and any child elements inside it.
An element is not an actual instance. Rather, it is a way to tell React what you *want* to see on the screen. You cant call any methods on the element. Its just an immutable description object with two fields: `type: (string | ReactClass)` and `props: Object`[^1].
### DOM Elements
When an elements `type` is a string, it represents a DOM node with that tag name, and `props` correspond to its attributes. This is what React will render. For example:
```js
{
type: 'button',
props: {
className: 'button button-blue',
children: {
type: 'b',
props: {
children: 'OK!'
}
}
}
}
```
This element is just a way to represent the following HTML as a plain object:
```html
<button class='button button-blue'>
<b>
OK!
</b>
</button>
```
Note how elements can be nested. By convention, when we want to create an element tree, we specify one or more child elements as the `children` prop of their containing element.
Whats important is that both child and parent elements are *just descriptions and not the actual instances*. They dont refer to anything on the screen when you create them. You can create them and throw them away, and it wont matter much.
React elements are easy to traverse, dont need to be parsed, and of course they are much lighter than the actual DOM elements—theyre just objects!
### Component Elements
However, the `type` of an element can also be a function or a class corresponding to a React component:
```js
{
type: Button,
props: {
color: 'blue',
children: 'OK!'
}
}
```
This is the core idea of React.
**An element describing a component is also an element, just like an element describing the DOM node. They can be nested and mixed with each other.**
This feature lets you define a `DangerButton` component as a `Button` with a specific `color` property value without worrying about whether `Button` renders to a DOM `<button>`, a `<div>`, or something else entirely:
```js
const DangerButton = ({ children }) => ({
type: Button,
props: {
color: 'red',
children: children
}
});
```
You can mix and match DOM and component elements in a single element tree:
```js
const DeleteAccount = () => ({
type: 'div',
props: {
children: [{
type: 'p',
props: {
children: 'Are you sure?'
}
}, {
type: DangerButton,
props: {
children: 'Yep'
}
}, {
type: Button,
props: {
color: 'blue',
children: 'Cancel'
}
}]
});
```
Or, if you prefer JSX:
```js
const DeleteAccount = () => (
<div>
<p>Are you sure?</p>
<DangerButton>Yep</DangerButton>
<Button color='blue'>Cancel</Button>
</div>
);
```
This mix and matching helps keep components decoupled from each other, as they can express both *is-a* and *has-a* relationships exclusively through composition:
* `Button` is a DOM `<button>` with specific properties.
* `DangerButton` is a `Button` with specific properties.
* `DeleteAccount` contains a `Button` and a `DangerButton` inside a `<div>`.
### Components Encapsulate Element Trees
When React sees an element with a function or class `type`, it knows to ask *that* component what element it renders to, given the corresponding `props`.
When it sees this element:
```js
{
type: Button,
props: {
color: 'blue',
children: 'OK!'
}
}
```
React will ask `Button` what it renders to. The `Button` will return this element:
```js
{
type: 'button',
props: {
className: 'button button-blue',
children: {
type: 'b',
props: {
children: 'OK!'
}
}
}
}
```
React will repeat this process until it knows the underlying DOM tag elements for every component on the page.
React is like a child asking “what is Y” for every “X is Y” you explain to them until they figure out every little thing in the world.
Remember the `Form` example above? It can be written in React as follows[^1]:
```js
const Form = ({ isSubmitted, buttonText }) => {
if (isSubmitted) {
// Form submitted! Return a message element.
return {
type: Message,
props: {
text: 'Success!'
}
};
}
// Form is still visible! Return a button element.
return {
type: Button,
props: {
children: buttonText,
color: 'blue'
}
};
};
```
Thats it! For a React component, props are the input, and an element tree is the output.
**The returned element tree can contain both elements describing DOM nodes, and elements describing other components. This lets you compose independent parts of UI without relying on their internal DOM structure.**
We let React create, update, and destroy instances. We *describe* them with elements we return from the components, and React takes care of managing the instances.
### Components Can Be Classes or Functions
In the code above, `Form`, `Message`, and `Button` are React components. They can either be written as functions, like above, or as classes descending from `React.Component`. These three ways to declare a component are mostly equivalent:
```js
// 1) As a function of props
const Button = ({ children, color }) => ({
type: 'button',
props: {
className: 'button button-' + color,
children: {
type: 'b',
props: {
children: children
}
}
}
});
// 2) Using the React.createClass() factory
const Button = React.createClass({
render() {
const { children, color } = this.props;
return {
type: 'button',
props: {
className: 'button button-' + color,
children: {
type: 'b',
props: {
children: children
}
}
}
};
}
});
// 3) As an ES6 class descending from React.Component
class Button extends React.Component {
render() {
const { children, color } = this.props;
return {
type: 'button',
props: {
className: 'button button-' + color,
children: {
type: 'b',
props: {
children: children
}
}
}
};
}
}
```
When a component is defined as a class, it is a little bit more powerful than a functional component. It can store some local state and perform custom logic when the corresponding DOM node is created or destroyed.
A functional component is less powerful but is simpler, and acts like a class component with just a single `render()` method. Unless you need features available only in a class, we encourage you to use functional components instead.
**However, whether functions or classes, fundamentally they are all components to React. They take the props as their input, and return the elements as their output.**
### Top-Down Reconciliation
When you call:
```js
ReactDOM.render({
type: Form,
props: {
isSubmitted: false,
buttonText: 'OK!'
}
}, document.getElementById('root'));
```
React will ask the `Form` component what element tree it returns, given those `props`. It will gradually “refine” its understanding of your component tree in terms of simpler primitives:
```js
// React: You told me this...
{
type: Form,
props: {
isSubmitted: false,
buttonText: 'OK!'
}
}
// React: ...And Form told me this...
{
type: Button,
props: {
children: 'OK!',
color: 'blue'
}
}
// React: ...and Button told me this! I guess I'm done.
{
type: 'button',
props: {
className: 'button button-blue',
children: {
type: 'b',
props: {
children: 'OK!'
}
}
}
}
```
This is a part of the process that React calls [reconciliation](/react/docs/reconciliation.html) which starts when you call [`ReactDOM.render()`](/react/docs/top-level-api.html#reactdom.render) or [`setState()`](/react/docs/component-api.html#setstate). By the end of the reconciliation, React knows the result DOM tree, and a renderer like `react-dom` or `react-native` applies the minimal set of changes necessary to update the DOM nodes (or the platform-specific views in case of React Native).
This gradual refining process is also the reason React apps are easy to optimize. If some parts of your component tree become too large for React to visit efficiently, you can tell it to [skip this “refining” and diffing certain parts of the tree if the relevant props have not changed](/react/docs/advanced-performance.html). It is very fast to calculate whether the props have changed if they are immutable, so React and immutability work great together, and can provide great optimizations with the minimal effort.
You might have noticed that this blog entry talks a lot about components and elements, and not so much about the instances. The truth is, instances have much less importance in React than in most object-oriented UI frameworks.
Only components declared as classes have instances, and you never create them directly: React does that for you. While [mechanisms for a parent component instance to access a child component instance](/react/docs/more-about-refs.html) exist, they are only used for imperative actions (such as setting focus on a field), and should generally be avoided.
React takes care of creating an instance for every class component, so you can write components in an object-oriented way with methods and local state, but other than that, instances are not very important in the Reacts programming model and are managed by React itself.
## Summary
An *element* is a plain object describing what you want to appear on the screen in terms of the DOM nodes or other components. Elements can contain other elements in their props. Creating a React element is cheap. Once an element is created, it is never mutated.
A *component* can be declared in several different ways. It can be a class with a `render()` method. Alternatively, in simple cases, it can be defined as a function. In either case, it takes props as an input, and returns an element tree as the output.
When a component receives some props as an input, it is because a particular parent component returned an element with its `type` and these props. This is why people say that the props flows one way in React: from parents to children.
An *instance* is what you refer to as `this` in the component class you write. It is useful for [storing local state and reacting to the lifecycle events](/react/docs/component-api.html).
Functional components dont have instances at all. Class components have instances, but you never need to create a component instance directly—React takes care of this.
Finally, to create elements, use [`React.createElement()`](/react/docs/top-level-api.html#react.createelement), [JSX](/react/docs/jsx-in-depth.html), or an [element factory helper](/react/docs/top-level-api.html#react.createfactory). Dont write elements as plain objects in the real code—just know that they are plain objects under the hood.
## Further Reading
* [Introducing React Elements](/react/blog/2014/10/14/introducing-react-elements.html)
* [Streamlining React Elements](/react/blog/2015/02/24/streamlining-react-elements.html)
* [React (Virtual) DOM Terminology](/react/docs/glossary.html)
[^1]: All React elements require an additional ``$$typeof: Symbol.for('react.element')`` field declared on the object for [security reasons](https://github.com/facebook/react/pull/4832). It is omitted in the examples above. This blog entry uses inline objects for elements to give you an idea of whats happening underneath but the code wont run as is unless you either add `$$typeof` to the elements, or change the code to use `React.createElement()` or JSX.

View File

@@ -0,0 +1,37 @@
---
title: "React v0.14.4"
author: spicyj
---
Happy December! We have a minor point release today. It has just a few small bug fixes.
The release is now available for download:
* **React**
Dev build with warnings: <https://fb.me/react-0.14.4.js>
Minified build for production: <https://fb.me/react-0.14.4.min.js>
* **React with Add-Ons**
Dev build with warnings: <https://fb.me/react-with-addons-0.14.4.js>
Minified build for production: <https://fb.me/react-with-addons-0.14.4.min.js>
* **React DOM** (include React in the page before React DOM)
Dev build with warnings: <https://fb.me/react-dom-0.14.4.js>
Minified build for production: <https://fb.me/react-dom-0.14.4.min.js>
* **React DOM Server** (include React in the page before React DOM Server)
Dev build with warnings: <https://fb.me/react-dom-server-0.14.4.js>
Minified build for production: <https://fb.me/react-dom-server-0.14.4.min.js>
We've also published version `0.14.4` of the `react`, `react-dom`, and addons packages on npm and the `react` package on bower.
- - -
## Changelog
### React
- Minor internal changes for better compatibility with React Native
### React DOM
- The `autoCapitalize` and `autoCorrect` props are now set as attributes in the DOM instead of properties to improve cross-browser compatibility
- Fixed bug with controlled `<select>` elements not handling updates properly
### React Perf Add-on
- Some DOM operation names have been updated for clarity in the output of `.printDOM()`

View File

@@ -19,6 +19,7 @@ UI를 가지고 할 수 있는 가장 기초적인 것은 데이터를 표시하
<meta charset="UTF-8" />
<title>Hello React</title>
<script src="https://fb.me/react-{{site.react_version}}.js"></script>
<script src="https://fb.me/react-dom-{{site.react_version}}.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script>
</head>
<body>
@@ -54,7 +55,6 @@ setInterval(function() {
}, 500);
```
## 반응 적(Reactive) 업데이트
`hello-react.html` 파일을 웹 브라우저에서 열어 당신의 이름을 텍스트 필드에 써 보세요. React는 단지 시간을 표시하는 부분만을 바꿉니다 — 텍스트 필드 안에 입력한 것은 그대로 남아 있구요, 당신이 이 동작을 관리하는 그 어떤 코드도 쓰지 않았음에도 불구하고 말이죠. React는 그걸 올바른 방법으로 알아서 해줍니다.
@@ -63,7 +63,6 @@ setInterval(function() {
이 컴포넌트에 대한 입력은 `props` 라고 불립니다 — "properties" 를 줄인 것이죠. 그들은 JSX 문법에서는 어트리뷰트로서 전달됩니다. 당신은 `props` 를 컴포넌트 안에서 불변의(immutable) 엘리먼트로서 생각해야 하고, `this.props` 를 덮어씌우려고 해서는 안됩니다.
## 컴포넌트들은 함수와 같습니다
React 컴포넌트들은 매우 단순합니다. 당신은 그것들을 `props``state` (이것들은 나중에 언급할 것입니다) 를 받고 HTML을 렌더링하는 단순한 함수들로 생각해도 됩니다. 이걸 염두하면, 컴포넌트의 작동을 이해하는 것도 쉽습니다.
@@ -72,7 +71,6 @@ React 컴포넌트들은 매우 단순합니다. 당신은 그것들을 `props`
>
> **한가지 제약이 있습니다**: React 컴포넌트들은 단 하나의 루트 노드(root node)만을 렌더할 수 있습니다. 만약 여러개의 노드들을 리턴하고 싶다면, 그것들은 단 하나의 루트 노드로 싸여져 있어야만 합니다.
## JSX 문법
우리는 컴포넌트를 사용하는 것이 "템플릿"과 "디스플레이 로직(display logic)"을 이용하는 것보다 관심을 분리(separate concerns)하는 데에 올바른 방법이라고 강하게 믿고 있습니다. 우리는 마크업과 그것을 만들어내는 코드는 친밀하게 함께 결합되어있다고 생각합니다. 또한, 디스플레이 로직은 종종 매우 복잡하고, 그것을 템플릿 언어를 이용해 표현하는 것은 점점 사용하기 어렵게 됩니다.
@@ -91,12 +89,11 @@ JSX를 이용하면:
우리는 이것이 React 앱들을 만들기 쉽게 하고, 디자이너들이 이 문법을 더 선호하는 것을 발견했습니다, 하지만 모든 사람은 그들만의 선호하는 워크플로우가 있기 마련이므로, **JSX는 React를 사용하기 위해 필수적이지는 않습니다.**
JSX는 매우 작은 언어입니다. 그것을 배우고 싶다면, [JSX 깊게 살펴보기](/react/docs/jsx-in-depth-ko-KR.html). 를 살펴 보시기 바랍니다. 또는, [우리의 온라인 JSX 컴파일러](/react/jsx-compiler.html)를 통해 문법이 변환되는 것을 살펴 보시기 바랍니다.
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를 사용하기 시작하기 위한 가장 쉬운 방법은 브라우저에서 작동하는 `JSXTransformer`를 사용하는 것입니다. 우리는 이것을 프로덕션에서는 사용하지 않기를 강하게 권장하는 바입니다. 당신은 우리의 커맨드 라인 [react-tools](https://www.npmjs.com/package/react-tools) 패키지를 이용하여 미리 컴파일(precompile)해 사용할 수 있습니다.
[바벨에서 JSX를 시작하는 여러 방법을 제공합니다](http://babeljs.io/docs/setup/). 여기에는 커맨드 라인 툴부터 루비 온 레일스 연동까지 다양한 방법이 있습니다. 가장 편한 툴을 사용하세요.
## JSX 없이 React 사용하기

View File

@@ -1,7 +1,6 @@
---
id: displaying-data-zh-CN
title: 显示数据
layout: docs
permalink: displaying-data-zh-CN.html
prev: why-react-zh-CN.html
next: jsx-in-depth-zh-CN.html
@@ -9,7 +8,6 @@ next: jsx-in-depth-zh-CN.html
用户界面能做的最基础的事就是显示一些数据。React 让显示数据变得简单,当数据变化的时候,用户界面会自动同步更新。
## 开始
让我们看一个非常简单的例子。新建一个名为 `hello-react.html` 的文件,代码内容如下:
@@ -57,7 +55,6 @@ setInterval(function() {
}, 500);
```
## 被动更新 (Reactive Updates)
在浏览器中打开 `hello-react.html` ,在输入框输入你的名字。你会发现 React 在用户界面中只改变了时间, 任何你在输入框输入的内容一直保留着即使你没有写任何代码来完成这个功能。React 为你解决了这个问题,做了正确的事。
@@ -66,7 +63,6 @@ setInterval(function() {
对这个组件的输入称为 `props` - "properties"的缩写。得益于 JSX 语法,它们通过参数传递。你必须知道在组件里,这些属性是不可改变的,也就是说 **`this.props` 是只读的**。
## 组件就像是函数
React 组件非常简单。你可以认为它们就是简单的函数,接受 `props``state` (后面会讨论) 作为参数,然后渲染出 HTML。正是应为它们是这么的简单这使得它们非常容易理解。
@@ -75,12 +71,13 @@ React 组件非常简单。你可以认为它们就是简单的函数,接受 `
>
> **只有一个限制**: React 组件只能渲染单个根节点。如果你想要返回多个节点,它们*必须*被包含在同一个节点里。
## JSX 语法
我们坚信组件是正确方法去做关注分离,而不是通过“模板”和“展示逻辑”。我们认为标签和生成它的代码是紧密相连的。此外,展示逻辑通常是很复杂的,通过模板语言实现这些逻辑会产生大量代码。
我们得出解决这个问题最好的方案是通过 JavaScript 直接生成模板,这样你就可以用一个真正语言的所有表达能力去构建用户界面。为了使这变得更简单,我们做了一个非常简单、**可选**类似 HTML 语法 ,通过函数调用即可生成模板的编译器,称为 JSX。
我们得出解决这个问题最好的方案是通过 JavaScript 直接生成模板,这样你就可以用一个真正语言的所有表达能力去构建用户界面。
为了使这变得更简单,我们做了一个非常简单、**可选**类似 HTML 语法 ,通过函数调用即可生成模板的编译器,称为 JSX。
**JSX 让你可以用 HTML 语法去写 JavaScript 函数调用** 为了在 React 生成一个链接,通过纯 JavaScript 你可以这么写:
@@ -125,4 +122,3 @@ var root = React.DOM.ul({ className: 'my-list' },
React.DOM.li(null, 'Text Content')
);
```

View File

@@ -83,7 +83,7 @@ var Nav = React.createClass({ });
var Nav = React.createClass({displayName: "Nav", });
```
[JSX 컴파일러](/react/jsx-compiler.html)를 보면 JSX에서 어떻게 네이티브 JavaScript로 변환(desugars)하는지 볼 수 있고, [HTML-JSX 변환기](/react/html-jsx.html)는 이미 있는 HTML을 JSX로 변환해 줍니다.
[바벨 REPL](https://babeljs.io/repl/)를 보면 JSX에서 어떻게 네이티브 JavaScript로 변환(desugars)하는지 볼 수 있고, [HTML-JSX 변환기](/react/html-jsx.html)는 이미 있는 HTML을 JSX로 변환해 줍니다.
JSX를 사용 하시려면, [시작하기](/react/docs/getting-started-ko-KR.html) 가이드에서 어떻게 컴파일을 하기 위해 설정하는지 보실 수 있습니다.

View File

@@ -22,7 +22,7 @@ It doesn't alter the semantics of JavaScript.
React can either render HTML tags (strings) or React components (classes).
To render a HTML tag, just use lower-case tag names in JSX:
To render an HTML tag, just use lower-case tag names in JSX:
```javascript
var myDivElement = <div className="foo" />;
@@ -82,10 +82,7 @@ var Nav = React.createClass({ });
var Nav = React.createClass({displayName: "Nav", });
```
Use the [Babel REPL](https://babeljs.io/repl/) to try out JSX and see how it
desugars into native JavaScript, and the
[HTML to JSX converter](/react/html-jsx.html) to convert your existing HTML to
JSX.
Use the [Babel REPL](https://babeljs.io/repl/) to try out JSX and see how it desugars into native JavaScript, and the [HTML to JSX converter](/react/html-jsx.html) to convert your existing HTML to JSX.
If you want to use JSX, the [Getting Started](/react/docs/getting-started.html) guide shows how to set up compilation.
@@ -163,8 +160,7 @@ var App = (
### Attribute Expressions
To use a JavaScript expression as an attribute value, wrap the expression in a
pair of curly braces (`{}`) instead of quotes (`""`).
To use a JavaScript expression as an attribute value, wrap the expression in a pair of curly braces (`{}`) instead of quotes (`""`).
```javascript
// Input (JSX):

View File

@@ -8,7 +8,6 @@ next: jsx-spread-zh-CN.html
[JSX](https://facebook.github.io/jsx/) 是一个看起来很像 XML 的 JavaScript 语法扩展。React 可以用来做简单的 JSX 句法转换。
## 为什么要用 JSX
你不需要为了 React 使用 JSX可以直接使用原生 JS。但是我们建议使用 JSX 是因为它能精确,也是常用的定义包含属性的树状结构的语法。
@@ -46,7 +45,6 @@ React 的 JSX 使用大、小写的约定来区分本地组件的类和 HTML 标
> 由于 JSX 就是 JavaScript一些标识符像 `class` 和 `for` 不建议作为 XML
> 属性名。作为替代React DOM 使用 `className` 和 `htmlFor` 来做对应的属性。
## 转换Transform
JSX 把类 XML 的语法转成原生 JavaScriptXML 元素、属性和子节点被转换成 `React.createElement` 的参数。
@@ -90,6 +88,7 @@ var Nav = React.createClass({displayName: "Nav", });
> 注意:
>
>
> JSX 表达式总是会当作 ReactElement 执行。具体的实际细节可能不同。一种优化
> 的模式是把 ReactElement 当作一个行内的对象字面量形式来绕过
> `React.createElement` 里的校验代码。

View File

@@ -12,7 +12,7 @@ next: jsx-gotchas-ko-KR.html
var component = <Component foo={x} bar={y} />;
```
## Props의 변경은 나빠요.[^1]
## Props의 변경은 나빠요
하지만 어떤 프로퍼티를 설정하고 싶은지 모른다면, 객체 레이어에 넣고 싶어질 수도 있습니다.
@@ -50,7 +50,3 @@ props는 변하지 않는 것으로 간주해야 합니다. props 객체를 변
## 이상한 `...` 표기법은 무엇인가요?
`...` 연산자(스프레드 연산자)는 이미 [ES6의 배열](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator)에서 지원합니다. [객체 rest와 스프레드 프로퍼티](https://github.com/sebmarkbage/ecmascript-rest-spread)에 대한 ES7의 제안도 있습니다. JSX의 구문을 더 깔끔하게 하기 위해 지원되고 개발중인 표준을 활용하고 있습니다.
[^1]: 아무래도 좋지만, 이 제목의 원문 "Mutating Props is Bad, mkay"는 사우스 파크에
나온 대사 "[Drug is bad, mkay](https://www.youtube-nocookie.com/watch?v=Uh7l8dx-h8M)"의
패러디입니다.

View File

@@ -49,4 +49,4 @@ You can use this multiple times or combine it with other attributes. The specifi
## What's with the weird `...` notation?
The `...` operator (or spread operator) is already supported for [arrays in ES6](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator). There is also an ES7 proposal for [Object Rest and Spread Properties](https://github.com/sebmarkbage/ecmascript-rest-spread). We're taking advantage of these supported and developing standards in order to provide a cleaner syntax in JSX.
The `...` operator (or spread operator) is already supported for [arrays in ES6](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator). There is also an ECMAScript proposal for [Object Rest and Spread Properties](https://github.com/sebmarkbage/ecmascript-rest-spread). We're taking advantage of these supported and developing standards in order to provide a cleaner syntax in JSX.

View File

@@ -12,7 +12,6 @@ next: jsx-gotchas-zh-CN.html
var component = <Component foo={x} bar={y} />;
```
## 修改 Props 是不好的,明白吗
如果你不知道要设置哪些 Props那么现在最好不要设置它
@@ -27,7 +26,6 @@ next: jsx-gotchas-zh-CN.html
Props 应该被认为是不可变的。在别处修改 props 对象可能会导致预料之外的结果,所以原则上这将是一个冻结的对象。
## 展开属性Spread Attributes
现在你可以使用 JSX 的新特性 - 展开属性:
@@ -49,7 +47,6 @@ Props 应该被认为是不可变的。在别处修改 props 对象可能会导
console.log(component.props.foo); // 'override'
```
## 这个奇怪的 `...` 标记是什么?
这个 `...` 操作符(增强的操作符)已经被 [ES6 数组](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator) 支持。相关的还有 ES7 规范草案中的 [Object 剩余和展开属性Rest and Spread Properties](https://github.com/sebmarkbage/ecmascript-rest-spread)。我们利用了这些还在制定中标准中已经被支持的特性来使 JSX 拥有更优雅的语法。
这个 `...` 操作符(增强的操作符)已经被 [ES6 数组](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator) 支持。相关的还有 ECMAScript 规范草案中的 [Object 剩余和展开属性Rest and Spread Properties](https://github.com/sebmarkbage/ecmascript-rest-spread)。我们利用了这些还在制定中标准中已经被支持的特性来使 JSX 拥有更优雅的语法。

View File

@@ -61,6 +61,12 @@ If you pass properties to native HTML elements that do not exist in the HTML spe
<div data-custom-attribute="foo" />
```
However, arbitrary attributes are supported on custom elements (those with a hyphen in the tag name or an `is="..."` attribute).
```javascript
<x-my-component custom-attribute="foo" />
```
[Web Accessibility](http://www.w3.org/WAI/intro/aria) attributes starting with `aria-` will be rendered properly.
```javascript

View File

@@ -52,6 +52,7 @@ HTML 实体可以插入到 JSX 的文本中。
<div dangerouslySetInnerHTML={{'{{'}}__html: 'First &middot; Second'}} />
```
## 自定义 HTML 属性
如果往原生 HTML 元素里传入 HTML 规范里不存在的属性React 不会显示它们。如果需要使用自定义属性,要加 `data-` 前缀。
@@ -60,6 +61,12 @@ HTML 实体可以插入到 JSX 的文本中。
<div data-custom-attribute="foo" />
```
然而,在自定义元素中任意的属性都是被支持的 那些在tag名里带有连接符或者 `is="..."` 属性的)
```javascript
<x-my-component custom-attribute="foo" />
```
`aria-` 开头的 [网络无障碍](http://www.w3.org/WAI/intro/aria) 属性可以正常使用。
```javascript

View File

@@ -8,7 +8,6 @@ next: multiple-components-ko-KR.html
이미 React에서 [어떻게 데이터를 표시](/react/docs/displaying-data-ko-KR.html)하는지를 배웠습니다. 이제 UI와의 상호작용을 어떻게 만드는지 살펴보죠.
## 간단한 예제
```javascript
@@ -35,34 +34,29 @@ ReactDOM.render(
);
```
## 이벤트 핸들링과 통합적인(Synthetic) 이벤트
React에서의 이벤트 핸들러는 HTML에서 그러던 것처럼 간단히 카멜케이스 프로퍼티(camelCased prop)로 넘기면 됩니다. React의 모든 이벤트는 통합적인 이벤트 시스템의 구현으로 IE8 이상에서는 같은 행동이 보장됩니다. 즉, React는 사양에 따라 어떻게 이벤트를 일으키고(bubble) 잡는지 알고 있고, 당신이 사용하는 브라우저와 관계없이 이벤트 핸들러에 전달되는 이벤트는 [W3C 사양](http://www.w3.org/TR/DOM-Level-3-Events/)과 같도록 보장됩니다.
## 기본 구현: 오토바인딩과 이벤트 델리게이션
<a name="under-the-hood-autobinding-and-event-delegation"></a>
코드를 고성능으로 유지하고 이해하기 쉽게 하기 위해, React는 보이지 않는 곳에서 몇 가지 일을 수행합니다.
**오토바인딩:** JavaScript에서 콜백을 만들 때, 보통은 `this`의 값이 정확하도록 명시적으로 메소드를 인스턴스에 바인드해야 합니다. React에서는 모든 메소드가 자동으로 React의 컴포넌트 인스턴스에 바인드됩니다. React가 바인드 메소드를 캐시하기 때문에 매우 CPU와 메모리에 효율적입니다. 타이핑해야 할 것도 줄어들죠!
**오토바인딩:** JavaScript에서 콜백을 만들 때, 보통은 `this`의 값이 정확하도록 명시적으로 메소드를 인스턴스에 바인드해야 합니다. React에서는 모든 메소드가 자동으로 React의 컴포넌트 인스턴스에 바인드됩니다.(ES6 클래스 문법을 사용할 때는 재외하고) React가 바인드 메소드를 캐시하기 때문에 매우 CPU와 메모리에 효율적입니다. 타이핑해야 할 것도 줄어들죠!
**이벤트 델리게이션:** React는 실제로는 노드자신에게 이벤트 핸들러를 붙이지 않습니다. React가 시작되면 React는 탑 레벨의 단일 이벤트 리스너로 모든 이벤트를 리스닝하기 시작합니다. 컴포넌트가 마운트되거나 언마운트 될 때, 이벤트 핸들러는 그냥 내부 매핑에서 넣거나 뺄 뿐입니다. 이벤트가 발생하면, React는 이 매핑을 사용해서 어떻게 디스패치할 지를 알게 됩니다. 매핑에 이벤트 핸들러가 남아있지 않으면, React의 이벤트 핸들러는 그냥 아무것도 하지 않습니다. 왜 이 방식이 빠른지 더 알고 싶으시면, [David Walsh의 멋진 블로그 글](http://davidwalsh.name/event-delegate)을 읽어 보세요.
## 컴포넌트는 그냥 state 머신일 뿐
React는 UI를 간단한 state 머신이라 생각합니다. UI를 다양한 state와 그 state의 렌더링으로 생각함으로써 UI를 일관성 있게 관리하기 쉬워집니다.
React에서는, 간단히 컴포넌트의 state를 업데이트하고, 이 새로운 state의 UI를 렌더링합니다. React는 DOM의 변경을 가장 효율적인 방법으로 관리해줍니다.
## state의 동작 원리
React에게 데이터의 변경을 알리는 일반적인 방법은 `setState(data, callback)`을 호출하는 것입니다. 이 메소드는 `this.state``data`를 머지하고 컴포넌트를 다시 렌더링 합니다. 컴포넌트의 재-렌더링이 끝나면, 생략가능한 `callback`이 호출됩니다. 대부분의 경우 React가 UI를 최신상태로 유지해주기 때문에 `callback`을 사용할 필요가 없습니다.
## 어떤 컴포넌트가 state를 가져야 할까요?
대부분의 컴포넌트는 `props`로부터 데이터를 받아 렌더할 뿐입니다만, 가끔 유저 인풋, 서버 요청, 시간의 경과에 반응해야 할 필요가 있습니다. 이럴 때 state를 사용합니다.
@@ -71,7 +65,6 @@ React에게 데이터의 변경을 알리는 일반적인 방법은 `setState(da
일반적인 패턴은 데이터만 렌더하는 여러 상태를 가지지 않은 컴포넌트를 만들고, 그 위에 상태기반(stateful) 컴포넌트를 만들어 계층 안의 자식 컴포넌트에게 `props`를 통해 state를 전달하는 것입니다. state를 가지지 않은 컴포넌트가 선언적인 방법으로 데이터를 렌더링 하는 동안, 상태기반 컴포넌트는 모든 상호작용 로직을 캡슐화합니다.
## state를 어떻게 *써야* 할까요?
**state는 컴포넌트의 이벤트 핸들러에 의해 UI 업데이트를 트리거할때 변경될 가능성이 있어, 그때 사용할 데이터를 가져야 합니다.** 실제 앱에서는 이 데이터는 매우 작고 JSON 직렬화 가능한 경향이 있습니다. 상태기반 컴포넌트를 만들때, 가능한 작게 state를 서술하고 `this.state`에만 저장하도록 해보세요. 그냥 `render()` 안에서 이 state를 기반으로 다른 모든 정보를 계산합니다. 이 방식으로 애플리케이션을 작성하고 생각하면 가장 최적의 애플리케이션으로 발전해가는 경향이 있다는 것을 발견하게 될 것입니다. 꼭 필요하지 않은 값이나 계산된 값을 state에 추가하는 것은 render가 그것을 계산하는 대신에 명시적으로 그것들을 맞춰줘야 하는 것을 의미하기 때문이죠.
@@ -82,4 +75,4 @@ React에게 데이터의 변경을 알리는 일반적인 방법은 `setState(da
* **계산된 데이터:** state에 따라 값을 미리 계산하는 것에 대해 염려하지 마세요. 계산은 모두 `render()`에서 하는 것이 UI의 일관성을 유지하기 쉽습니다. 예를 들어, state에서 list items 배열을 가지고 있고 문자열으로 카운트를 렌더링 할 경우, state에 저장하기보다는 그냥 `render()` 메소드안에서 `this.state.listItems.length + ' list items'`를 렌더하세요.
* **React 컴포넌트:** 가지고 있는 props와 state로 `render()`안에서 만드세요.
* **props에서 복사한 데이터:** 가능한 한 원래의 소스로 props를 사용하도록 해보세요. props를 state에 저장하는 단 하나의 올바른 사용법은 이전 값을 알고 싶을 때입니다. props는 시간이 지나면 변경될 수도 있기 때문이죠.
* **props에서 복사한 데이터:** 가능한 한 원래의 소스로 props를 사용하도록 해보세요. props를 state에 저장하는 단 하나의 올바른 사용법은 이전 값을 알고 싶을 때입니다. props는 부모 컴포넌트의 재 렌더링의 결과 변경될 수도 있기 때문이죠.

View File

@@ -8,7 +8,6 @@ next: multiple-components-zh-CN.html
我们已经学习如何使用 React [显示数据](/react/docs/displaying-data-zh-CN.html)。现在让我们来学习如何创建交互式界面。
## 简单例子
```javascript
@@ -35,7 +34,6 @@ ReactDOM.render(
);
```
## 事件处理与合成事件Synthetic Events
React 里只需把事件处理器event handler以骆峰命名camelCased形式当作组件的 props 传入即可,就像使用普通 HTML 那样。React 内部创建一套合成事件系统来使所有事件在 IE8 和以上浏览器表现一致。也就是说React 知道如何冒泡和捕获事件,而且你的事件处理器接收到的 events 参数与 [W3C 规范](http://www.w3.org/TR/DOM-Level-3-Events/) 一致,无论你使用哪种浏览器。
@@ -48,19 +46,16 @@ React 里只需把事件处理器event handler以骆峰命名camelCased
**事件代理 ** React 实际并没有把事件处理器绑定到节点本身。当 React 启动的时候它在最外层使用唯一一个事件监听器处理所有事件。当组件被加载和卸载时只是在内部映射里添加或删除事件处理器。当事件触发React 根据映射来决定如何分发。当映射里处理器时,会当作空操作处理。参考 [David Walsh 很棒的文章](http://davidwalsh.name/event-delegate) 了解这样做高效的原因。
## 组件其实是状态机State Machines
React 把用户界面当作简单状态机。把用户界面想像成拥有不同状态然后渲染这些状态,可以轻松让用户界面和数据保持一致。
React 里,只需更新组件的 state然后根据新的 state 重新渲染用户界面(不要操作 DOM。React 来决定如何最高效地更新 DOM。
## State 工作原理
常用的通知 React 数据变化的方法是调用 `setState(data, callback)`。这个方法会合并merge `data``this.state`,并重新渲染组件。渲染完成后,调用可选的 `callback` 回调。大部分情况下不需要提供 `callback`,因为 React 会负责把界面更新到最新状态。
## 哪些组件应该有 State
大部分组件的工作应该是从 `props` 里取数据并渲染出来。但是,有时需要对用户输入、服务器请求或者时间变化等作出响应,这时才需要使用 State。
@@ -69,16 +64,14 @@ React 里,只需更新组件的 state然后根据新的 state 重新渲染
常用的模式是创建多个只负责渲染数据的无状态stateless组件在它们的上层创建一个有状态stateful组件并把它的状态通过 `props` 传给子级。这个有状态的组件封装了所有用户的交互逻辑,而这些无状态组件则负责声明式地渲染数据。
## 哪些 *应该* 作为 State
**State 应该包括那些可能被组件的事件处理器改变并触发用户界面更新的数据。** 真实的应用中这种数据一般都很小且能被 JSON 序列化。当创建一个状态化的组件时,想象一下表示它的状态最少需要哪些数据,并只把这些数据存入 `this.state`。在 `render()` 里再根据 state 来计算你需要的其它数据。你会发现以这种方式思考和开发程序最终往往是正确的,因为如果在 state 里添加冗余数据或计算所得数据,需要你经常手动保持数据同步,不能让 React 来帮你处理。
## 哪些 *不应该* 作为 State
`this.state` 应该仅包括能表示用户界面状态所需的最少数据。因些,它不应该包括:
* **计算所得数据:** 不要担心根据 state 来预先计算数据 —— 把所有的计算都放到 `render()` 里更容易保证用户界面和数据的一致性。例如,在 state 里有一个数组listItems我们要把数组长度渲染成字符串 直接在 `render()` 里使用 `this.state.listItems.length + ' list items'` 比把它放到 state 里好的多。
* **React 组件:** 在 `render()` 里使用当前 props 和 state 来创建它。
* **基于 props 的重复数据:** 尽可能使用 props 来作为惟一数据来源。把 props 保存到 state 的一个有效的场景是需要知道它以前值的时候,因为未来的 props 可能变化。
* **基于 props 的重复数据:** 尽可能使用 props 来作为实际状态的源。把 props 保存到 state 的一个有效的场景是需要知道它以前值的时候,因为 props 可能因为父组件重绘的结果而变化。

View File

@@ -8,12 +8,10 @@ next: reusable-components-ko-KR.html
지금까지, 단일 컴포넌트에서 데이터를 표시하고 유저 입력을 다루는 것을 살펴보았습니다. 다음엔 React의 최고의 기능 중 하나인 조합가능성(composability)을 살펴봅시다.
## 동기: 관심의 분리
명확히 정의된 인터페이스와 다른 컴포넌트를 재사용해 모듈러 컴포넌트를 구축하면, 함수와 클래스를 이용했을 때 얻을 수 있는 이점 대부분을 얻을 수 있습니다. 특히 앱에서 *다른 관심을 분리*할 수 있습니다.아무리 간단히 새 컴포넌트를 만들었다고 해도 말이죠. 당신의 애플리케이션에서 쓸 커스텀 컴포넌트 라이브러리를 만들어서, 당신의 도메인에 최적화된 방법으로 UI를 표현할 수 있게 됩니다.
## 조합(Composition) 예제
간단히 페이스북 그래프 API를 사용해 프로필 사진과 유저이름을 보여주는 아바타 컴포넌트를 만든다고 합시다.
@@ -54,14 +52,12 @@ ReactDOM.render(
);
```
## 소유권(Ownership)
위의 예제에서, `Avatar` 인스턴스는 `ProfilePic``ProfileLink`인스턴스를 *가지고* 있습니다. React에서 **소유자는 다른 컴포넌트의 `props`를 설정하는 컴포넌트입니다**. 더 정식으로 말하면, `X` 컴포넌트가 `Y` 컴포넌트의 `render()` 메소드 안에서 만들어졌다면, `Y``X`*소유하고* 있다고 합니다. 앞에서 설명한 바와 같이, 컴포넌트는 자신의 `props`를 변경할 수 없습니다. `props`는 언제나 소유자가 설정한 것과 일치합니다. 이와 같은 중요한 성질은 UI가 일관성 있도록 해줍니다.
위의 예제에서, `Avatar` 인스턴스는 `ProfilePic``ProfileLink`인스턴스를 *가지고* 있습니다. React에서 **소유자는 다른 컴포넌트의 `props`를 설정하는 컴포넌트입니다**. 더 정식으로 말하면, `X` 컴포넌트가 `Y` 컴포넌트의 `render()` 메소드 안에서 만들어졌다면, `Y``X`*소유하고* 있다고 합니다. 앞에서 설명한 바와 같이, 컴포넌트는 자신의 `props`를 변경할 수 없습니다. `props`는 언제나 소유자가 설정한 것과 일치합니다. 이와 같은 근본적인 불변성은 UI가 일관성 있도록 해줍니다.
소유(owner-ownee)관계와 부모·자식 관계를 구별하는 것은 중요합니다. 부모·자식 관계가 DOM에서부터 쓰던 익숙하고 이미 알고있던 단순한 것인 한편, 소유관계는 React 고유의 것입니다. 위의 예제에서, `Avatar``div`, `ProfilePic`, `ProfileLink`인스턴스를 소유하고, `div``ProfilePic``ProfileLink`인스턴스의 (소유자가 아닌) **부모**입니다.
## 자식
React 컴포넌트 인스턴스를 만들 때, 추가적인 React 컴포넌트나 JavaScript 표현식을 시작과 끝 태그 사이에 넣을 수 있습니다. 이렇게 말이죠.
@@ -72,7 +68,6 @@ React 컴포넌트 인스턴스를 만들 때, 추가적인 React 컴포넌트
`Parent``this.props.children`라는 특수 prop으로 자식들을 읽을 수 있습니다. **`this.props.children` 는 불투명한 데이터 구조이며,** [React.Children 유틸리티](/react/docs/top-level-api-ko-KR.html#react.children)를 사용해 자식들을 관리합니다.
### 자식 Reconciliation (비교조정)
**Reconciliation은 React가 DOM을 각각 새로운 렌더 패스에 업데이트하는 과정입니다.** 일반적으로, 자식은 렌더하는 순서에 따라 비교조정됩니다. 예를 들어, 각각의 마크업을 생성하는 두 개의 렌더 패스가 있다고 해봅시다.
@@ -91,7 +86,6 @@ React 컴포넌트 인스턴스를 만들 때, 추가적인 React 컴포넌트
직관적으로 보면, `<p>Paragraph 1</p>`가 없어졌습니다만 그러는 대신에, React는 첫 번째 자식의 텍스트를 비교조정하고 마지막 자식을 파괴하도록 DOM을 비교조정할 것입니다. React는 자식들의 *순서*에 따라 비교조정합니다.
### 상태기반(Stateful) 자식
대부분의 컴포넌트에서는, 이것은 큰 문제가 아닙니다. 하지만 렌더 패스 간에 `this.state`를 유지하는 상태기반의 컴포넌트에서는 매우 문제가 될 수 있습니다.
@@ -111,7 +105,6 @@ React 컴포넌트 인스턴스를 만들 때, 추가적인 React 컴포넌트
</Card>
```
<a name="dynamic-children"></a>
### 동적 자식
@@ -179,7 +172,6 @@ ReactFragment 객체를 넘기는 것으로 자식에 키를 할당할 수도
React에서 데이터는 위에서 말한 것처럼 `props`를 통해 소유자로부터 소유한 컴포넌트로 흐릅니다. 이것은 사실상 단방향 데이터 바인딩입니다. 소유자는 `props``state`를 기준으로 계산한 어떤 값으로 소유한 컴포넌트의 props를 바인드합니다. 이 과정은 재귀적으로 발생하므로, 데이터의 변경은 자동으로 모든 곳에 반영됩니다.
## 성능의 주의점
소유자가 가지고 있는 노드의 수가 많아지면 데이터가 변화하는 비용이 증가할 것으로 생각할 수도 있습니다. 좋은 소식은 JavaScript의 속도는 빠르고 `render()` 메소드는 꽤 간단한 경향이 있어, 대부분 애플리케이션에서 매우 빠르다는 점입니다. 덧붙여, 대부분의 병목 현상은 JS 실행이 아닌 DOM 변경에서 일어나고, React는 배치와 탐지 변경을 이용해 최적화해 줍니다.

View File

@@ -8,7 +8,6 @@ next: reusable-components-zh-CN.html
目前为止,我们已经学了如何用单个组件来展示数据和处理用户输入。下一步让我们来体验 React 最激动人心的特性之一可组合性composability
## 动机:关注分离
通过复用那些接口定义良好的组件来开发新的模块化组件,我们得到了与使用函数和类相似的好处。具体来说就是能够通过开发简单的组件把程序的*不同关注面分离*。如果为程序开发一套自定义的组件库,那么就能以最适合业务场景的方式来展示你的用户界面。
@@ -53,15 +52,12 @@ ReactDOM.render(
);
```
## 从属关系
上面例子中,`Avatar` 拥有 `ProfilePic``ProfileLink` 的实例。`拥有者` 就是给其它组件设置 `props` 的那个组件。更正式地说,
如果组件 `Y``render()` 方法是创建了组件 `X`,那么 `Y` 就拥有 `X`。上面讲过,组件不能修改自身的 `props` - 它们总是与它们拥有者设置的保持一致。这是保持用户界面一致性的基本不变量。
上面例子中,`Avatar` 拥有 `ProfilePic``ProfileLink` 的实例。`拥有者` 就是给其它组件设置 `props` 的那个组件。更正式地说,如果组件 `Y``render()` 方法是创建了组件 `X`,那么 `Y` 就拥有 `X`。上面讲过,组件不能修改自身的 `props` - 它们总是与它们拥有者设置的保持一致。这是保持用户界面一致性的基本不变量。
把从属关系与父子关系加以区别至关重要。从属关系是 React 特有的而父子关系简单来讲就是DOM 里的标签的关系。在上一个例子中,`Avatar` 拥有 `div``ProfilePic``ProfileLink` 实例,`div``ProfilePic``ProfileLink` 实例的**父级**(但不是拥有者)。
## 子级
实例化 React 组件时你可以在开始标签和结束标签之间引用在React 组件或者Javascript 表达式:

View File

@@ -8,7 +8,6 @@ next: transferring-props-ko-KR.html
인터페이스를 설계할 때, 공통적으로 사용되는 디자인 요소들(버튼, 폼 필드, 레이아웃 컴포넌트 등.)을 잘 정의된 인터페이스의 재사용 가능한 컴포넌트로 분해합니다. 이런 방법으로 다음에 UI를 구축할 때에는 훨씬 적은 코드로 만들 수 있습니다. 이 말은 더 빠른 개발 시간, 더 적은 버그, 더 적은 용량으로 할 수 있다는 뜻이죠.
## Prop 검증
앱의 규모가 커지면 컴포넌트들이 바르게 사용되었는지 확인하는게 도움이 됩니다. 확인은 `propTypes`를 명시해서 할 수 있습니다. `React.PropTypes`는 받은 데이터가 적절한지(valid) 확인하는데 사용할 수 있는 다양한 검증자(validator)를 제공합니다. prop에 부적절한 값을 명시한다면 JavaScript 콘솔에 경고가 보일 것입니다. 성능상의 문제로 `propTypes`는 개발 모드에서만 검사됩니다. 다음은 제공되는 검증자를 설명하는 예제입니다.
@@ -78,7 +77,6 @@ React.createClass({
});
```
## 기본 Prop 값
React는 매우 선언적(declarative)인 방법으로 `props`의 기본값을 정의할 수 있게 해줍니다.
@@ -230,3 +228,30 @@ Counter.defaultProps = { initialCount: 0 };
### 믹스인 안됨
불행하게도 ES6는 믹스인에 대한 지원이 없이 출시되었기 때문에, React에서 ES6 클래스를 사용한다면 믹스인을 사용할 방법이 없습니다. 대신, 우리는 믹스인에 의존하지 않고도 동작하도록 만들기 위해 열심히 노력하고 있습니다.
<a name="stateless-functions"></a>
## 상태를 가지지 않는 함수
React 클래스를 일반 JavaScript 함수로 작성할 수도 있습니다. 상태를 가지지 않는 함수 문법을 사용하는 예제입니다.
```javascript
function HelloMessage(props) {
return <div>Hello {props.name}</div>;
}
ReactDOM.render(<HelloMessage name="Sebastian" />, mountNode);
```
아니면 ES6의 화살표 문법을 사용할 수 있습니다.
```javascript
var HelloMessage = (props) => <div>Hello {props.name}</div>;
ReactDOM.render(<HelloMessage name="Sebastian" />, mountNode);
```
이 단순화된 컴포넌트 API는 prop의 순수 함수인 컴포넌트를 나타냅니다. 이 컴포넌트는 내부 상태가 없어야 하고, 내부 인스턴스가 없어야 하고, 컴포넌트 생명주기 메소드가 없어야 합니다. 아무런 준비 과정없이 입력에 대한 순수한 기능적 변환이어야 합니다.
> 주의:
>
> 상태를 가지지 않는 함수는 내부 인스턴스가 없기 때문에, ref를 상태를 가지지않는 함수에 넣을 수 없습니다. 상태를 가지지 않는 함수는 명령형(imperative) API를 제공하지 않기 때문에 일반적으로 이것은 문제가 되지 않습니다. 명령형 API없이 인스턴스에 할 수 있는 것이 많지 않기도 하죠. 하지만 상태를 가지지 않는 컴포넌트의 DOM 노드를 검색하길 원한다면, 반드시 상태 기반 컴포넌트(예. ES6 클래스 컴포넌트)로 컴포넌트를 감싸고 상태 기반 래퍼 컴포넌트에 ref를 붙여야 합니다.
이상적으로는, 대부분의 컴포넌트는 상태를 가지지 않는 함수여야 합니다. 왜냐 하면 이런 상태를 가지지 않는 컴포넌트는 React 코어 안에서 더 빠른 코드 경로를 거치기 때문입니다. 이는 가능한 한 추천하는 패턴입니다.

View File

@@ -78,6 +78,27 @@ React.createClass({
});
```
### Single Child
With `React.PropTypes.element` you can specify that only a single child can be passed to a component as children.
```javascript
var MyComponent = React.createClass({
propTypes: {
children: React.PropTypes.element.isRequired
},
render: function() {
return (
<div>
{this.props.children} // This must be exactly one element or it will warn.
</div>
);
}
});
```
## Default Prop Values
React lets you define default values for your `props` in a very declarative way:
@@ -115,28 +136,6 @@ ReactDOM.render(
);
```
## Single Child
With `React.PropTypes.element` you can specify that only a single child can be passed to
a component as children.
```javascript
var MyComponent = React.createClass({
propTypes: {
children: React.PropTypes.element.isRequired
},
render: function() {
return (
<div>
{this.props.children} // This must be exactly one element or it will throw.
</div>
);
}
});
```
## Mixins
Components are the best way to reuse code in React, but sometimes very different components may share some common functionality. These are sometimes called [cross-cutting concerns](https://en.wikipedia.org/wiki/Cross-cutting_concern). React provides `mixins` to solve this problem.
@@ -249,6 +248,7 @@ ReactDOM.render(<HelloMessage name="Sebastian" />, mountNode);
```
This simplified component API is intended for components that are pure functions of their props. These components must not retain internal state, do not have backing instances, and do not have the component lifecycle methods. They are pure functional transforms of their input, with zero boilerplate.
However, you may still specify `.propTypes` and `.defaultProps` by setting them as properties on the function, just as you would set them on an ES6 class.
> NOTE:
>

View File

@@ -8,7 +8,6 @@ next: transferring-props-zh-CN.html
设计接口的时候,把通用的设计元素(按钮,表单框,布局组件等)拆成接口良好定义的可复用的组件。这样,下次开发相同界面程序时就可以写更少的代码,也意义着更高的开发效率,更少的 Bug 和更少的程序体积。
## Prop 验证
随着应用不断变大,保证组件被正确使用变得非常有用。为此我们引入 `propTypes``React.PropTypes` 提供很多验证器 (validator) 来验证传入数据的有效性。当向 props 传入无效数据时JavaScript 控制台会抛出警告。注意为了性能考虑,只在开发环境验证 `propTypes`。下面用例子来说明不同验证器的区别:
@@ -32,10 +31,12 @@ React.createClass({
// React 元素
optionalElement: React.PropTypes.element,
// 你同样可以断言一个 prop 是一个类的实例。
// 用 JS 的 instanceof 操作符声明 prop 为类的实例。
optionalMessage: React.PropTypes.instanceOf(Message),
// 用 enum 来限制 prop 只接受指定的值。
// 你可以用 enum 的方式
// 确保你的 prop 被限定为指定值。
optionalEnum: React.PropTypes.oneOf(['News', 'Photos']),
// 指定的多个对象类型中的一个
@@ -57,14 +58,16 @@ React.createClass({
fontSize: React.PropTypes.number
}),
// 以后任意类型加上 `isRequired` 来使 prop 不可空。
// 你可以在任意东西后面加上 `isRequired`
// 来确保 如果 prop 没有提供 就会显示一个警告。
requiredFunc: React.PropTypes.func.isRequired,
// 不可空的任意类型
requiredAny: React.PropTypes.any.isRequired,
// 自定义验证器。如果验证失败需要返回一个 Error 对象。不要直接
// 使用 `console.warn` 或抛异常,因为这样 `oneOfType` 会失效。
// 你可以自定义一个验证器。如果验证失败需要返回一个 Error 对象。
// 不要直接使用 `console.warn` 或抛异常,
// 因为这在 `oneOfType` 里不起作用。
customProp: function(props, propName, componentName) {
if (!/matchme/.test(props[propName])) {
return new Error('Validation failed!');
@@ -75,6 +78,26 @@ React.createClass({
});
```
### Single Child
`React.PropTypes.element` 你可以指定仅有一个子级能被传送给组件
```javascript
var MyComponent = React.createClass({
propTypes: {
children: React.PropTypes.element.isRequired
},
render: function() {
return (
<div>
{this.props.children} // 这里必须是一个元素否则就会警告
</div>
);
}
});
```
## 默认 Prop 值
@@ -93,9 +116,9 @@ var ComponentWithDefaultProps = React.createClass({
当父级没有传入 props 时,`getDefaultProps()` 可以保证 `this.props.value` 有默认值,注意 `getDefaultProps` 的结果会被 *缓存*。得益于此,你可以直接使用 props而不必写手动编写一些重复或无意义的代码。
## 传递 Props小技巧
## 传递 Props捷径
有一些常用的 React 组件只是对 HTML 做简单扩展。通常,你想少写点代码来把传入组件的 props 复制到对应的 HTML 元素上。这时 JSX _spread_ 语法会帮到你
有一些常用的 React 组件只是对 HTML 做简单扩展。通常,你想 复制任何传进你的组件的HTML属性 到底层的HTML元素上。为了减少输入,你可以用 JSX _spread_ 语法来完成
```javascript
var CheckLink = React.createClass({
@@ -113,28 +136,6 @@ ReactDOM.render(
);
```
## 单个子级
`React.PropTypes.element` 可以限定只能有一个子级传入。
```javascript
var MyComponent = React.createClass({
propTypes: {
children: React.PropTypes.element.isRequired
},
render: function() {
return (
<div>
{this.props.children} // 有且仅有一个元素,否则会抛异常。
</div>
);
}
});
```
## Mixins
组件是 React 里复用代码最佳方式,但是有时一些复杂的组件间也需要共用一些功能。有时会被称为 [跨切面关注点](https://en.wikipedia.org/wiki/Cross-cutting_concern)。React 使用 `mixins` 来解决这类问题。
@@ -228,3 +229,29 @@ Counter.defaultProps = { initialCount: 0 };
不幸的是ES6的发布没有任何mixin的支持。因此当你在ES6 classes下使用React时不支持mixins。作为替代我们正在努力使它更容易支持这些用例不依靠mixins。
## 无状态函数
你也可以用 JavaScript 函数来定义你的 React 类。例如使用无状态函数语法:
```javascript
function HelloMessage(props) {
return <div>Hello {props.name}</div>;
}
ReactDOM.render(<HelloMessage name="Sebastian" />, mountNode);
```
或者使用新的ES6箭头函数:
```javascript
var HelloMessage = (props) => <div>Hello {props.name}</div>;
ReactDOM.render(<HelloMessage name="Sebastian" />, mountNode);
```
这个简化的组件API旨在用于那些纯函数态的组件 。这些组件必须没有保持任何内部状态,没有备份实例,也没有组件生命周期方法。他们纯粹的函数式的转化他们的输入,没有引用。
然而你仍然可以以设置为函数的properties的方式来指定 `.propTypes``.defaultProps`就像你在ES6类里设置他们那样。
> 注意:
>
> 因为无状态函数没有备份实例,你不能附加一个引用到一个无状态函数组件。 通常这不是问题因为无状态函数不提供一个命令式的API。没有命令式的API你就没有任何需要实例来做的事。然而如果用户想查找无状态函数组件的DOM节点他们必须把这个组件包装在一个有状态组件里比如ES6 类组件) 并且连接一个引用到有状态的包装组件。
在理想世界里你的大多数组件都应该是无状态函数式的因为这些无状态组件可以在React核心里经过一个快速的代码路径。 如果可能,这是推荐的模式。

View File

@@ -51,7 +51,8 @@ ReactDOM.render(
> 주의:
>
> 아래의 예제에서는 실험적인 ES7 문법이 사용되었기 때문에 `--harmony ` 플래그가 필요합니다. 브라우저에서 JSX 변환기를 사용 중이라면, `<script type="text/jsx;harmony=true">`를 사용해 스크립트를 작성하세요. 자세히 알아보려면 아래의 [잔여 프로퍼티와 스프레드 프로퍼티 ...](/react/docs/transferring-props-ko-KR.html#rest-and-spread-properties-...)를 확인하세요.
> `...` 구문은 객체 잔여 스프레드 제안의 일부입니다. 이 제안은 표준화 과정에 있습니다. 더 자세한 내용은 밑의 [잔여 프로퍼티와 스프레드 프로퍼티 ...](/react/docs/transferring-props.html#rest-and-spread-properties-...) 부분을 참고하세요.
때로는 모든 프로퍼티를 일일이 전달 하는것은 지루하고 덧없는 작업입니다. 이 경우 [구조 해체 할당(destructuring assignment)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment)을 다른 프로퍼티를 함께 사용해 미상의 프로퍼티를 추출할 수 있습니다.
@@ -133,7 +134,7 @@ var FancyCheckbox = React.createClass({
잔여(Rest, `...`) 프로퍼티는 객체에서 소비되지 않은 나머지 프로퍼티를 추출해 새로운 객체로 만들 수 있게 해 줍니다. 구조 해체 패턴에서 열거된 다른 프로퍼티들은 모두 제외됩니다.
는 [ES7 제안](https://github.com/sebmarkbage/ecmascript-rest-spread)의 실험적인 구현체입니다.
제안은 2 단계에 돌입해 이제 바벨에서 기본값으로 활성화되어있습니다. 바벨의 이전 버전은 `babel --optional es7.objectRestSpread`로 명시적으로 활성화 할 필요가 있을 수도 있습니다.
```javascript
var { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };

View File

@@ -20,7 +20,7 @@ If you don't use JSX, you can use any object helper such as ES6 `Object.assign`
React.createElement(Component, Object.assign({}, this.props, { more: 'values' }));
```
The rest of this tutorial explains best practices. It uses JSX and experimental ES7 syntax.
The rest of this tutorial explains best practices. It uses JSX and experimental ECMAScript syntax.
## Manual Transfer
@@ -132,7 +132,7 @@ var FancyCheckbox = React.createClass({
Rest properties allow you to extract the remaining properties from an object into a new object. It excludes every other property listed in the destructuring pattern.
This is an experimental implementation of an [ES7 proposal](https://github.com/sebmarkbage/ecmascript-rest-spread).
This is an experimental implementation of an [ECMAScript proposal](https://github.com/sebmarkbage/ecmascript-rest-spread).
```javascript
var { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
@@ -143,7 +143,7 @@ z; // { a: 3, b: 4 }
> Note:
>
> This proposal has reached stage 2 and is now enabled by default in Babel. Older versions of Babel may need to explicitly enable this transform with `babel --optional es7.objectRestSpread`
> To transform rest and spread properties using Babel 6, you need to install the [`es2015`](https://babeljs.io/docs/plugins/preset-es2015/) preset, the [`transform-object-rest-spread`](https://babeljs.io/docs/plugins/transform-object-rest-spread/) plugin and configure them in the `.babelrc` file.
## Transferring with Underscore

View File

@@ -20,7 +20,7 @@ React 里有一个非常常用的模式就是对组件做一层抽象。组件
React.createElement(Component, Object.assign({}, this.props, { more: 'values' }));
```
下面的教程介绍一些最佳实践。使用了 JSX 和 ES7 的还在试验阶段的特性
下面的教程介绍一些最佳实践。使用了 JSX 和 试验性的ECMAScript 语法
## 手动传递
@@ -100,7 +100,6 @@ var FancyCheckbox = React.createClass({
});
```
## 使用和传递同一个 Prop
如果组件需要使用一个属性又要往下传递,可以直接使用 `checked={checked}` 再传一次。这样做比传整个 `this.props` 对象要好,因为更利于重构和语法检查。
@@ -129,12 +128,11 @@ var FancyCheckbox = React.createClass({
>
> 顺序很重要,把 `{...other}` 放到 JSX props 前面会使它不被覆盖。上面例子中我们可以保证 input 的 type 是 `"checkbox"`。
## 剩余属性和展开属性 `...`
剩余属性可以把对象剩下的属性提取到一个新的对象。会把所有在解构赋值中列出的属性剔除。
这是 [ES7 草案](https://github.com/sebmarkbage/ecmascript-rest-spread) 中的试验特性。
这是 [ECMAScript 草案](https://github.com/sebmarkbage/ecmascript-rest-spread) 中的试验特性。
```javascript
var { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
@@ -145,8 +143,7 @@ z; // { a: 3, b: 4 }
> 注意:
>
> 使[JSX 命令行工具](https://www.npmjs.com/package/react-tools) 配合 `--harmony` 标记来启用 ES7 语法。
> Babel 6转换 rest 和 spread 属性,你需要安装 [`es2015`](https://babeljs.io/docs/plugins/preset-es2015/) preset[`transform-object-rest-spread`](https://babeljs.io/docs/plugins/transform-object-rest-spread/) 插件并在 `.babelrc` 里配置他们.
## 使用 Underscore 来传递

View File

@@ -68,6 +68,9 @@ HTML에서는 `<textarea>` 태그의 값을 설정할 때 `<textarea>` 태그의
이것은 사용자 입력을 받아들이지만, 시작에서부터 140자로 값을 자릅니다.
### 체크박스와 라디오 버튼의 잠제적인 문제
변경 핸들링을 일반화하기 위해 React는 `change` 이벤트 대신에 `click` 이벤트를 사용하는 것에 주의하세요. `change` 핸들러 안에서 `preventDefault`를 호출하는 경우를 재외하고 이 동작은 예상대로 동작합니다. 이런 경우 `preventDefault`를 제거하거나, `setTimeout``checked`의 전환을 넣어서 해결 가능합니다.
## 제어되지 않는(Uncontrolled) 컴포넌트
@@ -91,7 +94,7 @@ HTML에서는 `<textarea>` 태그의 값을 설정할 때 `<textarea>` 태그의
}
```
이 예제는 위에있는 **제어되는 컴포넌트**에 더 가깝게 동작할 것입니다.
이 예제는 위에있는 **제어되지 않는 컴포넌트**에 더 가깝게 동작할 것입니다.
마찬가지로, `<input>``defaultChecked`를 지원하고 `<select>``defaultValue`를 지원합니다.
@@ -99,10 +102,8 @@ HTML에서는 `<textarea>` 태그의 값을 설정할 때 `<textarea>` 태그의
>
> `defaultValue`, `defaultChecked` prop은 최초 렌더에서만 사용됩니다. 뒤에 일어나는 렌더에서 값을 업데이트할 필요가 있다면, [제어되는(controlled) 컴포넌트](#controlled-components)를 사용하셔야 합니다.
## 심화 주제
### 왜 제어되는 컴포넌트인가요?
React에서 `<input>`같은 폼 컴포넌트를 사용하면, 전통적인 폼 HTML을 쓸 때에는 없던 어려운 문제가 있습니다. 예를 들어 HTML에서
@@ -123,7 +124,6 @@ HTML과 다르게, React 컴포넌트는 초기화 시점 뿐만 아니라, 어
이 메소드가 어떤 시점에도 뷰를 기술하기 때문에, 텍스트 input의 값은 *언제나* `Untitled`입니다.
### 왜 Textarea에 value를 사용하나요?
HTML에서, `<textarea>`의 값은 보통 그것의 자식들로 설정됩니다.
@@ -141,7 +141,6 @@ HTML에서는 이렇게 하면 여러 줄의 값을 쉽게 개발자가 넣을
자식들을 사용하기로 *했다면*, 자식들은 `defaultValue`처럼 동작할 것입니다.
### 왜 Select에 value를 사용하나요?
HTML `<select>`에서 선택된 `<option>`은 보통 option의 `selected` 어트리뷰트로 기술됩니다. React에서는 컴포넌트를 관리하기 쉽게 하기 위해, 다음 형식이 대신 채용됐습니다.

View File

@@ -32,7 +32,6 @@ next: working-with-the-browser-zh-CN.html
>
> 对于 `<input>` and `<textarea>` `onChange` 替代 — 一般应该用来替代 — the DOM's 内建的 [`oninput`](https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/oninput) 事件处理。
## 受限组件
设置了 `value``<input>` 是一个*受限*组件。 对于受限的 `<input>`,渲染出来的 HTML 元素始终保持 `value` 属性的值。例如:
@@ -72,7 +71,6 @@ next: working-with-the-browser-zh-CN.html
当心在力图标准化复选框与单选按钮的变换处理中React使用`click` 事件代替 `change` 事件。在大多数情况下它们表现的如同预期,除了在`change` handler中调用`preventDefault``preventDefault` 阻止了浏览器视觉上更新输入,即使`checked`被触发。变通的方式是要么移除`preventDefault`的调用,要么把`checked` 的触发放在一个`setTimeout`里。
## 不受限组件
没有设置 `value`(或者设为 `null`) 的 `<input>` 组件是一个*不受限*组件。对于不受限的 `<input>` 组件,渲染出来的元素直接反应用户输入。例如:
@@ -95,7 +93,7 @@ next: working-with-the-browser-zh-CN.html
}
```
这个例子会像上面的**Controlled Components** 例子一样运行。
这个例子会像上面的 **不受限组件** 例子一样运行。
同样的, `<input>` 支持 `defaultChecked``<select>` 支持 `defaultValue`.
@@ -103,10 +101,8 @@ next: working-with-the-browser-zh-CN.html
>
> `defaultValue` 和 `defaultChecked` props 只能在内部渲染时被使用。 如果你需要在随后的渲染更新值, 你需要使用 [受限组件](#受限组件).
## 高级主题
### 为什么使用受限组件?
在 React 中使用诸如 `<input>` 的表单组件时,遇到了一个在传统 HTML 中没有的挑战。比如下面的代码:
@@ -127,7 +123,6 @@ next: working-with-the-browser-zh-CN.html
该方法在任何时间点渲染组件以后,输入框的值就应该 *始终*`Untitled`
### 为什么 `<textarea>` 使用 `value` 属性?
在 HTML 中, `<textarea>` 的值通常使用子节点设置:
@@ -145,7 +140,6 @@ next: working-with-the-browser-zh-CN.html
如果 *非要* 使用子节点,效果和使用 `defaultValue` 一样。
### 为什么 `<select>` 使用 `value` 属性
HTML 中 `<select>` 通常使用 `<option>``selected` 属性设置选中状态React 为了更方面的控制组件,采用以下方式代替:

View File

@@ -11,7 +11,7 @@ React는 대부분의 경우 직접 DOM을 다루지 않아도 될만큼 강력
## 가상의 DOM
React는 DOM을 직접 다루지 않기 때문에 굉장히 빠릅니다. React는 메모리에(in-memory) DOM의 표상(representation)을 관리합니다. `render()` 메소드는 DOM의 *서술*를 반환하고, React는 이를 메모리에 있는 DOM의 표상과 비교(diff)해 가장 빠른 방식으로 계산해서 브라우저를 업데이트해 줍니다.
React는 DOM을 직접 다루지 않기 때문에 매우 빠릅니다. React는 메모리에(in-memory) DOM의 표상(representation)을 관리합니다. `render()` 메소드는 사실은 DOM의 *서술*를 반환하고, React는 이를 메모리에 있는 DOM의 표상과 비교해 가장 빠른 방식으로 계산해서 브라우저를 업데이트해 줍니다.
게다가 React는 브라우저의 괴악함(quirks)에도 불구하고 모든 이벤트 객체가 W3C 명세를 보장하도록 통합적인 이벤트 시스템을 구현했습니다. 모든 것이 일관된 방식으로 일어나고(bubbles) 효율적으로 크로스 브라우징을 수행합니다. 심지어 IE8에서도 HTML5 이벤트를 사용할 수 있습니다!
@@ -20,45 +20,7 @@ React는 DOM을 직접 다루지 않기 때문에 굉장히 빠릅니다. React
## Refs와 findDOMNode()
브라우저와 상호 작용하려면 DOM 노드에 대한 참조가 필요합니다. React는 `ReactDOM.findDOMNode(component)` 함수를 갖고 있으며, 이를 통해서 컴포넌트의 DOM 노드의 참조를 얻을 수 있습니다.
> 주의:
>
> `findDOMNode()`는 마운트 된 컴포넌트에서만 동작합니다 (DOM에 배치된 컴포넌트를 말합니다). 아직 마운트 되지 않은 컴포넌트에서 이를 호출하려고 하면 (컴포넌트가 아직 생성되기 이전인 `render()` 시점에 `findDOMNode()`를 호출한다든가) 예외가 발생합니다.
React 컴포넌트에 대한 참조는 현재의 React 컴포넌트를 위해 `this`를, 소유한 컴포넌트의 참조를 얻기 위해 refs를 사용해 얻을 수 있습니다. 다음과 같이 동작합니다:
```javascript
var MyComponent = React.createClass({
handleClick: function() {
// raw DOM API를 사용해 명시적으로 텍스트 인풋을 포커스 합니다.
ReactDOM.findDOMNode(this.refs.myTextInput).focus();
},
render: function() {
// ref 어트리뷰트는 컴포넌트가 마운트되면 그에 대한 참조를 this.refs에 추가합니다.
return (
<div>
<input type="text" ref="myTextInput" />
<input
type="button"
value="Focus the text input"
onClick={this.handleClick}
/>
</div>
);
}
});
ReactDOM.render(
<MyComponent />,
document.getElementById('example')
);
```
## Refs 심화
[refs 심화](/react/docs/more-about-refs-ko-KR.html) 문서에서 refs를 효율적으로 사용하는 법을 포함해 더 많은 내용을 익혀보세요.
브라우저와 상호 작용하려면 DOM 노드에 대한 참조가 필요합니다. `ref`를 어떤 엘리먼트에도 붙일 수 있으며, 이를 통해 컴포넌트 **지원 인스턴스**를 참조 할 수 있습니다. 이는 컴포넌트에 필수 적인 기능을 호출할 때나 기저의 DOM 노드에 접근하고 싶을 때 유용합니다. [refs에서 컴포넌트로](/react/docs/more-about-refs-ko-KR.html) 문서에서 refs를 효율적으로 사용하는 법을 포함해 더 많은 내용을 익혀보세요.
<a name="component-lifecycle"></a>
@@ -72,14 +34,12 @@ ReactDOM.render(
React는 이 프로세스에 훅을 지정할 수 있는 생명주기 메소드를 제공합니다. 발생 직전 시점을 위한 **will** 메소드, 발생 직후 시점을 위한 **did** 메소드가 있습니다.
### Mounting
* `getInitialState(): object`는 컴포넌트가 마운트되기 전에 호출됩니다. 상태기반 컴포넌트는 이를 구현하고 초기 상태 데이터를 리턴합니다.
* `componentWillMount()`는 마운팅되기 직전에 호출됩니다.
* `componentDidMount()`는 마운팅 직후 호출됩니다. 초기화에 필요한 DOM 노드는 이곳에 있어야 합니다.
### Updating
* `componentWillReceiveProps(object nextProps)`는 마운트된 컴포넌트가 새로운 props을 받을 때 호출됩니다. 이 메소드는 `this.props``nextProps`을 비교하여 `this.setState()`를 사용해 상태 변환을 수행하는데 사용되야 합니다.
@@ -87,19 +47,15 @@ React는 이 프로세스에 훅을 지정할 수 있는 생명주기 메소드
* `componentWillUpdate(object nextProps, object nextState)`는 업데이트가 발생하기 직전에 호출됩니다. 이 시점에는 `this.setState()`를 호출할 수 없습니다.
* `componentDidUpdate(object prevProps, object prevState)`는 업데이트가 발생한 후 즉시 호출됩니다.
### Unmounting
* `componentWillUnmount()`는 컴포넌트가 언마운트되어 파괴되기 직전에 호출됩니다. 정리(Cleanup)는 여기서 처리해야 합니다.
### Mounted 메소드
_마운트된_ 합성 컴포넌트들은 다음과 같은 메소드를 지원합니다:
* `findDOMNode(): DOMElement`는 렌더링 된 DOM 노드에 대한 참조를 얻기 위해 모든 마운트된 컴포넌트에서 호출할 수 있습니다.
* `forceUpdate()``this.setState`를 사용하지 않고 컴포넌트 state의 더 깊은 측면(deeper aspect)의 변경된 것을 알고 있을 때 모든 마운트된 컴포넌트에서 호출할 수 있습니다.
* `component.forceUpdate()``this.setState()`를 사용하지 않고 변경된 컴포넌트의 상태의 변경을 적용하고 싶을 때 마운트된 컴포넌트에서 사용할 수 있습니다.
## 브라우저 지원과 Polyfill
@@ -107,7 +63,6 @@ _마운트된_ 합성 컴포넌트들은 다음과 같은 메소드를 지원합
그 철학에 더하여, 우리는 또한 JS 라이브러리의 저자로서 polyfill을 라이브러리에 포함해서 배포하지 않습니다. 만약 모든 라이브러리가 이런 짓을 하면, 같은 polyfill을 여러 번 내리게 되어 쓸모없이 크기만 차지하는 죽은 코드들을 만들 것 입니다. 당신의 제품이 구식 브라우저를 지원해야한다면, [es5-shim](https://github.com/es-shims/es5-shim) 같은 녀석을 사용할 기회가 있었을 겁니다.
### Polyfill은 구식 브라우저를 지원하기 위해 필요하다
[kriskowal's es5-shim](https://github.com/es-shims/es5-shim)의 `es5-shim.js`는 React에 필요한 다음의 기능을 제공합니다:
@@ -134,12 +89,10 @@ _마운트된_ 합성 컴포넌트들은 다음과 같은 메소드를 지원합
`<section>`, `<article>`, `<nav>`, `<header>`, `<footer>`등 HTML5 엘리먼트를 IE8에서 이용하려면 [html5shiv](https://github.com/aFarkas/html5shiv)같은 스크립트가 추가로 필요합니다.
### 크로스 브라우징 이슈
React가 브라우저별 차이점을 썩 잘 추상화하긴 했지만 일부는 한정적이거나 우리가 발견하지 못한 이상한(quirky) 동작을 보여주기도 합니다.
#### IE8에서의 onScroll 이벤트
IE8에서는 `onScroll` 이벤트가 일어나지(bubble) 않으며, IE8은 이벤트의 캡쳐링 단계를 위한 핸들러를 정의하는 API를 갖고 있지 않습니다. 이는 React가 이 이벤트를 이해(listen) 할 방법이 없음을 뜻합니다. 현재 이 이벤트 핸들러는 IE8에서 무시됩니다.

View File

@@ -8,59 +8,17 @@ next: more-about-refs-zh-CN.html
React提供了强大的抽象机制使你在大多数情况下免于直接接触DOM但有时你仅仅只需要访问底层API也许是为了与第三方库或者已有的代码协作。
## 虚拟DOM
React如此快速是因为它从不直接操作DOM。React维持了一个快速的内存中的DOM表示。`render()` 方法返回一个DOM的*描述*然后React能根据内存中的描述diff此描述来计算出最快速的方法更新浏览器。
React非常快速是因为它从不直接操作DOM。React维持了一个快速的内存中的DOM表示。`render()` 方法实际上返回一个DOM的*描述*然后React能根据内存中的描述”来比较此“描述”以计算出最快速的方法更新浏览器。
此外React实现了一个完备的合成事件(synthetic event)系统以使得所有的事件对象都被保证符合W3C细则而不论各个浏览器的怪癖并且所有事件跨浏览器地一致并高效的冒泡bubbles你甚至能在IE8里使用一些HTML5事件
大多数时间你应该和React的"伪造浏览器"呆在一起因为它更高性能并且容易推理。然而有时你只需要访问底层API或许是为了与第三方库比如一个jQuery插件协作。React为你提供了安全仓口来直接使用底层API。
## Refs 和 findDOMNode()
为了与浏览器互动你需要一个指向DOM node的引用。React有一个函数`ReactDOM.findDOMNode(component)` 你能调用以得到一个指向指向组件的DOM node的引用
> 注意:
>
> `findDOMNode()` 只作用于已挂载的组件已经放置于DOM中的组件。如果你尝试在还没有被挂载的组件上调用此函数比如在`render()` 里有待被创建的组件上调用`findDOMNode()`将会抛出一个异常)
为了获得一个指向React组件的引用你可以要么使用`this` 来得到当前React组件要么使用refs来引用你拥有的组件。它们像这样工作
```javascript
var MyComponent = React.createClass({
handleClick: function() {
// 明确的强制text input使用原生DOM API。
ReactDOM.findDOMNode(this.refs.myTextInput).focus();
},
render: function() {
// 当组件被挂载时
// ref属性给this.refs添加了一个指向指向组件的引用
return (
<div>
<input type="text" ref="myTextInput" />
<input
type="button"
value="Focus the text input"
onClick={this.handleClick}
/>
</div>
);
}
});
ReactDOM.render(
<MyComponent />,
document.getElementById('example')
);
```
## 更多关于Refs
要学习更多有关refs包括更有效使用它们的方法请参见[more about refs](/react/docs/more-about-refs.html) 文档。
为了与浏览器互动你需要一个指向DOM node的引用。你可以连接一个 `ref` 到任何的元素,这允许你引用 组件的 **backing instance** 。它很有用如果你需要在组件上调用命令式函数或者想访问底层的DOM节点。要了解很多关于 refs包括更有效使用他们的方法请查看我们的 [关于Refs的更多内容](/react/docs/more-about-refs-zh-CN.html) 文档
## 组件的生命周期
@@ -72,14 +30,12 @@ ReactDOM.render(
React提供生命周期方法以便你可以指定钩挂到这个过程上。我们提供了 **will** 方法,该方法在某事发生前被调用,**did**方法,在某事发生后被调用。
### 挂载
* `getInitialState(): object` 在组件挂载前被调用. 有状态组件(Stateful components) 应该实现此函数并返回初始state的数据。
* `componentWillMount()` 在挂载发生前被立即调用。
* `componentDidMount()` 在挂载发生后被立即调用。 需要DOM node的初始化应该放在这里。
### 更新
* `componentWillReceiveProps(object nextProps)` 当挂载的组件接收到新的props时被调用。此方法应该被用于比较`this.props``nextProps`以用于使用`this.setState()`执行状态转换。
@@ -87,19 +43,15 @@ React提供生命周期方法以便你可以指定钩挂到这个过程上。
* `componentWillUpdate(object nextProps, object nextState)` 在更新发生前被立即调用。你不能在此调用`this.setState()`
* `componentDidUpdate(object prevProps, object prevState)` 在更新发生后被立即调用。
### 卸载
* `componentWillUnmount()` 在组件被卸载和摧毁后被立即调用。清理应该放在这里。
### Mounted Methods
### 已挂载的方法
_Mounted_ 复合组件同样支持以下方法:
* `findDOMNode(): DOMElement` 能够在任何已挂载的组件上调用以便于获取指向它渲染的DOM node的引用
* `forceUpdate()` 能在任何已挂载的组件上调用,当你知道一些更深层次的组件状态变化了但没有使用 `this.setState()`
* `component.forceUpdate()` 可以在任何已挂载的组件上调用,在你知道 某些深处的组件状态被未使用 `this.setState()` 改变了时
## 浏览器支持和填充物(polyfills)
@@ -107,7 +59,6 @@ _Mounted_ 复合组件同样支持以下方法:
除了这种哲学外我们也采用了这样的立场我们作为一个JS库的作者不应该把polyfills作为我们库的一部分。如果所有的库这样做就有很大的机会发送同样的polyfill多次这可能是一个相当大的无用代码。如果你的产品需要支援老的浏览器你很有可能已经在使用某些东西比如[es5-shim](https://github.com/es-shims/es5-shim)。
### 需要用来支持旧浏览器的Polyfills
来自 [kriskowal's es5-shim](https://github.com/es-shims/es5-shim)的`es5-shim.js` 提供了如下React需要的东西
@@ -134,12 +85,10 @@ _Mounted_ 复合组件同样支持以下方法:
当在IE8里使用HTML5元素包括`<section>`, `<article>`, `<nav>`, `<header>`, 和 `<footer>`, 同样必须包含[html5shiv](https://github.com/aFarkas/html5shiv) 或者类似的脚本。
### 跨浏览器问题
尽管React在抽象浏览器不同时做的相当好但一些浏览器被限制或者表现出怪异的行为我们没能找到变通的方案解决。
#### IE8的onScroll事件
在IE8`onScroll` 事件不冒泡并且IE8没有定义事件捕获阶段handlers的API意味React这没有办法去监听这些事件。

View File

@@ -1,174 +0,0 @@
---
id: more-about-refs
title: Refs 的更多信息
permalink: more-about-refs-zh-CN.html
prev: working-with-the-browser-zh-CN.html
next: tooling-integration-zh-CN.html
---
在从render方法返回你的UI结构之前你可能想向从`render()` 返回的组件的实例“伸手”并调用其上的方法。通常做类似这样的事情没必要在你的引用中制造数据流因为Reactive的数据量确保最近的`props` 被发送到从 `render()` 返回的每个孩子中。然而,有些情况,这样做还是必须的或者有帮助的。
考虑一下情形,元素`<input />` (他存在于你的子层级中),当你更新它的值为一个空的字符串`''` 的时候,你告诉它获得焦点。
```javascript
var App = React.createClass({
getInitialState: function() {
return {userInput: ''};
},
handleChange: function(e) {
this.setState({userInput: e.target.value});
},
clearAndFocusInput: function() {
this.setState({userInput: ''}); //清空输入
// 现在我们希望获取焦点<input />!
},
render: function() {
return (
<div>
<div onClick={this.clearAndFocusInput}>
Click to Focus and Reset
</div>
<input
value={this.state.userInput}
onChange={this.handleChange}
/>
</div>
);
}
});
```
在这个例子中,注意我们是如何想要“告诉” input 一些事情的- 一些不能从它的props得到的东西。在这种情形下我们想要“告诉”它它现在也要改获取焦点了。然而这里有些挑战。从`render()` 中返回的不是你实际组件的“孩子”组件,相反他是这些孩子在特定的时刻的一个*描述* - 一个快照。
> 注意:
>
>记着,从`render()` 中返回的不是你的*实际*渲染地孩子实例。从`render()` 中返回的仅仅是在你的组件的子层次结构中的这些孩子实例一个特定时刻的*描述*。
这意味着你绝不该“拿”从`render()` 中返回的东西去做什么事情并期望有什么意义。
```javascript
// 反模式:不能工作.
render: function() {
var myInput = <input />; // 我打算在这个上调用这个方法
this.rememberThisInput = myInput; // input在未来的某个时间点上YAY!
return (
<div>
<div>...</div>
{myInput}
</div>
);
}
```
在这个例子中,`<input />` 仅仅是 `<input />` 的一个*描述*。这个描述不能用来为`<input />`创建一个*真实的* **背后的实例**
那么对 input 的*真实的* 背后的实例,该怎么说呢?
## ref 字符串属性
React 假设你可以向任何的从`render()` 中返回的组件附加一个特别的属性。这个特殊的属性允许你引用任何的从`render()` 返回的东西对于有的**背后的实例**。而且保证在任何时间点都是合适的实例。
简单的说就是:
1. 给任何从`render()` 中返回的东西赋一个`ref` 的属性,如下所示:
```html
<input ref="myInput" />
```
2. 在其他的代码中(通常是事件处理代码中),通过 `this.refs` 来访问 **背后的实例** 如下所示:
```javascript
this.refs.myInput
```
通过调用`this.refs.myInput` 你可以直接方法这个组建的DOM。
## ref 回调属性
`ref` 属性可以用一个回调函数来替换一个名字。当这个组件装载好之后立即执行。被引用的组件被作为一个参数传入,这个回调函数可能立即使用这个组件,或保存这个引用,将来再用(或者两者都做)。
使用ES6的箭头函数为从`render` 中返回的东西添加一个`ref` 属性非常简单:
```html
render: function() {
return <TextInput ref={(c) => this._input = c} />;
},
componentDidMount: function() {
this._input.focus();
},
```
```html
render: function() {
return (
<TextInput
ref={function(input) {
if (input != null) {
input.focus();
}
}} />
);
},
```
注意当引用的组件被卸载以及无论何时这个引用改变之后,旧的引用将会被用`null` 作为一个参数来调用。这避免了当实例被存储的情形下- 像第一个例子那样 - 引起的内存泄漏。注意像这个例子中这样用inline 函数表达式写引用的时候每次有更新的时候Reac看到的都是不同的函数对象在引用被组件的实例调用之前引用被用`null` 调用。
## 完整的例子
```javascript
var App = React.createClass({
getInitialState: function() {
return {userInput: ''};
},
handleChange: function(e) {
this.setState({userInput: e.target.value});
},
clearAndFocusInput: function() {
// 清空input
this.setState({userInput: ''}, function() {
// 当这个组件被再次渲染之后,这个代码执行
this.refs.theInput.focus(); //获取焦点了!
});
},
render: function() {
return (
<div>
<div onClick={this.clearAndFocusInput}>
Click to Focus and Reset
</div>
<input
ref="theInput"
value={this.state.userInput}
onChange={this.handleChange}
/>
</div>
);
}
});
```
在这个例子中我们的render函数返回了`<input />` 实例的一个描述。但是真的实例通过`this.refs.theInput` 访问。只要`ref="theInput"` 从`render` 中返回了, `this.refs.theInput` 就可以访问合适的实例。这个事件对于高级的非DOM)的组件,例如`<Typeahead ref="myTypeahead" />` 也适用的。
## 总结
在不方便通过Reactive的 `props` 和`state` 流的方式传递信息的时候Refs是给一个特殊的子实例发送消息的重要的方法。然而他们不应该成为你的应用程序的到哪里去的数据流的抽象。对于那些本质上来说非交互的情形来说默认的应该使用Reactive数据流而少用`ref` 。
### 优点:
- 在你的组件类中你可以定义任意的公开方法例如在一个Typeahead定义一个reset方法然后通过refs来调用这些方法像这样`this.refs.myTypeahead.reset()`)。
- 执行 DOM操作总是要求诸如`<input />` 这样的一个“原生”组件,并通过`this.refs.myInput` 来访问她的低层的MOD 节点。Refs是可以做成这个事的唯一的实践可行的方法。
- Refs自动管理如果孩子被销毁了它的ref也被销毁。在这里不用担心内存除非你做了一些疯狂的事情来自己保持一个引用
### 小心:
- *绝对不要* 在组件的render方法内部- 获 当任何组件的render方法还在调用栈中执行的时候访问refs 。
- 如果你想要保护Google 闭包编译器崩溃的内力,确保绝不作为访问一个被特别的设置为一个字符串的属性。这就意味着,如果你用`ref="myRefString"` 来定义你的ref的话你必须使用`this.refs['myRefsString']` 来访问。
- 如果你不是用React做服务器编程的在你的程序中你首先的倾向是用refs来“让事情发生“。如果这是正是你的情况的话花点时间仔细的想想`state` 在这个组件的结构层次中应在在哪里使用。通常,正确的"拥有" 状态的地方是结构层次的高层。把状态放在那些地方通常可以消除使用`ref` 来”让事情发生” 的渴望 - 相反的,数据流通常能完成你的目标。

View File

@@ -1,137 +1,125 @@
---
id: more-about-refs-ko-KR
title: refs 심화
title: refs에서 컴포넌트로
permalink: more-about-refs-ko-KR.html
prev: working-with-the-browser-ko-KR.html
next: tooling-integration-ko-KR.html
---
render 메소드를 통해 UI 구조를 얻은 다음, 반환된 컴포넌트 인스턴스에 접근하거나 메소드를 호출할 방법이 필요할 수도 있습니다. 반응적 데이터 플로우가 `render()`의 결과물에서 최신의 `props`가 각각의 자식으로 보내진 것을 항상 보장하기 때문에 애플리케이션의 데이터 플로우를 만드는데 대체로 이런 작업은 필요가 없지만, 여전히 이런 작업이 필요하거나 유리한 경우가 있긴 합니다.
컴포넌트를 빌드한 후에는 `render()`에서 반환된 컴포넌트 인스턴스에 접근하거나 메소드를 호출할 방법이 필요할 수도 있습니다. 반응적 데이터 플로우가 `render()`의 결과물에서 최신의 `props`가 각각의 자식으로 보내진 것을 항상 보장하기 때문에 애플리케이션의 데이터 플로우를 만드는데 대체로 이런 작업은 필요가 없지만, 여전히 이런 작업이 필요하거나 유리한 경우가 있긴 합니다. React는 이를 위해 `refs`라는 탈출구를 제공합니다. `refs`(레퍼런스)는 특히 다음과 같은 경우 유용합니다: 컴포넌트에 의해 렌더된 DOM 마크업을 찾을때 (인스턴스내의 절대적인 위치), 큰 프로젝트의 일부에 React 컴포넌트를 사용하는 경우 또는 기존의 코드베이스를 React로 변경하는 경우.
ref를 어떻게 얻는지 살펴보고, 예제를 완성해 봅시다.
인스턴스의 하위 계층구조에 존재하는 `<input />` 엘리먼트의 value를 빈 문자열(`''`)로 업데이트한 후 포커스 하는 경우를 생각해 봅시다.
## ReactDOM.render에서 반환된 ref
```javascript
var App = React.createClass({
getInitialState: function() {
return {userInput: ''};
},
handleChange: function(e) {
this.setState({userInput: e.target.value});
},
clearAndFocusInput: function() {
this.setState({userInput: ''}); // 입력내용을 지워줍니다
// 이제 <input />에 포커스를 주길 원합니다!
},
render: function() {
return (
<div>
<div onClick={this.clearAndFocusInput}>
클릭해서 초기화하고 포커스주기
</div>
<input
value={this.state.userInput}
onChange={this.handleChange}
/>
</div>
);
}
});
컴포넌트에서 정의한, 가상의 DOM 엘리먼트를 반환하는 `render()`와 헷갈리지 않도록 합니다. [ReactDOM.render()](/react/docs/top-level-api-ko-KR.html#reactdom.render)는 컴포넌트의 **지원 인스턴스(backing instance)**에 대한 참조를 반환 합니다. [상태를 가지지 않는 컴포넌트](/react/docs/reusable-components-ko-KR.html#stateless-functions)에 대해선 `null`을 반환하죠.
```js
var myComponent = ReactDOM.render(<MyComponent />, myContainer);
```
명심하세요. 위의 코드는 컴포넌트 인스턴스를 반환하지 않습니다! 이는 그저 **ReactElement**:React에 마운트된 컴포넌트가 어떻게 보여야 할지 알려주는 경량의 표상(representation) 입니다.
```js
var myComponentElement = <MyComponent />; // 이건 그냥 ReactElement 입니다.
한번 살펴보죠. 이 예제에서 우리는 시간이 지남에 따라 props에서 추론할 수 없는 무언가를 입력하도록 "알려주길" 원했습니다. 이 사례에서 우리는 이제 포커스 되도록 "알려주길" 원합니다. 그러나 몇 가지 문제가 있습니다. `render()`에서 반환된 것은 "자식" 컴포넌트의 실제 구성이 아니고, 단지 특정 시점의 인스턴스의 자식에 대한 *서술*일 뿐입니다. - 말하자면 스냅샷인 것이지요.
// 여기 코드가 위치합니다...
var myComponentInstance = ReactDOM.render(myComponentElement, myContainer);
myComponentInstance.doSomething();
```
> 주의:
>
> 기억하세요, `render()`에서 반환된 것은 *실제* 자식 인스턴스가 아닙니다. 단지 특정 시점의 컴포넌트의 하위 계층구조에 있는 자식 인스턴스의 *서술*일 뿐입니다.
> 이는 오직 최상위 레벨에서만 사용되어야 합니다. 컴포넌트의 내부에서는 `props`와 `state`가 자식 컴포넌트와 통신하도록 하거나 문자열이나 콜백 어트리뷰트 등 ref를 얻어오는 다른 방법을 사용하도록 하세요.
## ref 콜백 어트리뷰트
React는 어떤 컴포넌트에든 추가할 수 있는 특별한 어트리뷰트를 제공합니다. `ref` 어트리뷰트는 콜백 함수일 수 있으며 이는 컴포넌트가 마운트 된 후 즉시 실행됩니다. 참조된 컴포넌트는 파라미터로 전달될 것이며 콜백 함수는 즉시, 혹은 미래에 사용하기 위해 컴포넌트의 참조를 저장합니다.
이는 `render()`에서 반환된 무언가를 "계속 유지할 수" 없으며 아무런 의미도 없을 것이라는 뜻입니다.
`render`에서 반환되는 무엇에든 `ref` 어트리뷰트를 추가하는 것은 간단합니다:
```javascript
// 안티패턴: 이것은 동작하지 않습니다.
```js
render: function() {
var myInput = <input />; // 여기서 메소드를 호출할 겁니다.
this.rememberThisInput = myInput; // 언젠가 미래의 특정 시점에 입력할 거에요! YAY!
return (
<div>
<div>...</div>
{myInput}
</div>
<TextInput
ref={function(input) {
if (input != null) {
input.focus();
}
}} />
);
}
},
```
ES6 화살표 함수를 사용한다면 다음과 같습니다:
```js
render: function() {
return <TextInput ref={(c) => this._input = c} />;
},
componentDidMount: function() {
this._input.focus();
},
```
이 예제에서 `<input />`은 단지 `<input />`의 *서술*일 뿐입니다. 이 서술은 `<input />`에 대한 *진짜* **지원 인스턴스(backing instance)**를 생성하는 데 사용됩니다.
`<div />` 같은 DOM 컴포넌트에 ref를 추가하면 DOM 노드를 얻게 됩니다; `<TextInput />` 같은 합성 컴포넌트에 ref를 추가하면 React 클래스 인스턴스를 얻게 됩니다. 후자의 경우, 클래스에 정의되어 있는 노출된 메소드를 호출할 수 있습니다.
자 그럼 어떻게 *진짜* input의 지원 인스턴스를 다룰까요?
참조된 컴포넌트가 언마운트되고 ref가 변경되면 이전의 ref는 `null`을 인수로 호출됨을 주의 하세요. 이는 첫번째 예제에서처럼 인스턴트가 저장된 경우의 메모리 누수를 방지합니다. 또한 예제와 같이 ref를 인라인 함수 표현식으로 서술하게되면 React는 모든 업데이트에 대해 다른 함수 객체를 참조하게 됩니다. ref는 컴포넌트의 인스턴스의 호출 이전에 `null` 객체와 함께 즉시 호출될 것입니다.
## ref 문자열 어트리뷰트
React는 `render()`로 출력된 컴포넌트에 추가할 수 있는 아주 특별한 프로퍼티를 지원합니다. 특별한 프로퍼티는 `render()`에서 반환한 모든 것들에 대해 각각에 대응하는 **지원 인스턴스**를 참조할 수 있습니다. 이는 항상 어떤 시점에서든 올바른 인스턴스를 보장합니다.
React는 ref에 콜백 대신 문자열도 지원합니다 이런 접근은 이제 과거의 것이긴 합니다.
간단합니다:
1. `render`에서 반환된 값을 `ref` 어트리뷰트에 할당합니다:
```html
<input ref="myInput" />
```
```html
<input ref="myInput" />
```
2. 다른 코드(일반적으로는 이벤트 핸들러 코드)에서 `this.refs`를 통해 **지원 인스턴스**에 접근 합니다:
```javascript
this.refs.myInput
```
```javascript
var input = this.refs.myInput;
var inputValue = input.value;
var inputRect = input.getBoundingClientRect();
```
`this.refs.myInput`를 호출해 컴포넌트의 DOM 노드에 접근할 수 있습니다.
## ref 콜백 어트리뷰트
`ref` 어트리뷰트는 이름 대신 콜백 함수가 될 수도 있습니다. 이 콜백은 컴포넌트가 마운트 된 뒤 즉시 실행될 것입니다. 참조된 컴포넌트는 매개 변수로 전달되며 콜백은 이를 즉시 사용하거나, 앞으로 사용하기 위해 참조를 저장해 놓거나, 혹은 둘 다 할 것입니다.
`render`에서 반환한 모든 것에 간단하게 `ref` 어트리뷰트를 할당할 수 있습니다:
```html
<input ref={ function(component){component.focus();} } />
```
## 예제 완성하기
## 최종 예제
React 컴포넌트의 참조를 얻기 위해서, 현재의 React 컴포넌트를 위해서는 `this`를, 소유한 컴포넌트에 대해서는 ref를 사용할 수 있습니다. 다음과 같이 작동 합니다:
```javascript
var App = React.createClass({
getInitialState: function() {
return {userInput: ''};
},
handleChange: function(e) {
this.setState({userInput: e.target.value});
},
clearAndFocusInput: function() {
// input을 비워준다
this.setState({userInput: ''}, function() {
// 이 코드는 컴포넌트가 다시 렌더 된 다음 실행됩니다
this.refs.theInput.focus(); // 짠! 포커스 됨!
});
},
render: function() {
return (
<div>
<div onClick={this.clearAndFocusInput}>
클릭해서 초기화하고 포커스주기
</div>
<input
ref="theInput"
value={this.state.userInput}
onChange={this.handleChange}
/>
</div>
);
}
});
var MyComponent = React.createClass({
handleClick: function() {
// 명시적으로 텍스트 인풋에 포커스하기 위해 raw DOM API를 사용합니다.
this.myTextInput.focus();
},
render: function() {
// ref 어트리뷰트는 컴포넌트가 마운트되면
// this.refs에 컴포넌트에 대한 참조를 추가합니다.
return (
<div>
<input type="text" ref={(ref) => this.myTextInput = ref} />
<input
type="button"
value="Focus the text input"
onClick={this.handleClick}
/>
</div>
);
}
});
ReactDOM.render(
<MyComponent />,
document.getElementById('example')
);
```
이 예제에서 render 함수는 `<input />` 인스턴스의 서술을 반환했지만, 진짜 인스턴스는 `this.refs.theInput`을 통해 접근할 수 있었습니다. `render`에서 `ref="theInput"`을 가진 컴포넌트가 반환된 동안, `this.refs.theInput`은 적절한 인스턴스에 접근합니다. 이는 `<Typeahead ref="myTypeahead" />`처럼 DOM이 아닌 고수준의 컴포넌트에서도 동작합니다.
이 예제에서, 텍스트 인풋의 **지원 인스턴스**에 대한 참조를 얻었으며 버튼이 클릭되었을때 `focus()`를 호출했습니다.
합성 컴포넌트에서는 참조는 컴포넌트 클래스의 인스턴스를 가리키기 때문에 클래스에 정의된 어떤 메소드도 호출할 수 있습니다. 컴포넌트의 기저에 있는 DOM 노드에 접근하기 위해서는 [ReactDOM.findDOMNode](/react/docs/top-level-api-ko-KR.html#reactdom.finddomnode)를 "탈출구"로 사용할 수 있습니다. 하지만 이는 캡슐화를 깨며, 대부분의 경우 React 모델을 이용해 더 명확한 방법으로 구조를 짤 수 있기 때문에 추천하지 않습니다.
## 요약
@@ -139,12 +127,13 @@ Refs는 반응적인 `props`와 `state` 스트리밍을 통해서는 불편했
### 이점:
- 컴포넌트 클래스에 public 메소드(ex. Typeahead의 reset)를 선언할 수 있으며 refs를 통해 그를 호출할 수 있습니다. (ex. `this.refs.myTypeahead.reset()`)
- DOM을 측정하기 위해서는 거의 항상 `<input />` 같은 "기본" 컴포넌트를 다루고 `this.refs.myInput`를 통해 그 기저의 DOM 노드에 접근해야 합니다. Refs는 이 일을 확실하게 수행하는 몇 안 되는 실용적인 방법의 하나입니다.
- 컴포넌트 클래스에 public 메소드(ex. Typeahead의 reset)를 선언할 수 있으며 refs를 통해 그를 호출할 수 있습니다. (ex. `this.refs.myTypeahead.reset()`) 대부분, 이는 선언적으로 refs를 사용하는 것보다 내장 React 데이터 흐름을 명확하게 합니다.
- DOM을 측정하기 위해서는 거의 항상 `<input />` 같은 "기본" 컴포넌트를 다루고 ref를 통해 그 기저의 DOM 노드에 접근해야 합니다. Refs는 이 일을 확실하게 수행하는 몇 안 되는 실용적인 방법의 하나입니다.
- Refs는 자동으로 관리합니다! 자식이 파괴되면, 그의 ref도 마찬가지로 파괴됩니다. 참조를 유지하기 위해 뭔가 미친 짓을 하지 않는 한, 메모리 걱정은 하지 않아도 됩니다.
### 주의:
- 컴포넌트의 렌더 메소드에서는, 혹은 컴포넌트의 렌더 메소드가 콜스택 어디에서든 실행되는 동안에는 절대 접근하지 마세요.
- Google Closure Compiler에서의 분쇄 복원력 유지(to preserve Crushing resilience)를 위해서는 문자열로 정의한 것을 절대 프로퍼티로 접근하지 마세요. ref가 ref="myRefString"으로 정의되어 있다면 this.refs['myRefString']으로만 접근해야 한다는 이야기 입니다.
- Google Closure Compiler에서의 어드벤스드 모드 분쇄 복원력 유지(to preserve advanced-mode crushing resilience)를 위해서는 문자열로 정의한 것을 절대 프로퍼티로 접근하지 마세요. ref가 ref="myRefString"으로 정의되어 있다면 this.refs['myRefString']으로만 접근해야 한다는 이야기 입니다.
- React로 앱을 여럿 만들어 본 경험이 없다면, 보통은 처음엔 앱에서 "무언가 일어나도록" 하는데 refs를 사용하게 될 것입니다. 이 경우, 잠시 시간을 내어 `state`가 컴포넌트 계층구조의 어느 부분에서 관리되어야 할지 비판적으로 생각해 봅시다. 대개는 state가 계층구조의 더 높은 레벨에서 "소유"하는 것이 타당함이 명확해집니다. 그렇게 함으로써 `ref`를 사용해 "무언가 일어나도록" 하려는 욕망이 대부분 제거됩니다. - 대신에 데이터 플로우를 통해 대개 원하는 바를 달성하게 될 것입니다.
- Refs는 [상태를 가지지 않는 함수](/react/docs/reusable-components-ko-KR.html#stateless-functions)에 붙일 수 없습니다. 왜냐하면 컴포넌트가 내부 인스턴스를 가지지 않기 때문입니다. 상태를 가지지 않는 컴포넌트는 항상 일반 컴포넌트로 감싸 ref를 조합 컴포넌트에 붙일 수 있습니다.

View File

@@ -5,7 +5,7 @@ permalink: more-about-refs.html
prev: working-with-the-browser.html
next: tooling-integration.html
---
After building your component, you may find yourself wanting to "reach out" and invoke methods on component instances returned from `render()`. In most cases, this should be unnecessary because the reactive data flow always ensures that the most recent props are sent to each child that is output from render(). However, there are a few cases where it still might be necessary or beneficial, so React provides an escape hatch known as `refs`. These `refs` (references) are especially useful when you need to: find the DOM markup rendered by a component (for instance, to position it absolutely), use React components in a larger non-React application, or transition your existing codebase to React.
After building your component, you may find yourself wanting to "reach out" and invoke methods on component instances returned from `render()`. In most cases, this should be unnecessary because the reactive data flow always ensures that the most recent props are sent to each child that is output from `render()`. However, there are a few cases where it still might be necessary or beneficial, so React provides an escape hatch known as `refs`. These `refs` (references) are especially useful when you need to: find the DOM markup rendered by a component (for instance, to position it absolutely), use React components in a larger non-React application, or transition your existing codebase to React.
Let's look at how to get a ref, and then dive into a complete example.

View File

@@ -1,109 +1,45 @@
---
id: more-about-refs-zh-CN
title: 关于Refs的更多内容
title: 对组件的refs
permalink: more-about-refs-zh-CN.html
prev: working-with-the-browser-zh-CN.html
next: tooling-integration-zh-CN.html
---
从render方法返回你的UI结构以后,你也许发现自己想“接触”并且调用从 `render()`返回的组件实例上的方法。通常这样做对于让数据流过你的应用并不是必须的因为Reactive的数据流总是确保最新的`props`送到 `render()`输出的每个子级。然而,有一些情况下它仍旧是必要或者有益的。
在建立你的组件以后,你也许发现想“接触”并且调用从 `render()`返回的组件实例上的方法。大部分情况下,这是不必要的因为响应式的数据流总是确保最近的 props 被送到每一个从 `render()` 输出的子级。然而,有一些情况下它仍旧是必要或者有益的,所以 React 提供了一个被称为 `refs` 的安全舱口。这些 `refs` (引用) 在你需要时特别有用 如:查找被组件绘制的 DOM 标记(例如,绝对定位它),使用 React 组件在一个大的非React组件里或者转换你已有的代码库到React
考虑这样一种场景,当你想要告诉一个`<input />` 元素(存在于你的实例的子层级)在你更新他的值为空字符串后获得焦点
让我们来看看怎样取得一个ref然后深入完整的例子
```javascript
var App = React.createClass({
getInitialState: function() {
return {userInput: ''};
},
handleChange: function(e) {
this.setState({userInput: e.target.value});
},
clearAndFocusInput: function() {
this.setState({userInput: ''}); // Clear the input
// We wish to focus the <input /> now!
},
render: function() {
return (
<div>
<div onClick={this.clearAndFocusInput}>
Click to Focus and Reset
</div>
<input
value={this.state.userInput}
onChange={this.handleChange}
/>
</div>
);
}
});
## 从 ReactDOM.render 返回的 ref
不要被 你在你的组件它返回一个虚拟的DOM元素里定义的 `render()` 迷惑了, [ReactDOM.render()](/react/docs/top-level-api.html#reactdom.render) 会返回一个对你的组件的 **backing instance** 的引用(或者 `null` for [stateless components](/react/docs/reusable-components.html#stateless-functions)).
```js
var myComponent = ReactDOM.render(<MyComponent />, myContainer);
```
记住不管怎样JSX不会返回一个组件的实例它只是一个 **ReactElement**: 一个轻量级的表达告诉React被挂载的组件应该长什么样。
注意,在这个例子中,我们想 "告诉" input 一些东西 - 那些最后它不能从他的props推断出来的东西。在这个场景中我们想 "告诉" 它,它应该转为获得焦点。然而,有一些挑战。从`render()` 返回的东西不是你实际的 "子" 组件的组合,而是一个在某刻特定实例的子组件的 *描述* - 一个快照。
```js
var myComponentElement = <MyComponent />; // 这只是一个 ReactElement.
// 省略一些代码 ...
var myComponentInstance = ReactDOM.render(myComponentElement, myContainer);
myComponentInstance.doSomething();
```
> 注意:
>
> 记住,从 `render()`返回的东西不是你的 *实际的* 被渲染出的子组件实例。从 `render()` 返回的东西仅仅是一个在特定时间你的组件的子层级中的子实例的 *描述*
> 这只应该用在顶层上。在组件内部,让你的 `props` 和 `state` 来处理和子组件的通信或者使用其他获取ref的方法string attribute or callbacks
## ref Callback 属性
这意味着你万万不要把你从`render()`返回的东西 "抓住不放" 然后期望它变成任何有意义的东西
React支持一种非常特殊的属性你可以附加到任何的组件上。 `ref` 属性可以是一个回调函数,这个回调函数会在组件被挂载后立即执行。被引用的组件会被作为参数传递,回调函数可以用立即使用这个组件,或者保存引用以后使用(或者二者皆是)
```javascript
// 反面模式: 这行不通.
render: function() {
var myInput = <input />; // I'm going to try to call methods on this
this.rememberThisInput = myInput; // input at some point in the future! YAY!
return (
<div>
<div>...</div>
{myInput}
</div>
);
}
```
简单的说就是添加一个 `ref` 属性到任何从 `render` 返回的东西上:
在这个例子中,`<input />` 仅仅是一个`<input />`*描述*。 这个描述被用于为`<input />`创建一个 *真实的* **支持实例(backing instance)**
所以我们如何与input的 *真实的*支持实例对话?
## ref String 属性
React支持一种非常特殊的属性你可以附加到任何从`render()`输出的组件上。这个特殊的属性允许你引用任何从`render()`返回的东西的对应 **支持实例(backing instance)** 。它总是保证是适当的实例,在任何时点上。
就是这么简单:
1. 赋值`ref`属性为任何从`render` 返回的东西,比如:
```html
<input ref="myInput" />
```
2. 在其他一些代码中(典型的事件处理代码),通过`this.refs`访问 **支持实例(backing instance)**,如:
```javascript
this.refs.myInput
```
你可以直接通过调用`ReactDOM.findDOMNode(this.refs.myInput)` 访问组件的DOM node。
## ref 回调属性
`ref` 属性可以是一个回调函数而不是名字。这个回调函数将会在组件挂载以后立即执行。被引用的组件将被作为参数传递,并且回调函数可以立即使用组件,或者保存引用将来使用(或两者都是)。
通过使用ES6的箭头函数它像添加一个`ref`属性到任何从`render`返回的东西一样简单。
```html
render: function() {
return <TextInput ref={(c) => this._input = c} />;
},
componentDidMount: function() {
this._input.focus();
},
```
或者
```html
```js
render: function() {
return (
<TextInput
@@ -115,60 +51,87 @@ React支持一种非常特殊的属性你可以附加到任何从`render()`
);
},
```
或者使用ES6的箭头函数:
```js
render: function() {
return <TextInput ref={(c) => this._input = c} />;
},
componentDidMount: function() {
this._input.focus();
},
```
当连接一个ref到一个DOM组件如 `<div />`你取回DOM节点;当连接一个ref到一个复合组件如 `<TextInput />`你会得到React类的实例。在后一种情况下你可以调用任何那个组件的类暴露的方法。
注意当被引用的组件卸载和每当ref变动旧的ref将会被以`null`做参数调用。这阻止了在实例被保存的情况下的内存泄露如第一个例子。注意当像在这里的例子使用内联函数表达式写refsReact在每次更新都看到不同的函数对象ref将会被以`null` 立即调用在它被以组件实例调用前。
## ref String 属性
## 完成的示例
React同样支持使用一个字符串代替回调函数在任意组件上作为一个 ref prop尽管这个方法在这点上主要是遗留物。
1. 赋值`ref`属性为任何从`render` 返回的东西,比如:
```html
<input ref="myInput" />
```
2. 在其他一些代码中(典型的事件处理代码),通过`this.refs`访问 **支持实例(backing instance)**,如:
```javascript
var input = this.refs.myInput;
var inputValue = input.value;
var inputRect = input.getBoundingClientRect();
```
## 完整的示例
为了获取一个React组件的引用你既可以使用 `this` 来获取当前的React组件也可以使用一个 ref 来获取一个你拥有的组件的引用。他们像这样工作:
```javascript
var App = React.createClass({
getInitialState: function() {
return {userInput: ''};
},
handleChange: function(e) {
this.setState({userInput: e.target.value});
},
clearAndFocusInput: function() {
// Clear the input
this.setState({userInput: ''}, function() {
// This code executes after the component is re-rendered
ReactDOM.findDOMNode(this.refs.theInput).focus(); // Boom! Focused!
});
},
render: function() {
return (
<div>
<div onClick={this.clearAndFocusInput}>
Click to Focus and Reset
</div>
<input
ref="theInput"
value={this.state.userInput}
onChange={this.handleChange}
/>
</div>
);
}
});
var MyComponent = React.createClass({
handleClick: function() {
// Explicitly focus the text input using the raw DOM API.
this.myTextInput.focus();
},
render: function() {
// The ref attribute adds a reference to the component to
// this.refs when the component is mounted.
return (
<div>
<input type="text" ref={(ref) => this.myTextInput = ref} />
<input
type="button"
value="Focus the text input"
onClick={this.handleClick}
/>
</div>
);
}
});
ReactDOM.render(
<MyComponent />,
document.getElementById('example')
);
```
在这个例子中, 我们的render函数返回一个 `<input />` 实例的描述。但是真正的实例通过 `this.refs.theInput` 访问。只要带有`ref="theInput"`的子组件从 `render`被返回,`this.refs.theInput` 就可以访问正确的实例。这甚至在更高层(non-DOM)的组件上生效,比如`<Typeahead ref="myTypeahead" />`。
在这个例子中,我们获得一个对 text input **backing instance** 的引用 并且当按钮被点击时我们调用 `focus()`。
对于复合组件引用会指向一个组件类的实例所以你可以调用那个类定义的任何方法。如果你需要访问那个组件的底层的DOM节点你可以使用 [ReactDOM.findDOMNode](/react/docs/top-level-api.html#reactdom.finddomnode) 作为一个 `安全舱口` 但是我们不推荐这样因为它打破了封装在大多数情况下都有一个清晰的方法来以React模式构建你的代码.
## 总结
Refs是一种很好的发送消息给特定子实例(通过流式的Reactive `props` 和 `state`来做会不方便)的方式。它们应该,不论怎样,不是你数据流通你的应用的首选。默认方式使用Reactive数据流并为本身不是reactive的用例保存`ref`。
Refs是一种很好的发送消息给特定子实例(通过流式的Reactive `props` 和 `state`来做会不方便)的方式。它们应该,不论怎样,不是你数据流通你的应用的首选。默认情况下,使用响应式数据流并为本身不是reactive的用例保存`ref`s
### 优点:
- 你可以在你的组件类里定义任何的公开方法比如在一个Typeahead的重置方法然后通过refs调用那些公开方法比如`this.refs.myTypeahead.reset()`)。
- 实行DOM测量几乎总是需要接触到"原生" 组件比如 `<input />` 并且`ReactDOM.findDOMNode(this.refs.myInput)`通过访问它的底层DOM 节点。 Refs 是唯一一个可靠的完成这件事的实际方式。
- 你可以在你的组件类里定义任何的公开方法比如在一个Typeahead的重置方法然后通过refs调用那些公开方法比如`this.refs.myTypeahead.reset()`)。在大多数情况下使用内建的React数据流更清晰而不是使用强制的ref。
- 实行DOM测量几乎总是需要接触到 "原生" 组件比如 `<input />` 并且通过 ref 访问它的底层DOM节点。 Refs 是唯一一个可靠的完成这件事的实际方式。
- Refs 是为你自动管理的如果子级被销毁了它的ref也同样为你销毁了。这里不用担心内存除非你做了一些疯狂的事情来自己保持一份引用
### 注意事项:
- *绝不* 在任何组件的 render 方法中访问 refs - 或者当任何组件的render方法还在调用栈上的任何地方运行时。
- 如果你想要保留Google Closure Compiler Crushing resilience务必不要指明为字符串的属性来访问。这意味这你必须用`this.refs['myRefString']`访问如果你的ref被定义为`ref="myRefString"`。
- 如果你没有用React写过数个程序你的第一反应通常是打算试着用refs来在你的应用里"让事情发生"。如果是这样,花一些时间并且更精密的思考`state`应该属于组件层级的哪个位置。常常,这会变得清晰:正确的"拥有"那个属性的地方应该在层级的更高层上。把state放在那里往往消除了任何使用`ref`来 "让事情发生"的渴望 - 作为替代,数据流通常将完成你的目标。
- 如果你想要保留Google Closure Compiler advanced-mode crushing resilience务必不要以属性的方式访问指明为字符串的属性。这意味这你必须用`this.refs['myRefString']`访问如果你的ref被定义为`ref="myRefString"`。
- 如果你没有用React写过数个程序你的第一反应通常是打算试着用refs来在你的应用里"让事情发生"。如果是这样,花一些时间并且更精密的思考`state`应该属于组件层级的哪个位置。常常,这会变得清晰:正确的"拥有"那个属性的地方应该在层级的更高层上。把state放在那里 往往消除了任何使用`ref`s 来 "让事情发生"的渴望 - 作为替代,数据流通常将完成你的目标。
- Refs 不能连接到一个 [stateless function无状态函数](/react/docs/reusable-components.html#stateless-functions)因为这些组件没有支持实例。你总是可以包装一个无状态组件在一个标准复合组件里并且连接一个ref到这个复合组件。

View File

@@ -23,7 +23,7 @@ next: addons-ko-KR.html
### 브라우저에서 JSX 변환
JSX를 사용하신다면, [다운로드 페이지](/react/downloads.html)에서 브라우저 JSX 변환기를 제공합니다. 간단히 `<script type="text/jsx">`를 넣으면 JSX 변환기가 작동합니다.
JSX를 사용하신다면, Babel에서 browser.js라는 [개발용 브라우저 ES6, JSX 변환기](http://babeljs.io/docs/usage/browser/)를 제공합니다. 이는 `babel-core`의 npm 릴리스나 [CDNJS](http://cdnjs.com/libraries/babel-core)로 넣을 수 있습니다. `<script type="text/babel">`를 넣으면 JSX 변환기가 작동합니다.
> 주의:
>
@@ -32,12 +32,48 @@ JSX를 사용하신다면, [다운로드 페이지](/react/downloads.html)에서
### 상용화하기: 미리 컴파일된 JSX
[npm](https://www.npmjs.com/) 모듈을 가지고 있다면, 간단히 `npm install -g react-tools`를 실행해 커맨드 라인 `jsx` 툴을 설치할 수 있습니다. 이 툴은 JSX 구문을 일반적인 JavaScript파일로 변환해 브라우져에서 바로 실행할 수 있도록 합니다. 디렉터리를 감시해 파일이 변경되었을 때 자동으로 변환하도록 할 수도 있습니다. 예를 들면 `jsx --watch src/ build/` 이렇게요.
[npm](https://www.npmjs.com/) 모듈을 가지고 있다면, `npm install -g babel-cli`를 실행할 수 있습니다. Babel은 React v0.12이상을 내장 지원합니다. 태그는 자동으로 동등한 `React.createElement(...)`로 변환되며, `displayName`은 모든 `React.createClass` 호출에 자동으로 추론, 추가됩니다.
기본적으로는 JSX 파일들은 `.js` 확장자로 변환됩니다. `jsx --extension jsx src/ build/`를 사용해 `.jsx` 확장자로 파일들을 변환할 수 있습니다.
이 툴은 JSX 구문을 일반적인 JavaScript파일로 변환해 브라우져에서 바로 실행할 수 있도록 합니다. 디렉터리를 감시해 파일이 변경되었을 때 자동으로 변환하도록 할 수도 있습니다. 예를 들면 `babel --watch src/ --out-dir lib/` 이렇게요.
이 툴을 어떻게 사용하는지 더 자세하게 알고싶으시면 `jsx --help`를 실행해 보세요.
Babel 6부터 기본값으로 변환기가 포함되지 않게 되었습니다. 이는 `babel` 명령을 실행할 때나 `.babelrc`에 반드시 옵션을 지정해야 한다는 뜻입니다. React를 사용할 때 가장 일반적인 방법은 `es2015`, `react` 프리셋을 사용하는 것입니다. Babel의 변경에 대한 좀 더 자세한 정보는 [블로그에 올라온 Babel 6 공지 글](http://babeljs.io/blog/2015/10/29/6.0.0/)을 읽어보세요.
ES2015 문법과 React를 사용하려 할 경우의 예제입니다.
```
npm install babel-preset-es2015 babel-preset-react
babel --presets es2015,react --watch src/ --out-dir lib/
```
기본적으로는 JSX 파일들은 `.js` 확장자로 변환됩니다. 바벨을 어떻게 사용하는지 더 자세하게 알고싶으시면 `babel --help`를 실행해 보세요.
출력 예:
```
$ cat test.jsx
var HelloMessage = React.createClass({
render: function() {
return <div>Hello {this.props.name}</div>;
}
});
ReactDOM.render(<HelloMessage name="John" />, mountNode);
$ babel test.jsx
"use strict";
var HelloMessage = React.createClass({
displayName: "HelloMessage",
render: function render() {
return React.createElement(
"div",
null,
"Hello ",
this.props.name
);
}
});
ReactDOM.render(React.createElement(HelloMessage, { name: "John" }), mountNode);
```
### 도움되는 오픈소스 프로젝트들

View File

@@ -30,10 +30,19 @@ If you like using JSX, Babel provides an [in-browser ES6 and JSX transformer for
### Productionizing: Precompiled JSX
If you have [npm](https://www.npmjs.com/), you can run `npm install -g babel`. Babel has built-in support for React v0.12 and v0.13. Tags are automatically transformed to their equivalent `React.createElement(...)`, `displayName` is automatically inferred and added to all React.createClass calls.
If you have [npm](https://www.npmjs.com/), you can run `npm install -g babel-cli`. Babel has built-in support for React v0.12+. Tags are automatically transformed to their equivalent `React.createElement(...)`, `displayName` is automatically inferred and added to all `React.createClass` calls.
This tool will translate files that use JSX syntax to plain JavaScript files that can run directly in the browser. It will also watch directories for you and automatically transform files when they are changed; for example: `babel --watch src/ --out-dir lib/`.
Beginning with Babel 6, there are no transforms included by default. This means that options must be specified when running the `babel` command, or a `.babelrc` must specify options. Additional packages must also be installed which bundle together a number of transforms, called presets. The most common use when working with React will be to include the `es2015` and `react` presets. More information about the changes to Babel can be found in [their blog post announcing Babel 6](http://babeljs.io/blog/2015/10/29/6.0.0/).
Here is an example of what you will do if using ES2015 syntax and React:
```
npm install babel-preset-es2015 babel-preset-react
babel --presets es2015,react --watch src/ --out-dir lib/
```
By default JSX files with a `.js` extension are transformed. Run `babel --help` for more information on how to use Babel.
Example output:

View File

@@ -14,7 +14,6 @@ next: addons-zh-CN.html
我们提供了CDN-hosted版本的React[在我们的下载页面](/react/downloads.html).这些预构建的文件使用UMD模块格式。将他们放进一个简单的`<script>` 标签将会注入一个`React` 全局变量到你的环境里。这也同样在CommonJS 和 AMD 环境里开箱即用。
### 使用 master
我们[在我们的 GitHub repository](https://github.com/facebook/react)有从`master`构建的说明。我们在`build/modules` 下构建了一个CommonJS模块的树你可以把它放到任何支持CommonJS的环境或者打包工具里。
@@ -29,13 +28,21 @@ next: addons-zh-CN.html
>
> 浏览器中的JSX转换器相当大并且导致额外的本可避免的客户端计算。不要在生产环境中使用 - 见下一节。
### 投入生产: 预编译 JSX
如果你有[npm](https://www.npmjs.com/),你可以运行 `npm install -g babel`. Babel 对React v0.12 和 v0.13 有内建支持。 标签被自动转化为它们的等价物`React.createElement(...)`, `displayName` 被自动推断并添加到所有的React.createClass 调用。
如果你有[npm](https://www.npmjs.com/),你可以运行 `npm install -g babel-cli`. Babel 对React v0.12+ 有内建支持。 标签被自动转化为它们的等价物`React.createElement(...)`, `displayName` 被自动推断并添加到所有的React.createClass 调用。
这个工具会把使用JSX语法的文件转化为简单的可直接在浏览器运行的JavaScript文件。它同样将为你监视目录并自动转化文件当他们变动时例如`babel --watch src/ --out-dir lib/`.
从 Babel 6 开始,默认不再包含转换。这意味这必须在运行 `babel` 命令时指定选项,或者 `.babelrc` 必须指定选项。附加的捆绑了一大批转化的包(presets)也同样需要被安装.协同React工作最常用的是 `es2015``react` presets.更多关于 Babel 变化的信息可以在 [Babel 6 博客发布的信息](http://babeljs.io/blog/2015/10/29/6.0.0/)上找到.
这里是一个要使用ES2015 语法和 React 你该怎样做的例子:
```
npm install babel-preset-es2015 babel-preset-react
babel --presets es2015,react --watch src/ --out-dir lib/
```
默认模式下带有`.js`后缀的JSX文件被转化。运行 `babel --help` 获取更多关于如何使用 Babel 的信息。
输出的例子:
@@ -68,7 +75,6 @@ var HelloMessage = React.createClass({
ReactDOM.render(React.createElement(HelloMessage, { name: "John" }), mountNode);
```
### 有帮助的开源项目
开源社区已经创建了一些集成JSX到数个编辑器和构建系统的工具。见[JSX integrations](https://github.com/facebook/react/wiki/Complementary-Tools#jsx-integrations) 查看全部列表
开源社区已经创建了一些集成JSX到数个编辑器和构建系统的工具。全部列表请见[JSX integrations](https://github.com/facebook/react/wiki/Complementary-Tools#jsx-integrations) 。

View File

@@ -6,7 +6,7 @@ prev: tooling-integration-ko-KR.html
next: animation-ko-KR.html
---
`React.addons`은 React 앱을 만드는 데 유용한 유틸리티를 두는 곳입니다. **실험적인 기능으로 취급해야 하지만** 결국 코어나 유틸리티 라이브러리에 포함될 예정입니다.
React 애드온은 React 앱을 만드는 데 유용한 유틸리티의 모음입니다. **실험적인 기능으로 취급해야 하** 코어보다 더 자주 변경될 수 있습니다.
- [`TransitionGroup` 과 `CSSTransitionGroup`](animation-ko-KR.html)은 예를 들면 컴포넌트 삭제 직전의 트랜지션 처럼, 구현하기 까다로운 애니메이션과 트랜지션을 다룹니다.
- [`LinkedStateMixin`](two-way-binding-helpers-ko-KR.html)는 사용자 입력과 컴포넌트의 state사이의 조정(coordination)을 단순화 합니다.
@@ -20,6 +20,4 @@ next: animation-ko-KR.html
- [`TestUtils`](test-utils-ko-KR.html)는 테스트 케이스를 적기 위한 간단한 헬퍼입니다. (압축되지 않은 빌드에서만 사용가능)
- [`Perf`](perf-ko-KR.html)는 성능을 측정하고, 최적화를 위한 힌트를 제공합니다.
애드온을 쓰려면, 보통 `react.js` 대신 `react-with-addons.js`(혹은 압축판)을 사용해야 합니다.
npm을 이용해 React 패키지를 설치해 사용한다면, 그냥 `require('react')` 대신 `require('react/addons')`을 사용해 모든 애드온을 쓸 수 있습니다.
애드온을 쓰려면, npm에서 각각 설치하세요.(예를 들면, `npm install react-addons-pure-render-mixin`) npm을 사용하지 않는 애드온 사용법에 대한 지원은 없습니다.

View File

@@ -14,6 +14,7 @@ The React add-ons are a collection of useful utility modules for building React
- [`createFragment`](create-fragment.html), to create a set of externally-keyed children.
- [`update`](update.html), a helper function that makes dealing with immutable data in JavaScript easier.
- [`PureRenderMixin`](pure-render-mixin.html), a performance booster under certain situations.
- [`shallowCompare`](shallow-compare.html), a helper function that performs a shallow comparison for props and state in a component to decide if a component should update.
The add-ons below are in the development (unminified) version of React only:

View File

@@ -6,7 +6,7 @@ prev: tooling-integration-zh-CN.html
next: animation-zh-CN.html
---
`React.addons` 是我们放置一些用来构建React apps的有用的工具的地方**这些应该被认为是实验性的** 但是最终批量进入核心代码或者一个有用的工具库中:
React插件是一系列的用来构建 React app的有用模块**这些应该被认为是实验性的** 并趋向于比core变动更频繁。
- [`TransitionGroup` 和 `CSSTransitionGroup`](animation.html), 用来处理通常不能简单实现的动画和转换,比如在组件移除之前。
- [`LinkedStateMixin`](two-way-binding-helpers.html), 简化用户的表单输入数据与组件状态的协调。
@@ -14,12 +14,11 @@ next: animation-zh-CN.html
- [`createFragment`](create-fragment.html), 创建一组外键的子级。
- [`update`](update.html), 一个使不可变数据在JavaScript里更易处理的辅助函数。
- [`PureRenderMixin`](pure-render-mixin.html), 一个特定情况下的性能优化器。
- [`shallowCompare`](shallow-compare.html), 一个辅助函数,用来对 props 和 state在组件里 执行浅比较 以决定一个组件是否应该更新。
下面的插件只存在开发版(未压缩)React中
- [`TestUtils`](test-utils.html), 用于写测试用例的简单的辅助工具(仅存在于未压缩版本)。
- [`Perf`](perf.html), 用于测量性能并给你提示哪里可以优化。
要获取插件,使用 `react-with-addons.js` (和它的压缩副本)而不是通常的 `react.js`
当从npm使用react包时简单的用`require('react/addons')` 代替 `require('react')` 来获取带有所有插件的React。
要获取插件,单独从npm安装他们(例如 `npm install react-addons-pure-render-mixin`).我们不支持使用插件如果你没有用npm.

View File

@@ -44,7 +44,7 @@ var TodoList = React.createClass({
return (
<div>
<button onClick={this.handleAdd}>Aggiungi Elemento</button>
<ReactCSSTransitionGroup transitionName="example" transitionEnterTimeout={500} transitionLeaveTimeout={300} >
<ReactCSSTransitionGroup transitionName="example" transitionEnterTimeout={500} transitionLeaveTimeout={300}>
{items}
</ReactCSSTransitionGroup>
</div>

View File

@@ -18,7 +18,7 @@ React에는 애니메이션을 위한 저 수준 API로 `ReactTransitionGroup`
`ReactCSSTransitionGroup``ReactTransitions`을 위한 인터페이스입니다. 이는 애니메이션을 제어할 모든 컴포넌트를 감싸는 하나의 엘리먼트 입니다. 아래는 목록의 아이템을 페이드 인/아웃하는 간단한 예제입니다.
```javascript{28-30}
var ReactCSSTransitionGroup = React.addons.CSSTransitionGroup;
var ReactCSSTransitionGroup = require('react-addons-css-transition-group');
var TodoList = React.createClass({
getInitialState: function() {
@@ -45,7 +45,7 @@ var TodoList = React.createClass({
return (
<div>
<button onClick={this.handleAdd}>Add Item</button>
<ReactCSSTransitionGroup transitionName="example">
<ReactCSSTransitionGroup transitionName="example" transitionEnterTimeout={500} transitionLeaveTimeout={300}>
{items}
</ReactCSSTransitionGroup>
</div>
@@ -53,9 +53,10 @@ var TodoList = React.createClass({
}
});
```
> 주의:
>
> `ReactCSSTransitionGroup`의 모든 자식은 [`key` 어트리뷰트](/react/docs/multiple-components-ko-KR.html#dynamic-children)를 반드시 만들어야 합니다. 한 아이템을 렌더한다 해도 예외는 아닙니다. 키는 React가 어떤 자식이 들어오고, 나가고, 머무르는지 파악할 때 사용합니다.
> `ReactCSSTransitionGroup`의 모든 자식은 [`key` 어트리뷰트](/react/docs/multiple-components-ko-KR.html#dynamic-children)를 반드시 만들어야 합니다. 한 아이템을 렌더할 때도 예외는 아닙니다. 키는 React가 어떤 자식이 들어오고, 나가고, 머무르는지 파악할 때 사용합니다.
이 컴포넌트에서 새로운 아이템이 `ReactCSSTransitionGroup`에 추가되면 `example-enter` 아이템은 CSS 클래스를 가지게 되고 다음 순간에 `example-enter-active` CSS 클래스가 추가됩니다. 이는 `transitionName` prop을 기반으로 한 관례입니다.
@@ -68,23 +69,21 @@ var TodoList = React.createClass({
.example-enter.example-enter-active {
opacity: 1;
transition: opacity .5s ease-in;
transition: opacity 500ms ease-in;
}
```
`ReactCSSTransitionGroup`에서 아이템을 제거하려해도 DOM에는 남게 됩니다. 만약 애드온을 React의 최소화하지 않은 빌드와 사용한다면, 애니메이션이나 트랜지션이 일어나는 것을 예상하고 있었다는 React의 경고를 보게 될 것입니다. 그게 바로 `ReactCSSTransitionGroup`가 DOM 엘리먼트를 애니메이션이 끝날 때까지 페이지에 남겨두는 이유입니다. 이 CSS를 넣어보세요.
```css
.example-leave {
opacity: 1;
}
.example-leave.example-leave-active {
opacity: 0.01;
transition: opacity .5s ease-in;
transition: opacity 300ms ease-in;
}
```
에니메이션 기간이 CSS와 렌더 메소드 양쪽에 지정될 필요가 있다는 것에 주의하셔야 합니다. 이는 엘리먼트에서 애니메이션 클래스를 제거할 때 (만약 남아있다면) DOM에서 엘리먼트를 제거할 때 React에 알려줍니다.
### 처음 마운트에서 애니메이션 하기
`ReactCSSTransitionGroup`은 컴포넌트를 처음 마운트할 때 추가 트렌지션 단계를 추가하기 위해, 선택적인 prop `transitionAppear`를 제공합니다. 일반적으로 처음 마운트할 때 트렌지션 단계를 넣지 않기 때문에 `transitionAppear`의 기본 값은 `false`입니다. 뒤의 예제는 `transitionAppear` prop에 `true` 값을 넘기고 있습니다.
@@ -92,7 +91,7 @@ var TodoList = React.createClass({
```javascript{3-5}
render: function() {
return (
<ReactCSSTransitionGroup transitionName="example" transitionAppear={true}>
<ReactCSSTransitionGroup transitionName="example" transitionAppear={true} transitionAppearTimeout={500}>
<h1>Fading at Initial Mount</h1>
</ReactCSSTransitionGroup>
);
@@ -104,11 +103,11 @@ var TodoList = React.createClass({
```css
.example-appear {
opacity: 0.01;
transition: opacity .5s ease-in;
}
.example-appear.example-appear-active {
opacity: 1;
transition: opacity .5s ease-in;
}
```
@@ -125,23 +124,23 @@ var TodoList = React.createClass({
```javascript
...
<ReactCSSTransitionGroup
transitionName={
transitionName={ {
enter: 'enter',
enterActive: 'enterActive',
leave: 'leave',
leaveActive: 'leaveActive',
appear: 'appear',
appearActive: 'appearActive'
}>
} }>
{item}
</ReactCSSTransitionGroup>
<ReactCSSTransitionGroup
transitionName={
transitionName={ {
enter: 'enter',
leave: 'leave',
appear: 'appear'
}>
} }>
{item2}
</ReactCSSTransitionGroup>
...
@@ -176,7 +175,7 @@ var TodoList = React.createClass({
위의 예제에서 `ReactCSSTransitionGroup`에 아이템 목록을 렌더했지만, `ReactCSSTransitionGroup`의 자식은 하나이거나 없을 수도 있습니다. 이는 한 엘리먼트가 들어오고 나가는 것의 애니메이션을 가능하게 합니다. 비슷하게, 현재 엘리먼트가 나가는 동안 새 앨리먼트의 애니메이션을 하면, 새 엘리먼트가 현재 엘리먼트를 교체하는 애니메이션을 만들 수 있습니다. 예를 들어 이렇게 간단한 이미지 회전 베너(carousel)를 구현할 수 있습니다.
```javascript{10-12}
var ReactCSSTransitionGroup = React.addons.CSSTransitionGroup;
var ReactCSSTransitionGroup = require('react-addons-css-transition-group');
var ImageCarousel = React.createClass({
propTypes: {
@@ -185,7 +184,7 @@ var ImageCarousel = React.createClass({
render: function() {
return (
<div>
<ReactCSSTransitionGroup transitionName="carousel">
<ReactCSSTransitionGroup transitionName="carousel" transitionEnterTimeout={300} transitionLeaveTimeout={300}>
<img src={this.props.imageSrc} key={this.props.imageSrc} />
</ReactCSSTransitionGroup>
</div>
@@ -204,7 +203,7 @@ var ImageCarousel = React.createClass({
## 저수준 API: `ReactTransitionGroup`
`ReactTransitionGroup`은 애니메이션의 기초입니다. 이는 `React.addons.TransitionGroup`으로 접근할 수 있습니다. 위에 있는 예제처럼 자식들이 선언적으로 여기에 추가되거나 삭제되는 경우, 특별한 훅이 이 생명주기에서 호출됩니다.
`ReactTransitionGroup`은 애니메이션의 기초입니다. 이는 `require('react-addons-transition-group')`으로 접근할 수 있습니다. 위 예제처럼 자식들이 선언적으로 여기에 추가되거나 삭제되는 경우, 특별한 훅이 이 생명주기에서 호출됩니다.
### `componentWillAppear(callback)`
@@ -240,11 +239,7 @@ var ImageCarousel = React.createClass({
</ReactTransitionGroup>
```
모든 React가 렌더할 수 있는 DOM 컴포넌트는 사용할 수 있습니다. 하지만 `component`가 DOM 컴포넌트일 필요는 없습니다. React 컴포넌트라면 무엇이든 넣을 수 있습니다. 직접 구현한 컴포넌트여도 됩니다!
> 주의:
>
> v0.12이전에는, DOM 컴포넌트를 사용할 때, `component` prop은 `React.DOM.*`로 참조할 필요가 있었습니다. 이제 컴포넌트가 단순히 `React.createElement`로 전달되기 때문에, `component` prop은 스트링이어야 합니다. 복합 컴포넌트는 팩토리를 넘겨야 합니다.
React가 렌더할 수 있는 DOM 컴포넌트는 전부 사용할 수 있습니다. 하지만 `component`가 DOM 컴포넌트일 필요는 없습니다. React 컴포넌트라면 무엇이든 넣을 수 있습니다. 직접 구현한 컴포넌트여도 됩니다! 그냥 `component={List}`를 적으면 컴포넌트는 `this.props.children`로 받을 수 있습니다.
사용자 정의를 포함한 어떤 프로퍼티도 렌더된 컴포넌트의 프로퍼티가 됩니다. 예를 들어, `<ul>`에 CSS 클래스를 넣어서 렌더하려면 이렇게 하면 됩니다.

View File

@@ -29,7 +29,7 @@ var TodoList = React.createClass({
this.setState({items: newItems});
},
handleRemove: function(i) {
var newItems = this.state.items;
var newItems = this.state.items.slice();
newItems.splice(i, 1);
this.setState({items: newItems});
},
@@ -44,7 +44,7 @@ var TodoList = React.createClass({
return (
<div>
<button onClick={this.handleAdd}>Add Item</button>
<ReactCSSTransitionGroup transitionName="example" transitionEnterTimeout={500} transitionLeaveTimeout={300} >
<ReactCSSTransitionGroup transitionName="example" transitionEnterTimeout={500} transitionLeaveTimeout={300}>
{items}
</ReactCSSTransitionGroup>
</div>

View File

@@ -17,7 +17,7 @@ React 提供了一个 `ReactTransitionGroup` 插件作为动画的底层API,和
`ReactCSSTransitionGroup``ReactTransitions` 的接口。这是一个简单的元素,包裹了所有你感兴趣的动画组件。这里是一个淡入和淡出列表项目的例子。
```javascript{28-30}
var ReactCSSTransitionGroup = React.addons.CSSTransitionGroup;
var ReactCSSTransitionGroup = require('react-addons-css-transition-group');
var TodoList = React.createClass({
getInitialState: function() {
@@ -29,7 +29,7 @@ var TodoList = React.createClass({
this.setState({items: newItems});
},
handleRemove: function(i) {
var newItems = this.state.items;
var newItems = this.state.items.slice();
newItems.splice(i, 1);
this.setState({items: newItems});
},
@@ -44,7 +44,7 @@ var TodoList = React.createClass({
return (
<div>
<button onClick={this.handleAdd}>Add Item</button>
<ReactCSSTransitionGroup transitionName="example" transitionEnterTimeout={500} transitionLeaveTimeout={300} >
<ReactCSSTransitionGroup transitionName="example" transitionEnterTimeout={500} transitionLeaveTimeout={300}>
{items}
</ReactCSSTransitionGroup>
</div>
@@ -101,11 +101,11 @@ var TodoList = React.createClass({
```css
.example-appear {
opacity: 0.01;
transition: opacity .5s ease-in;
}
.example-appear.example-appear-active {
opacity: 1;
transition: opacity .5s ease-in;
}
```
@@ -173,7 +173,7 @@ var TodoList = React.createClass({
在上面的例子中,我们渲染了一系列的项目到`ReactCSSTransitionGroup`里。然而 `ReactCSSTransitionGroup` 的子级同样可以是一个或零个项目。这使它能够动画化单个元素的进入和离开。同样,你可以动画化一个新的元素替换当前元素。例如,我们可以像这样实现一个简单的图片轮播器:
```javascript{10-12}
var ReactCSSTransitionGroup = React.addons.CSSTransitionGroup;
var ReactCSSTransitionGroup = require('react-addons-css-transition-group');
var ImageCarousel = React.createClass({
propTypes: {
@@ -201,7 +201,7 @@ var ImageCarousel = React.createClass({
## 底层 API: `ReactTransitionGroup`
`ReactTransitionGroup`是动画的基础。它通过 `React.addons.TransitionGroup` 访问。当子级被声明式的从其中添加或移除(就像上面的例子)时,特殊的生命周期挂钩会在它们上面被调用。
`ReactTransitionGroup`是动画的基础。它通过 `require('react-addons-transition-group')` 访问。当子级被声明式的从其中添加或移除(就像上面的例子)时,特殊的生命周期挂钩会在它们上面被调用。
### `componentWillAppear(callback)`
@@ -237,11 +237,8 @@ var ImageCarousel = React.createClass({
</ReactTransitionGroup>
```
每一个React能渲染的DOM组件都是可用的。然而`组件`不需要是一个DOM组件。它可以是任何你想要的React组件甚至是你自己已经写好的
每一个React能渲染的DOM组件都是可用的。然而`组件`不需要是一个DOM组件。它可以是任何你想要的React组件甚至是你自己已经写好的只要写 `component={List}` 你的组件会收到 `this.props.children`
> 注意:
>
> v0.12之前当使用DOM组件时`组件` prop 需要是一个对`React.DOM.*`的引用。既然组件简单的被传递到 `React.createElement`它现在必然是一个字符串。复合组件必须传递工厂函数factory
任何额外的、用户定义的属性将会成为已渲染的组件的属性。例如以下是你将如何渲染一个带有css类的 `<ul>`

View File

@@ -0,0 +1,32 @@
---
id: shallow-compare
title: Shallow Compare
permalink: shallow-compare.html
prev: perf.html
next: advanced-performance.html
---
`shallowCompare` is a helper function to achieve the same functionality as `PureRenderMixin` while using ES6 classes with React.
If your React component's render function is "pure" (in other words, it renders the same result given the same props and state), you can use this helper function for a performance boost in some cases.
Example:
```js
var shallowCompare = require('react-addons-shallow-compare');
export class SampleComponent extends React.Component {
shouldComponentUpdate(nextProps, nextState) {
return shallowCompare(this, nextProps, nextState);
}
render() {
return <div className={this.props.className}>foo</div>;
}
}
```
`shallowCompare` performs a shallow equality check on the current `props` and `nextProps` objects as well as the current `state` and `nextState` objects.
It does this by iterating on the keys of the objects being compared and returning false when the value of a key in each object are not strictly equal.
`shallowCompare` returns `true` if the shallow comparison for props or state fails and therefore the component should update.
`shallowCompare` returns `false` if the shallow comparison for props and state both pass and therefore the component does not need to update.

View File

@@ -45,9 +45,11 @@ var NoLink = React.createClass({
이것은 정말 잘 동작하고, 데이터가 어떻게 흐르는지 매우 명확하게 보여지지만, 폼필드가 많을 경우 약간 장황해 질 수 있습니다. 타이핑을 줄이기 위해 `ReactLink`를 사용해 보겠습니다.
```javascript{2,7}
```javascript{4,9}
var LinkedStateMixin = require('react-addons-linked-state-mixin');
var WithLink = React.createClass({
mixins: [React.addons.LinkedStateMixin],
mixins: [LinkedStateMixin],
getInitialState: function() {
return {message: 'Hello!'};
},
@@ -66,7 +68,6 @@ checkbox의 `value` 어트리뷰트는 다른 것과 다르게 checkbox가 체
<input type="checkbox" checkedLink={this.linkState('booleanValue')} />
```
## 내부 구조
`ReactLink`에는 크게 인스턴스를 생성하는 면과 사용하는 면이 있습니다. `ReactLink`가 얼마나 간단한지 확인하기 위해, 이 부분들을 보다 명시적으로 고쳐 봅시다.
@@ -96,8 +97,10 @@ var WithoutMixin = React.createClass({
### valueLink 없이 ReactLink 쓰기
```javascript
var LinkedStateMixin = require('react-addons-linked-state-mixin');
var WithoutLink = React.createClass({
mixins: [React.addons.LinkedStateMixin],
mixins: [LinkedStateMixin],
getInitialState: function() {
return {message: 'Hello!'};
},

View File

@@ -8,7 +8,7 @@ next: test-utils-ko-KR.html
> 주의:
>
> 이 모듈은 이제 [JedWatson/classnames](https://github.com/JedWatson/classnames)에 독립적으로 있고 React와 관련없습니다. 그러므로 이 애드온은 제거될 예정입니다.
> 이 모듈은 폐기예정입니다. 대신 [JedWatson/classnames](https://github.com/JedWatson/classnames)를 사용하세요.
`classSet()`은 간단히 DOM `class` 문자열을 조작하는 편리한 도구입니다.

View File

@@ -6,39 +6,66 @@ prev: two-way-binding-helpers-ko-KR.html
next: clone-with-props-ko-KR.html
---
`React.addons.TestUtils`는 선택한 테스트 프레임워크(React는 [Jest](https://facebook.github.io/jest/)를 사용)에서 React 컴포넌트를 테스트하기 쉽게 합니다.
`ReactTestUtils`는 선택한 테스트 프레임워크(React는 [Jest](https://facebook.github.io/jest/)를 사용)에서 React 컴포넌트를 테스트하기 쉽게 합니다.
```
var ReactTestUtils = require('react-addons-test-utils');
```
### Simulate
```javascript
Simulate.{eventName}(DOMElement element, object eventData)
Simulate.{eventName}(
DOMElement element,
[object eventData]
)
```
DOM 노드에 이벤트 디스패치하는 것을 시뮬레이트합니다. 선택적으로 `eventData`를 통해 이벤트 데이터도 처리할 수 있습니다. **아마 `ReactTestUtils`에서 가장 유용한 유틸리티일 것 입니다.**
사용 예:
**엘리먼트 클릭**
```javascript
var node = ReactDOM.findDOMNode(this.refs.input);
React.addons.TestUtils.Simulate.click(node);
React.addons.TestUtils.Simulate.change(node, {target: {value: 'Hello, world'}});
React.addons.TestUtils.Simulate.keyDown(node, {key: "Enter"});
// <button ref="button">...</button>
var node = this.refs.button;
ReactTestUtils.Simulate.click(node);
```
**입력 필드의 값을 변경하고 엔터 누르기.**
```javascript
// <input ref="input" />
var node = this.refs.input;
node.value = 'giraffe'
ReactTestUtils.Simulate.change(node);
ReactTestUtils.Simulate.keyDown(node, {key: "Enter", keyCode: 13, which: 13});
```
*컴포넌트에서 사용할 이벤트 프로퍼티(예를 들어 keyCode, which, 등등...)는 React에서 만들어 주지 않으므로 직접 제공해야 합니다.*
`Simulate`에는 React가 이해하는 모든 이벤트에 대해 메소드가 있습니다.
### renderIntoDocument
```javascript
ReactComponent renderIntoDocument(ReactElement instance)
ReactComponent renderIntoDocument(
ReactElement instance
)
```
문서의 detach된 DOM 노드에 컴포넌트를 렌더합니다. **이 기능은 DOM을 필요로 합니다.**
> 주의:
>
> React를 임포트하기 **전에** `window`, `window.document`, `window.document.createElement`을 전역적으로 사용가능하게 해두어야 합니다. 아니면 React는 DOM과 `setState`같은 메소드가 동작하지 않는다고 생각할 수 있습니다.
### mockComponent
```javascript
object mockComponent(function componentClass, string? mockTagName)
object mockComponent(
function componentClass,
[string mockTagName]
)
```
목 컴포넌트 모듈을 이 메소드에 넘겨 더미 React 컴포넌트로 사용할 수 있도록 합니다. 이 더미는 유용한 메소드와 함께 사용해 기능을 보강할 수 있습니다. 일반적인 렌더링과는 다르게, 컴포넌트는 제공된 자식을 포함하는 평범한 `<div>`가 됩니다. (`mockTagName`을 통해 div가 아닌 다른 태그를 지정해 줄 수도 있습니다.)
@@ -46,7 +73,9 @@ object mockComponent(function componentClass, string? mockTagName)
### isElement
```javascript
boolean isElement(ReactElement element)
boolean isElement(
ReactElement element
)
```
`element`가 ReactElement면 `true`를 리턴합니다.
@@ -54,7 +83,10 @@ boolean isElement(ReactElement element)
### isElementOfType
```javascript
boolean isElementOfType(ReactElement element, function componentClass)
boolean isElementOfType(
ReactElement element,
function componentClass
)
```
`element`가 React `componentClass` 타입인 ReactElement면 `true`를 리턴합니다.
@@ -62,7 +94,9 @@ boolean isElementOfType(ReactElement element, function componentClass)
### isDOMComponent
```javascript
boolean isDOMComponent(ReactComponent instance)
boolean isDOMComponent(
ReactComponent instance
)
```
`instance`가 (`<div>``<span>`같은) DOM 컴포넌트면 `true`를 리턴합니다.
@@ -78,7 +112,10 @@ boolean isCompositeComponent(ReactComponent instance)`
### isCompositeComponentWithType
```javascript
boolean isCompositeComponentWithType(ReactComponent instance, function componentClass)
boolean isCompositeComponentWithType(
ReactComponent instance,
function componentClass
)
```
`instance`가 (`React.createClass()`로 생성된) 복합 컴포넌트고 React `componentClass` 타입이면 `true`를 리턴합니다.
@@ -86,7 +123,10 @@ boolean isCompositeComponentWithType(ReactComponent instance, function component
### findAllInRenderedTree
```javascript
array findAllInRenderedTree(ReactComponent tree, function test)
array findAllInRenderedTree(
ReactComponent tree,
function test
)
```
`tree`안의 모든 컴포넌트에서 `test(component)``true`인 모든 컴포넌트를 모읍니다. 이것만으로는 그렇게 유용하지 않습니다만, 다른 테스트 유틸와 같이 사용합니다.
@@ -94,7 +134,9 @@ array findAllInRenderedTree(ReactComponent tree, function test)
### scryRenderedDOMComponentsWithClass
```javascript
array scryRenderedDOMComponentsWithClass(ReactComponent tree, string className)
array scryRenderedDOMComponentsWithClass(
ReactComponent tree, string className
)
```
렌더된 트리의 모든 컴포넌트 인스턴스 중에서 클래스 이름이 `className`인 DOM 컴포넌트들을 찾습니다.
@@ -109,7 +151,10 @@ ReactComponent findRenderedDOMComponentWithClass(ReactComponent tree, string cla
### scryRenderedDOMComponentsWithTag
```javascript
array scryRenderedDOMComponentsWithTag(ReactComponent tree, string tagName)
array scryRenderedDOMComponentsWithTag(
ReactComponent tree,
string tagName
)
```
렌더된 트리의 모든 컴포넌트 인스턴스중에서 태그 이름이 `tagName`인 DOM 컴포넌트들을 찾습니다.
@@ -117,7 +162,10 @@ array scryRenderedDOMComponentsWithTag(ReactComponent tree, string tagName)
### findRenderedDOMComponentWithTag
```javascript
ReactComponent findRenderedDOMComponentWithTag(ReactComponent tree, string tagName)
ReactComponent findRenderedDOMComponentWithTag(
ReactComponent tree,
string tagName
)
```
`scryRenderedDOMComponentsWithTag()`와 비슷하지만 하나의 결과만 기대될 때 사용합니다. 하나의 결과를 리턴하거나 한개 이상의 결과가 나온 경우에는 예외를 던집니다.
@@ -125,7 +173,10 @@ ReactComponent findRenderedDOMComponentWithTag(ReactComponent tree, string tagNa
### scryRenderedComponentsWithType
```javascript
array scryRenderedComponentsWithType(ReactComponent tree, function componentClass)
array scryRenderedComponentsWithType(
ReactComponent tree,
function componentClass
)
```
타입이 `componentClass`인 모든 컴포넌트 인스턴스를 찾습니다.
@@ -133,7 +184,9 @@ array scryRenderedComponentsWithType(ReactComponent tree, function componentClas
### findRenderedComponentWithType
```javascript
ReactComponent findRenderedComponentWithType(ReactComponent tree, function componentClass)
ReactComponent findRenderedComponentWithType(
ReactComponent tree, function componentClass
)
```
`scryRenderedComponentsWithType()`와 비슷하지만 하나의 결과만 기대될 때 사용합니다. 하나의 결과를 리턴하거나 한개 이상의 결과가 나온 경우에는 예외를 던집니다.
@@ -149,13 +202,15 @@ ReactShallowRenderer createRenderer()
테스트에서 얕은 렌더러를 생성하고자 할때 호출합니다. 이를 이벤트와 업데이트에 스스로 반응하는 컴포넌트를 렌더하기 위한 "장소"라고 생각할 수 있습니다.
```javascript
shallowRenderer.render(ReactElement element)
shallowRenderer.render(
ReactElement element
)
```
`ReactDOM.render`와 유사합니다.
```javascript
ReactComponent shallowRenderer.getRenderOutput()
ReactElement shallowRenderer.getRenderOutput()
```
`render`가 호출 된 후, 얕게 렌더된 결과물을 반환합니다. 그 후엔 결과물에 대한 검증을 시작할 수 있습니다. 예를 들어 컴포넌트의 렌더 메소드가 다음을 반환한다면:

View File

@@ -217,7 +217,7 @@ shallowRenderer.render(
Similar to `ReactDOM.render`.
```javascript
ReactComponent shallowRenderer.getRenderOutput()
ReactElement shallowRenderer.getRenderOutput()
```
After `render` has been called, returns shallowly rendered output. You can then begin to assert facts about the output. For example, if your component's render method returns:

View File

@@ -12,8 +12,10 @@ next: create-fragment-ko-KR.html
드문 경우긴 하지만 원래 엘리먼트와 다른 prop을 가진 React 엘리먼트의 복사본을 만들고 싶을 때가 있습니다. 예를 들면 `this.props.children`에 클론한 엘리먼트를 넘기고 다른 prop으로 렌더링하는 경우 입니다.
```js
var cloneWithProps = require('react-addons-clone-with-props');
var _makeBlue = function(element) {
return React.addons.cloneWithProps(element, {style: {color: 'blue'}});
return cloneWithProps(element, {style: {color: 'blue'}});
};
var Blue = React.createClass({

View File

@@ -18,7 +18,7 @@ var Swapper = React.createClass({
rightChildren: React.PropTypes.node,
swapped: React.PropTypes.bool
}
},
render: function() {
var children;
if (this.props.swapped) {
@@ -33,20 +33,22 @@ var Swapper = React.createClass({
`swapped` prop을 변경할 경우 자식은 마운트 해제되거나 다시 마운트 될 수 있습니다. 두 자식 집합에 키가 할당되지 않았기 때문입니다.
이 문제를 해결하기 위해서 `React.addons.createFragment`를 사용해 자식 집합에 키를 부여할 수 있습니다.
이 문제를 해결하기 위해서 `createFragment`를 사용해 자식 집합에 키를 부여할 수 있습니다.
#### `ReactFragment React.addons.createFragment(object children)`
#### `Array<ReactNode> createFragment(object children)`
배열을 만드는 대신에 다음과 같이 해볼 수 있습니다:
```js
var createFragment = require('react-addons-create-fragment');
if (this.props.swapped) {
children = React.addons.createFragment({
children = createFragment({
right: this.props.rightChildren,
left: this.props.leftChildren
});
} else {
children = React.addons.createFragment({
children = createFragment({
left: this.props.leftChildren,
right: this.props.rightChildren
});

View File

@@ -44,7 +44,9 @@ var newData = extend(myData, {
`update()`는 이런 패턴 속에서 코드를 더 쉽게 쓸 수 있도록 편의 문법을 제공합니다. 코드는 이렇습니다:
```js
var newData = React.addons.update(myData, {
var update = require('react-addons-update');
var newData = update(myData, {
x: {y: {z: {$set: 7}}},
a: {b: {$push: [9]}}
});

View File

@@ -11,7 +11,7 @@ React 컴포넌트의 렌더 함수가 "pure"하다면 (다른 말로, props나
예제:
```js
var PureRenderMixin = require('react/addons').addons.PureRenderMixin;
var PureRenderMixin = require('react-addons-pure-render-mixin');
React.createClass({
mixins: [PureRenderMixin],

View File

@@ -16,11 +16,13 @@ React는 보통 처음에는 꽤 빠릅니다. 하지만 모든 성능을 짜내
## 일반 API
여기에서 설명하는 `Perf` 객체는 `react-with-addons.js`를 사용해 개발 모드에서 빌드될 때 `React.addons.Perf`로 노출됩니다.
여기에서 설명하는 `Perf` 객체는 `require('react-addons-perf')`로 노출되고 React 개발 모드에서만 사용할 수 있습니다. 이 번들을 프로덕션에서 앱과 같이 빌드하시면 안됩니다.
### `Perf.start()`와 `Perf.stop()`
측정을 시작/정지합니다. 그 사이의 React 연산은 밑에 있는 분석을 하기위해 기록됩니다. 미미한 양의 연산은 무시됩니다.
종료 후, 측정을 하기위해서는 이후에 설명할 `Perf.getLastMeasurements()`가 필요합니다.
### `Perf.printInclusive(measurements)`
전 수행 시간을 출력합니다. 인자가 넘겨지지 않으면, 기본값은 지난 기록부터의 모든 측정이 됩니다. 이 출력은 밑에 있는 것처럼 콘솔에서 깔끔한 테이블로 그려집니다.

View File

@@ -3,7 +3,7 @@ id: perf
title: Performance Tools
permalink: perf.html
prev: pure-render-mixin.html
next: advanced-performance.html
next: shallow-compare.html
---
React is usually quite fast out of the box. However, in situations where you need to squeeze every ounce of performance out of your app, it provides a [shouldComponentUpdate](/react/docs/component-specs.html#updating-shouldcomponentupdate) hook where you can add optimization hints to React's diff algorithm.

View File

@@ -3,6 +3,7 @@ id: advanced-performance-ko-KR
title: 성능 심화
permalink: advanced-performance-ko-KR.html
prev: perf-ko-KR.html
next: context-ko-KR.html
---
React를 도입하려 할 때 많은 사람이 묻는 첫 번째 질문은 React를 사용하지 않을 때처럼 애플리케이션이 빠르고 반응성도 좋을 것이냐는 것입니다. 모든 상태변화에 대해 컴포넌트의 하위 트리를 전부 다시 렌더링하는 아이디어에 대해 사람들은 이 프로세스가 성능에 부정적인 영향을 줄 것으로 생각하지만, React는 여러 가지 영리한 방법을 통해 UI를 업데이트하는데 필요한 비싼 DOM 조작을 최소화합니다.
@@ -52,7 +53,7 @@ React.createClass({
},
render: function() {
return <div>this.props.value</div>;
return <div>{this.props.value}</div>;
}
});
```
@@ -76,7 +77,7 @@ React.createClass({
},
render: function() {
return <div>this.props.value.foo</div>;
return <div>{this.props.value.foo}</div>;
}
});
```

View File

@@ -2,7 +2,7 @@
id: advanced-performance
title: Advanced Performance
permalink: advanced-performance.html
prev: perf.html
prev: shallow-compare.html
next: context.html
---

View File

@@ -0,0 +1,174 @@
---
id: context
title: 컨텍스트
permalink: context-ko-KR.html
prev: advanced-performance-ko-KR.html
---
React의 가장 큰 장점 중 하나는 React 컴포넌트를 통해 데이터의 흐름을 추적하기 쉽다는 것입니다. 컴포넌트를 보면 각각의 프로퍼티가 어떻게 전달되었는지 쉽게 파악할 수 있습니다.
때때로 컴포넌트 트리를 통해 props을 전단하는 대신 수동으로 모든 레벨에서 데이터를 전달하고 싶은 경우가 있습니다. React의 "컨텍스트" 기능은 이를 가능하게 해줍니다.
> 주의:
>
> 컨텍스트는 실험적인 고급 기능입니다. 향후 릴리즈에서 API가 변경될 수 있습니다.
>
> 대부분은 애플리켄이션은 컨텍스트가 필요하지 않을겁니다. 특히 React로 시작한 경우에는 컨텍스트를 사용하지 않을겁니다. 컨텍스트의 사용은 데이터 흐름을 명확하지 않게 만들기 때문에 코드를 이해하기 어려워 집니다. 이는 마치 앱에서 전역 변수를 state로 전달하는 경우와 유사합니다.
>
> **만약 컨텍스트를 사용해야 하는 경우에도, 가능한 아껴 사용하세요.**
>
> 구축하는것이 애플리케이션이든 라이브러리든간에, 가능한 컨텍스트의 사용은 작은 영역으로 격리하고 직접적으로 컨텍스트 API를 사용하는 것을 피하세요. 그렇게 하면 API가 변경 되더라도 쉽게 업데이트 할 수 있습니다.
## 트리를 통해 정보를 자동으로 전달하기
아래와 같은 구조가 있다고 가정해 봅시다:
```javascript
var Button = React.createClass({
render: function() {
return (
<button style={{'{{'}}background: this.props.color}}>
{this.props.children}
</button>
);
}
});
var Message = React.createClass({
render: function() {
return (
<div>
{this.props.text} <Button color={this.props.color}>삭제</Button>
</div>
);
}
});
var MessageList = React.createClass({
render: function() {
var color = "purple";
var children = this.props.messages.map(function(message) {
return <Message text={message.text} color={color} />;
});
return <div>{children}</div>;
}
});
```
이 예제에서, 우리는 스타일을 주기 위해 수동으로 적절하게 `Button``Messages` 컴포넌트에 `color` 프로퍼티를 엮어서 전달했습니다. 테마는 서브트리가 정보 조각의 일부(여기선 color)에 접근하기 원하는 좋은 예제입니다. 컨텍스트를 사용하면 우리는 이를 자동으로 트리로 전달할 수 있습니다:
```javascript{2-4,7,18,25-30,33}
var Button = React.createClass({
contextTypes: {
color: React.PropTypes.string
},
render: function() {
return (
<button style={{'{{'}}background: this.context.color}}>
{this.props.children}
</button>
);
}
});
var Message = React.createClass({
render: function() {
return (
<div>
{this.props.text} <Button>Delete</Button>
</div>
);
}
});
var MessageList = React.createClass({
childContextTypes: {
color: React.PropTypes.string
},
getChildContext: function() {
return {color: "purple"};
},
render: function() {
var children = this.props.messages.map(function(message) {
return <Message text={message.text} />;
});
return <div>{children}</div>;
}
});
```
`childContextTypes`와 `getChildContext`를 `MessageList`(context provider)에 추가함으로써, React는 정보를 자동으로 아래로 전달하며 서브트리내의 어떤 컴포넌트든 (여기선 `Button`) `contextTypes`를 정의함으로써 이에 접근할 수 있습니다.
`contextTypes`가 정의되지 않은 경우, `this.context`는 빈 오브젝트가 됩니다.
## 부모-자식 커플링
컨텍스트는 다음과 같은 API를 구성할 수 있게 해줍니다:
```javascript
<Menu>
<MenuItem>가지</MenuItem>
<MenuItem>땅콩호박</MenuItem>
<MenuItem>클레멘타인</MenuItem>
</Menu>
```
`Menu` 컴포넌트에서 관련 정보를 전달함으로써 각각의 `MenuItem`가 부모인 `Menu` 컴포넌트와 통신할 수 있습니다.
**이 API를 이용해 컴포넌트를 구성하기 전에, 깔끔한 대안이 있는지 먼저 고려해 보세요.** 다음과 같이 간단히 아이템을 배열로 넘겨 보겠습니다:
```javascript
<Menu items={['가지', '땅콩호박', '클레멘타인']} />
```
원한다면 전체 React 컴포넌트를 프로퍼티로 전달할 수도 있습니다.
## Referencing context in lifecycle methods
If `contextTypes` is defined within a component, the following lifecycle methods will receive an additional parameter, the `context` object:
```javascript
void componentWillReceiveProps(
object nextProps, object nextContext
)
boolean shouldComponentUpdate(
object nextProps, object nextState, object nextContext
)
void componentWillUpdate(
object nextProps, object nextState, object nextContext
)
void componentDidUpdate(
object prevProps, object prevState, object prevContext
)
```
## Referencing context in stateless functional components
Stateless functional components are also able to reference `context` if `contextTypes` is defined as a property of the function. The following code shows the `Button` component above written as a stateless functional component.
```javascript
function Button(props, context) {
return (
<button style={{'{{'}}background: context.color}}>
{props.children}
</button>
);
}
Button.contextTypes = {color: React.PropTypes.string};
```
## 컨텍스트를 사용하지 말아야 하는 경우
대부분의 경우, 깔끔한 코드를 위해 전역 변수를 피하는 것과 마찬가지로 컨텍스트의 사용을 피해야 합니다. 특히 "타이핑을 줄이거나" 명시적인 프로퍼티 전달 대신 이를 사용하려는 경우 다시 한번 생각해 보세요.
컨텍스트의 가장 적절한 사용 사례는 로그인한 유저, 언어 설정, 테마 정보 등을 암시적으로 전달하는 것입니다. 컨텍스트를 사용함으로써 이런 정보들을 전역으로 다루는 대신 단일 React 서브트리 내에서 다룰 수 있습니다.
모델 데이터를 컴포넌트로 전달하는데 컨텍스트를 사용하지 마세요. 트리를 통해 명시적으로 데이터를 엮어 전달하는 것이 훨씬 이해하기 쉽습니다. 컨텍스트는 렌더되는 위치에 따라 다르게 작동하기 때문에 컴포넌트를 더욱 연결되고(coupled) 재사용성이 떨어지게 만듭니다.
## 알려진 한계점
컴포넌트에 의해 제공되는 컨텍스트의 값이 변경될 때, 중간 부모가 `shouldComponentUpdate`에서`false`을 반환한다면 그 값을 사용하는 자손은 업데이트되지 않습니다. 자세한 내용은 [#2517](https://github.com/facebook/react/issues/2517) 이슈를 확인하세요.

View File

@@ -123,6 +123,43 @@ By passing down the relevant info in the `Menu` component, each `MenuItem` can c
Recall that you can also pass entire React components in props if you'd like to.
## Referencing context in lifecycle methods
If `contextTypes` is defined within a component, the following lifecycle methods will receive an additional parameter, the `context` object:
```javascript
void componentWillReceiveProps(
object nextProps, object nextContext
)
boolean shouldComponentUpdate(
object nextProps, object nextState, object nextContext
)
void componentWillUpdate(
object nextProps, object nextState, object nextContext
)
void componentDidUpdate(
object prevProps, object prevState, object prevContext
)
```
## Referencing context in stateless functional components
Stateless functional components are also able to reference `context` if `contextTypes` is defined as a property of the function. The following code shows the `Button` component above written as a stateless functional component.
```javascript
function Button(props, context) {
return (
<button style={{'{{'}}background: context.color}}>
{props.children}
</button>
);
}
Button.contextTypes = {color: React.PropTypes.string};
```
## When not to use context
Just as global variables are best avoided when writing clear code, you should avoid using context in most cases. In particular, think twice before using it to "save typing" and using it instead of passing explicit props.

View File

@@ -17,3 +17,13 @@ January 28 & 29
July 2 & 3
[Website](http://www.react-europe.org/) - [Schedule](http://www.react-europe.org/#schedule)
### Reactive 2015
November 2-4
[Website](https://reactive2015.com/) - [Schedule](https://reactive2015.com/schedule_speakers.html#schedule)
### ReactEurope 2016
June 2 & 3
[Website](http://www.react-europe.org/) - [Schedule](http://www.react-europe.org/#schedule)

View File

@@ -13,13 +13,39 @@ React를 시작하는 가장 빠른 방법은 다음의 Hello World JSFiddle 예
* **[React JSFiddle](https://jsfiddle.net/reactjs/69z2wepo/)**
* [React JSFiddle without JSX](https://jsfiddle.net/reactjs/5vjqabv3/)
## 초심자용 키트
## npm으로 React 사용하기
초심자용 키트를 내려받아 시작합니다.
[browserify](http://browserify.org/), [webpack](https://webpack.github.io/) 같은 CommonJS 모듈 시스템과 함께 React를 사용하시는 것을 권장합니다. [`react`](https://www.npmjs.com/package/react), [`react-dom`](https://www.npmjs.com/package/react-dom) npm 패키지를 사용하세요.
```js
// main.js
var React = require('react');
var ReactDOM = require('react-dom');
ReactDOM.render(
<h1>Hello, world!</h1>,
document.getElementById('example')
);
```
browserify를 설치한 후에 React DOM을 설치하고 bundle을 빌드합니다.
```sh
$ npm install --save react react-dom babelify babel-preset-react
$ browserify -t [ babelify --presets [ react ] ] main.js -o bundle.js
```
> 주의:
>
> ES2015를 사용하고 있다면, `babel-preset-es2015` 패키지도 설치할 필요가 있습니다.
## npm 없이 Quick Start 하기
만약 당신이 npm을 사용할 준비가 아직 안되었다면, 미리빌드된 React와 React DOM 파일이 포함된 초심자용 키트를 다운로드 받을 수 있습니다.
<div class="buttons-unit downloads">
<a href="/react/downloads/react-{{site.react_version}}.zip" class="button">
초심자용 키트 내려받기 {{site.react_version}}
초심자용 키트 내려받기 {{site.react_version}}
</a>
</div>
@@ -32,6 +58,7 @@ React를 시작하는 가장 빠른 방법은 다음의 Hello World JSFiddle 예
<meta charset="UTF-8" />
<title>Hello React!</title>
<script src="build/react.js"></script>
<script src="build/react-dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script>
</head>
<body>
@@ -46,7 +73,7 @@ React를 시작하는 가장 빠른 방법은 다음의 Hello World JSFiddle 예
</html>
```
JavaScript 안에 보이는 XML 구문은 JSX라고 합니다; 더 자세한 내용은 [JSX syntax](/react/docs/jsx-in-depth-ko-KR.html)을 확인하세요. 일반적인 JavaScript로 번역하기 위해 `<script type="text/jsx">`를 사용하고 `JSXTransformer.js` 포함하는 것으로 실제로 브라우저에서 변환작업을 수행합니다.
JavaScript 안에 보이는 XML 구문은 JSX라고 합니다; 더 자세한 내용은 [JSX syntax](/react/docs/jsx-in-depth-ko-KR.html)을 확인하세요. 일반적인 JavaScript로 번역하기 위해 `<script type="text/babel">`를 사용하고 Babel을 포함하는 것으로 실제로 브라우저에서 변환작업을 수행합니다.
### 파일의 분리
@@ -69,19 +96,24 @@ ReactDOM.render(
### 오프라인 변환
먼저 커맨드라인 도구를 설치합니다. ([npm](https://www.npmjs.com/) 필요):
먼저 [Babel](http://babeljs.io/) 커맨드라인 도구를 설치합니다. ([npm](https://www.npmjs.com/) 필요):
```
npm install -g react-tools
npm install --global babel-cli
npm install babel-preset-react
```
그다음, `src/helloworld.js` 파일을 일반 JavaScript 파일로 변환합니다:
```
jsx --watch src/ build/
babel --presets react src --watch --out-dir build
```
수정할 때마다 `build/helloworld.js` 파일이 자동생성됩니다.
> 주의:
>
> ES2015를 사용하고 있다면, `babel-preset-es2015` 패키지도 설치할 필요가 있습니다.
수정할 때마다 `build/helloworld.js` 파일이 자동생성됩니다. 더 자세한 사용법은 [Babel CLI 문서](http://babeljs.io/docs/usage/cli/)를 읽어보세요.
```javascript{2}
ReactDOM.render(
@@ -92,14 +124,15 @@ ReactDOM.render(
아래의 내용대로 HTML 파일을 업데이트합니다:
```html{7,11}
```html{8,12}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Hello React!</title>
<script src="build/react.js"></script>
<!-- Babel는 이제 불필요합니다! -->
<script src="build/react-dom.js"></script>
<!-- Babel은 이제 불필요합니다! -->
</head>
<body>
<div id="example"></div>
@@ -108,10 +141,6 @@ ReactDOM.render(
</html>
```
## CommonJS를 원하시나요?
만약 React를 [browserify](http://browserify.org/), [webpack](https://webpack.github.io/)이나 기타 CommonJS와 호환되는 모듈시스템과 함께 사용하고 싶다면, [`react` npm 패키지](https://www.npmjs.com/package/react)를 사용하세요. 그 외에도 `jsx` 빌드툴은 아주 쉽게 CommonJS 외에도 대부분의 패키징 시스템에 통합될 수 있습니다.
## 다음 단계로
더 알아보려면 [튜토리얼](/react/docs/tutorial-ko-KR.html)과 초심자용 키트의 `examples` 디렉터리에서 다른 예제들을 확인해 보세요.

View File

@@ -27,13 +27,25 @@ ReactDOM.render(
);
```
To install React DOM and build your bundle after installing browserify:
To install React DOM and build your bundle with browserify:
```sh
$ npm install --save react react-dom
$ browserify -t babelify main.js -o bundle.js
$ npm install --save react react-dom babelify babel-preset-react
$ browserify -t [ babelify --presets [ react ] ] main.js -o bundle.js
```
To install React DOM and build your bundle with webpack:
```sh
$ npm install --save react react-dom babel-preset-react
$ webpack
```
> Note:
>
> If you are using ES2015, you will want to also use the `babel-preset-es2015` package.
## Quick Start Without npm
If you're not ready to use npm yet, you can download the starter kit which includes prebuilt copies of React and React DOM.
@@ -94,16 +106,20 @@ Note that some browsers (Chrome, e.g.) will fail to load the file unless it's se
First install the [Babel](http://babeljs.io/) command-line tools (requires [npm](https://www.npmjs.com/)):
```
npm install --global babel
npm install --global babel-cli
npm install babel-preset-react
```
Then, translate your `src/helloworld.js` file to plain JavaScript:
```
babel src --watch --out-dir build
babel --presets react src --watch --out-dir build
```
> Note:
>
> If you are using ES2015, you will want to also use the `babel-preset-es2015` package.
The file `build/helloworld.js` is autogenerated whenever you make a change. Read the [Babel CLI documentation](http://babeljs.io/docs/usage/cli/) for more advanced usage.
```javascript{2}

View File

@@ -68,6 +68,73 @@ factoryFunction createFactory(
주어진 타입의 ReactElement를 만들어주는 함수를 리턴합니다. `React.createElement`와 마찬가지로 `type` 인자는 HTML 태그명 문자열 (예: 'div', 'span' 등) 또는 `ReactClass`입니다.
### React.isValidElement
```javascript
boolean isValidElement(* object)
```
주어진 객체가 ReactElement인지 확인합니다.
### React.DOM
`React.DOM`은 DOM 컴포넌트에 대해 `React.createElement`의 편의 래퍼(wrapper)를 제공합니다. JSX를 사용하지 않는 경우에만 사용하십시오. 예를 들어, `React.DOM.div(null, 'Hello World!')`와 같이 사용할 수 있습니다.
### React.PropTypes
`React.PropTypes`는 컴포넌트에 넘어오는 props가 올바른지 검사할 수 있는 컴포넌트의 `propTypes` 객체에 들어가는 타입을 가집니다. `propTypes`에 대한 자세한 정보는 [재사용 가능한 컴포넌트](/react/docs/reusable-components-ko-KR.html)를 참고하세요.
### React.Children
`React.Children`은 불투명한 자료 구조인 `this.props.children`를 다룰 수 있는 유틸리티를 제공합니다.
#### React.Children.map
```javascript
array React.Children.map(object children, function fn [, object thisArg])
```
`children`의 바로 밑에 있는 모든 자식에 `fn`을 호출합니다. 이 때 `this``thisArg`로 설정됩니다. `children`이 중첩된 객체나 배열일 경우 그 안의 값을 순회합니다. 따라서 `fn`에 컨테이너 객체가 넘어가는 일은 일어나지 않습니다. `children``null`이거나 `undefined`면 배열 대신 `null` 또는 `undefined`를 리턴합니다.
#### React.Children.forEach
```javascript
React.Children.forEach(object children, function fn [, object thisArg])
```
`React.Children.map()`과 비슷하지만 배열을 리턴하지 않습니다.
#### React.Children.count
```javascript
number React.Children.count(object children)
```
`children`에 들어있는 컴포넌트의 총 갯수를 리턴합니다. 이 갯수는 `map`이나 `forEach`에 넘긴 콜백이 호출되는 횟수와 동일합니다.
#### React.Children.only
```javascript
object React.Children.only(object children)
```
`children`에 단 하나의 자식이 있을 때 그 자식을 리턴합니다. 그 밖의 경우에는 예외를 발생시킵니다.
#### React.Children.toArray
```javascript
array React.Children.toArray(object children)
```
불투명한 자료구조인 `children`를 개별 자식마다 키를 할당해 평면 배열로 리턴합니다. 이는 render 메소드 내에서 자식의 컬렉션을 조작할 때, 특히 `this.props.children`을 넘기기 전에 재정렬하거나 재단할 때 유용합니다.
## ReactDOM
`react-dom` 패키지는 앱의 최상위 레벨에서 사용될 DOM 고유의 메소드를 제공하며, 원한다면 리액트 외부모델을 위한 출구로 사용될 수 있습니다. 대부분의 컴포넌트는 이 모듈을 사용할 필요가 없습니다.
### ReactDOM.render
```javascript
@@ -78,7 +145,7 @@ ReactComponent render(
)
```
주어진 ReactElement를 `container` 인자에 넘어온 DOM 안에 렌더링하고 컴포넌트의 레퍼런스를 리턴합니다.
주어진 ReactElement를 `container` 인자에 넘어온 DOM 안에 렌더링하고 컴포넌트의 [레퍼런스](/react/docs/more-about-refs-ko-KR.html)를 컴포넌트에 리턴합니다. [상태가 없는 컴포넌트](/react/docs/reusable-components-ko-KR.html#stateless-functions)에서는 `null`을 리턴합니다.
어떤 ReactElement가 이미 `container`에 렌더링 된 적이 있다면, 그것을 업데이트한 뒤 React 컴포넌트의 최신 상태를 반영하기 위해 꼭 필요한 만큼만 DOM을 변경합니다.
@@ -100,7 +167,26 @@ boolean unmountComponentAtNode(DOMElement container)
DOM에 마운트된 React 컴포넌트를 제거하고 이벤트 핸들러 및 state를 정리합니다. 컨테이너에 마운트된 컴포넌트가 없는 경우에는 호출해도 아무 동작을 하지 않습니다. 컴포넌트가 마운트 해제된 경우 `true`를, 마운트 해제할 컴포넌트가 없으면 `false`를 리턴합니다.
### ReactDOM.renderToString
### ReactDOM.findDOMNode
```javascript
DOMElement findDOMNode(ReactComponent component)
```
이 컴포넌트가 DOM에 마운트된 경우 해당하는 네이티브 브라우저 DOM 엘리먼트를 리턴합니다. 이 메소드는 폼 필드의 값이나 DOM의 크기/위치 등 DOM에서 정보를 읽을 때 유용합니다. **대부분의 경우, DOM 노드에 ref를 쓸 수 있으며 `findDOMNode`를 사욯할 필요는 없습니다.** `render``null`이나 `false`를 리턴할 때 `findDOMNode()``null`을 리턴합니다.
> 주의:
>
> `findDOMNode()`는 기본 DOM 노드에 접근하기 위한 출구입니다. 컴포넌트 추상화를 파괴하기 때문에 대부분의 경우 이것의 사용은 권장되지 않습니다.
>
> `findDOMNode()`는 마운트된 컴포넌트에서만 작동합니다. 이는 컴포넌트가 DOM에 위치해야 함을 뜻합니다. 만약 아직 생성되기전의 컴포넌트에서 `render()`에서 `findDOMNode()`를 호출하는 등 컴포넌트가 마운트 되기 이전에 이를 호출한다면, 예외가 던져질 것입니다.
>
> `findDOMNode()`는 상태가없는 컴포넌트에서 쓸 수 없습니다.
## ReactDOMServer
`react-dom/server` 패키지는 서버단에서 컴포넌트를 렌더할 수 있도록 해 줍니다.
### ReactDOMServer.renderToString
```javascript
string renderToString(ReactElement element)
@@ -111,73 +197,10 @@ string renderToString(ReactElement element)
또한 이 메소드로 서버에서 렌더링한 마크업을 포함한 노드에 `ReactDOM.render()`를 호출하면, React는 마크업을 보존하고 이벤트 핸들러만 붙이므로 최초 로딩을 매우 빠르게 느껴지게 할 수 있습니다.
### ReactDOM.renderToStaticMarkup
### ReactDOMServer.renderToStaticMarkup
```javascript
string renderToStaticMarkup(ReactElement element)
```
`renderToString`와 비슷하지만 `data-react-id`처럼 React에서 내부적으로 사용하는 추가적인 DOM 어트리뷰트를 만들지 않습니다. 추가적인 어트리뷰트를 제거하면 생성되는 마크업의 용량을 줄일 수 있기 때문에 React를 단순한 정적 페이지 생성기로 사용할 때 유용합니다.
### ReactDOM.isValidElement
```javascript
boolean isValidElement(* object)
```
주어진 객체가 ReactElement인지 확인합니다.
### ReactDOM.findDOMNode
```javascript
DOMElement findDOMNode(ReactComponent component)
```
이 컴포넌트가 DOM에 마운트된 경우 해당하는 네이티브 브라우저 DOM 엘리먼트를 리턴합니다. 이 메소드는 폼 필드의 값이나 DOM의 크기/위치 등 DOM에서 정보를 읽을 때 유용합니다. `render``null`이나 `false`를 리턴할 때 `findDOMNode()``null`을 리턴합니다.
### React.DOM
`React.DOM`은 DOM 컴포넌트에 대해 `React.createElement`의 편의 래퍼(wrapper)를 제공합니다. JSX를 사용하지 않는 경우에만 사용하십시오. 예를 들어, `React.DOM.div(null, 'Hello World!')`와 같이 사용할 수 있습니다.
### React.PropTypes
`React.PropTypes`는 컴포넌트에 넘어오는 props가 올바른지 검사할 수 있는 컴포넌트의 `propTypes` 객체에 들어가는 타입을 가집니다. `propTypes`에 대한 자세한 정보는 [재사용 가능한 컴포넌트](/react/docs/reusable-components-ko-KR.html)를 참고하세요.
### React.Children
`React.Children`은 불투명한 자료 구조인 `this.props.children`를 다룰 수 있는 유틸리티를 제공합니다.
#### React.Children.map
```javascript
object React.Children.map(object children, function fn [, object thisArg])
```
`children`의 바로 밑에 있는 모든 자식에 `fn`을 호출합니다. 이 때 `this``thisArg`로 설정됩니다. `children`이 중첩된 객체나 배열일 경우 그 안의 값을 순회합니다. 따라서 `fn`에 컨테이너 객체가 넘어가는 일은 일어나지 않습니다. `children``null`이거나 `undefined`면 빈 객체 대신 `null` 또는 `undefined`를 리턴합니다.
#### React.Children.forEach
```javascript
React.Children.forEach(object children, function fn [, object thisArg])
```
`React.Children.map()`과 비슷하지만 객체를 리턴하지 않습니다.
#### React.Children.count
```javascript
number React.Children.count(object children)
```
`children`에 들어있는 컴포넌트의 총 갯수를 리턴합니다. 이 갯수는 `map`이나 `forEach`에 넘긴 콜백이 호출되는 횟수와 동일합니다.
#### React.Children.only
```javascript
object React.Children.only(object children)
```
`children`에 단 하나의 자식이 있을 때 그 자식을 리턴합니다. 그 밖의 경우에는 예외를 발생시킵니다.

View File

@@ -14,14 +14,17 @@ React 컴포넌트의 인스턴스는 React가 렌더링 시에 내부적으로
### setState
```javascript
void setState(function|object nextState[, function callback])
void setState(
function|object nextState,
[function callback]
)
```
`nextState`를 현재 state에 합니다. 이벤트 핸들러와 서버 요청 콜백에서 UI 업데이트를 발생시키기 위해 이 메소드를 주로 사용합니다.
nextState를 현재 state에 얕게(shallow) 병합합니다. 이벤트 핸들러와 서버 요청 콜백에서 UI 업데이트를 발생시키기 위해 이 메소드를 주로 사용합니다.
첫번째 인자는 업데이트를 위한 키를 0개 이상 가진 객체이거나 업데이트를 위한 키들을 포함한 객체를 반환하는 함수(의 state나 props)일 수 있습니다.
객체를 사용하는 간단한 예제입니다...
객체를 사용하는 간단한 예제입니다:
```javascript
setState({mykey: '새로운 값'});
@@ -51,7 +54,10 @@ setState(function(previousState, currentProps) {
### replaceState
```javascript
void replaceState(object nextState[, function callback])
void replaceState(
object nextState,
[function callback]
)
```
`setState()`와 비슷하지만 기존에 존재하는 state 중 nextState에 없는 키는 모두 삭제됩니다.
@@ -64,7 +70,9 @@ void replaceState(object nextState[, function callback])
### forceUpdate
```javascript
void forceUpdate([function callback])
void forceUpdate(
[function callback]
)
```
기본적으로, 컴포넌트의 state나 props가 변경되면, 컴포넌트는 다시 렌더됩니다. 하지만 이런 변경이 묵시적이거나(예를들어 객체의 변경 없이 깊이 있는 데이터만 변경된 경우) `render()` 함수가 다른 값에 의존하는 경우, `forceUpdate()`를 호출해 React에게 `render()`를 다시 실행할 필요가 있다고 알릴 수 있습니다.
@@ -95,7 +103,7 @@ DOMElement getDOMNode()
boolean isMounted()
```
`isMounted()`는 컴포넌트가 DOM에 렌더링되었으면 true를, 아니면 false를 리턴합니다. 비동기적으로 `setState()``forceUpdate()`를 호출할 때 이 메소드를 사용하여 오류를 방지할 수 있습니다.
`isMounted()`는 컴포넌트가 DOM에 렌더링되었으면 `true`를, 아니면 `false`를 리턴합니다. 비동기적으로 `setState()``forceUpdate()`를 호출할 때 이 메소드를 사용하여 오류를 방지할 수 있습니다.
> 주의:
>
@@ -105,7 +113,10 @@ boolean isMounted()
### setProps
```javascript
void setProps(object nextProps[, function callback])
void setProps(
object nextProps,
[function callback]
)
```
외부 JavaScript 애플리케이션과 연동하는 경우 `ReactDOM.render()`로 렌더링된 React 컴포넌트에 변경을 알리고 싶을 때가 있습니다.
@@ -124,7 +135,10 @@ void setProps(object nextProps[, function callback])
### replaceProps
```javascript
void replaceProps(object nextProps[, function callback])
void replaceProps(
object nextProps,
function callback]
)
```
`setProps()`와 비슷하지만 두 객체를 합치는 대신 이전에 존재하던 props를 삭제합니다.

View File

@@ -106,7 +106,7 @@ boolean isMounted()
> Note:
>
> This method is not available on ES6 `class` components that extend `React.Component`. It may be removed entirely in a future version of React.
> This method is not available on ES6 `class` components that extend `React.Component`. It will likely be removed entirely in a future version of React, so you might as well [start migrating away from isMounted() now](/react/blog/2015/12/16/ismounted-antipattern.html).
### setProps
@@ -124,11 +124,11 @@ Calling `setProps()` on a root-level component will change its properties and tr
> Note:
>
> This method is deprecated and will be removed soon. This method is not available on ES6 `class` components that extend `React.Component`. Instead of calling `setProps`, try invoking ReactDOM.render() again with the new props. For additional notes, see our [blog post about using the Top Level API](/react/blog/2015/10/01/react-render-and-top-level-api.html)
>
> When possible, the declarative approach of calling `ReactDOM.render()` again on the same node is preferred instead. It tends to make updates easier to reason about. (There's no significant performance difference between the two approaches.)
>
> This method can only be called on a root-level component. That is, it's only available on the component passed directly to `ReactDOM.render()` and none of its children. If you're inclined to use `setProps()` on a child component, instead take advantage of reactive updates and pass the new prop to the child component when it's created in `render()`.
>
> This method is not available on ES6 `class` components that extend `React.Component`. It may be removed entirely in a future version of React.
### replaceProps
@@ -143,4 +143,4 @@ Like `setProps()` but deletes any pre-existing props instead of merging the two
> Note:
>
> This method is not available on ES6 `class` components that extend `React.Component`. It may be removed entirely in a future version of React.
> This method is deprecated and will be removed soon. This method is not available on ES6 `class` components that extend `React.Component`. Instead of calling `replaceProps`, try invoking ReactDOM.render() again with the new props. For additional notes, see our [blog post about using the Top Level API](/react/blog/2015/10/01/react-render-and-top-level-api.html)

View File

@@ -122,7 +122,7 @@ void componentWillMount()
void componentDidMount()
```
최초 렌더링이 일어난 다음 클라이언트에서만 한번 호출됩니다. (서버에서는 호출되지 않습니다.) 이 시점에 컴포넌트 `ReactDOM.findDOMNode(this)`로 접근 가능한 DOM 표현을 가집니다.
최초 렌더링이 일어난 다음 클라이언트에서만 한번 호출됩니다. (서버에서는 호출되지 않습니다.) 이 시점에 자식의 refs들에 접근 할 수 있습니다. (기본 DOM 표현에 접근하는 등). 자식 컴포넌트 `componentDidMount()` 메소드는 부모 컴포넌트보다 먼저 호출됩니다.
다른 JavaScript 프레임워크를 연동하거나, `setTimeout`/`setInterval`로 타이머를 설정하고 AJAX 요청을 보내는 등의 작업을 이 메소드에서 합니다.
@@ -130,7 +130,9 @@ void componentDidMount()
### 업데이트 시: componentWillReceiveProps
```javascript
void componentWillReceiveProps(object nextProps)
void componentWillReceiveProps(
object nextProps
)
```
컴포넌트가 새로운 props를 받을 때 호출됩니다. 이 메소드는 최초 렌더링 시에는 호출되지 않습니다.
@@ -154,7 +156,9 @@ componentWillReceiveProps: function(nextProps) {
### 업데이트 시: shouldComponentUpdate
```javascript
boolean shouldComponentUpdate(object nextProps, object nextState)
boolean shouldComponentUpdate(
object nextProps, object nextState
)
```
새로운 props 또는 state를 받아 렌더링을 하기 전에 호출됩니다. 최초 렌더링 시나 `forceUpdate`를 사용하는 경우에는 호출되지 않습니다.
@@ -168,9 +172,9 @@ shouldComponentUpdate: function(nextProps, nextState) {
}
```
`shouldComponentUpdate`가 false를 리턴하면, 다음에 state가 바뀌기 전까지 `render()`가 완전히 호출되지 않고 넘어갑니다. (그리고 `componentWillUpdate``componentDidUpdate` 또한 호출되지 않습니다.)
`shouldComponentUpdate`가 false를 리턴하면, 다음에 state가 바뀌기 전까지 `render()`가 완전히 호출되지 않고 넘어갑니다. `componentWillUpdate``componentDidUpdate` 또한 호출되지 않습니다.
기본적으로 `shouldComponentUpdate`는 항상 true를 리턴합니다. `state`가 제자리에서(in place) 바뀐 경우에 발생하는 파악하기 힘든 버그를 막기 위함입니다. 하지만 `state`가 항상 변경 불가능하도록 주의하고 `render()`에서 `props``state`를 읽기만 하면 이전 props 및 state와 바뀌는 값을 비교하는 `shouldComponentUpdate`를 직접 구현할 수 있습니다.
기본적으로 `shouldComponentUpdate`는 항상 `true`를 리턴합니다. `state`가 제자리에서(in place) 바뀐 경우에 발생하는 파악하기 힘든 버그를 막기 위함입니다. 하지만 `state`가 항상 변경 불가능하도록 주의하고 `render()`에서 `props``state`를 읽기만 하면 이전 props 및 state와 바뀌는 값을 비교하는 `shouldComponentUpdate`를 직접 구현할 수 있습니다.
성능에 병목이 있다면, 특히 컴포넌트가 매우 많은 경우 `shouldComponentUpdate`를 사용하여 앱을 빠르게 만들 수 있습니다.
@@ -178,7 +182,9 @@ shouldComponentUpdate: function(nextProps, nextState) {
### 업데이트 시: componentWillUpdate
```javascript
void componentWillUpdate(object nextProps, object nextState)
void componentWillUpdate(
object nextProps, object nextState
)
```
새로운 props나 state를 받았을 때 렌더링 직전에 호출됩니다. 최초 렌더링 시에는 호출되지 않습니다.
@@ -193,7 +199,9 @@ void componentWillUpdate(object nextProps, object nextState)
### 업데이트 시: componentDidUpdate
```javascript
void componentDidUpdate(object prevProps, object prevState)
void componentDidUpdate(
object prevProps, object prevState
)
```
컴포넌트의 업데이트가 DOM에 반영된 직후에 호출됩니다. 최초 렌더링 시에는 호출되지 않습니다.

View File

@@ -59,7 +59,7 @@ controls coords crossOrigin data dateTime defer dir disabled download draggable
encType form formAction formEncType formMethod formNoValidate formTarget frameBorder
headers height hidden high href hrefLang htmlFor httpEquiv icon id inputMode
keyParams keyType label lang list loop low manifest marginHeight marginWidth max
maxLength media mediaGroup method min minlength multiple muted name noValidate open
maxLength media mediaGroup method min minLength multiple muted name noValidate open
optimum pattern placeholder poster preload radioGroup readOnly rel required role
rows rowSpan sandbox scope scoped scrolling seamless selected shape size sizes
span spellCheck src srcDoc srcSet start step style summary tabIndex target title

View File

@@ -8,7 +8,7 @@ next: events-ko-KR.html
## 지원되는 태그
React는 모든 공통 엘리먼트를 지원하려 합니다. 필요한 엘리먼트가 목록에 없다면, 이슈로 등록해 주세요.
React는 모든 공통 엘리먼트를 지원하려 합니다. 필요한 엘리먼트가 목록에 없다면, [이슈로 등록](https://github.com/facebook/react/issues/new)해 주세요.
### HTML 엘리먼트
@@ -53,17 +53,17 @@ React는 모든 `data-*`, `aria-*` 어트리뷰트와 밑에 있는 모든 어
```
accept acceptCharset accessKey action allowFullScreen allowTransparency alt
async autoComplete autoFocus autoPlay cellPadding cellSpacing charSet challenge
checked classID className colSpan cols content contentEditable contextMenu controls
coords crossOrigin data dateTime defer dir disabled download draggable encType
form formAction formEncType formMethod formNoValidate formTarget frameBorder
async autoComplete autoFocus autoPlay capture cellPadding cellSpacing charSet
challenge checked classID className cols colSpan content contentEditable contextMenu
controls coords crossOrigin data dateTime defer dir disabled download draggable
encType form formAction formEncType formMethod formNoValidate formTarget frameBorder
headers height hidden high href hrefLang htmlFor httpEquiv icon id inputMode
keyParams keyType label lang list loop low manifest marginHeight marginWidth max
maxLength media mediaGroup method min multiple muted name noValidate open
maxLength media mediaGroup method min minLength multiple muted name noValidate open
optimum pattern placeholder poster preload radioGroup readOnly rel required role
rowSpan rows sandbox scope scoped scrolling seamless selected shape size sizes
rows rowSpan sandbox scope scoped scrolling seamless selected shape size sizes
span spellCheck src srcDoc srcSet start step style summary tabIndex target title
type useMap value width wmode
type useMap value width wmode wrap
```
덧붙여, 이런 비표준 어트리뷰트도 지원됩니다.
@@ -72,15 +72,19 @@ type useMap value width wmode
- [오픈 그래프](http://ogp.me/) 메타 태그를 위한 `property`.
- [HTML5 마이크로데이터](http://schema.org/docs/gs.html)를 위한 `itemProp itemScope itemType itemRef itemID`.
- 인터넷 익스플로어를 위한 `unselectable`.
- WebKit/Blink의 `search` 타입 input 필드를 위한 `results autoSave`
컴포넌트에 직접 HTML 문자열을 넣을 때 사용하는, React 전용 어트리뷰트 `dangerouslySetInnerHTML`([자세한 정보는 여기](/react/docs/special-non-dom-attributes-ko-KR.html))도 있습니다.
### SVG 어트리뷰트
```
clipPath cx cy d dx dy fill fillOpacity fontFamily fontSize fx fy
gradientTransform gradientUnits markerEnd markerMid markerStart offset opacity
patternContentUnits patternUnits points preserveAspectRatio r rx ry
spreadMethod stopColor stopOpacity stroke strokeDasharray strokeLinecap
strokeOpacity strokeWidth textAnchor transform version viewBox x1 x2 x y1 y2 y
clipPath cx cy d dx dy fill fillOpacity fontFamily
fontSize fx fy gradientTransform gradientUnits markerEnd
markerMid markerStart offset opacity patternContentUnits
patternUnits points preserveAspectRatio r rx ry spreadMethod
stopColor stopOpacity stroke strokeDasharray strokeLinecap
strokeOpacity strokeWidth textAnchor transform version
viewBox x1 x2 x xlinkActuate xlinkArcrole xlinkHref xlinkRole
xlinkShow xlinkTitle xlinkType xmlBase xmlLang xmlSpace y1 y2 y
```

View File

@@ -59,7 +59,7 @@ controls coords crossOrigin data dateTime defer dir disabled download draggable
encType form formAction formEncType formMethod formNoValidate formTarget frameBorder
headers height hidden high href hrefLang htmlFor httpEquiv icon id inputMode
keyParams keyType label lang list loop low manifest marginHeight marginWidth max
maxLength media mediaGroup method min minlength multiple muted name noValidate open
maxLength media mediaGroup method min minLength multiple muted name noValidate open
optimum pattern placeholder poster preload radioGroup readOnly rel required role
rows rowSpan sandbox scope scoped scrolling seamless selected shape size sizes
span spellCheck src srcDoc srcSet start step style summary tabIndex target title

View File

@@ -81,6 +81,22 @@ DOMDataTransfer clipboardData
```
### Eventi di Composizione
Nomi degli eventi:
```
onCompositionEnd onCompositionStart onCompositionUpdate
```
Proprietà:
```javascript
string data
```
### Eventi di Tastiera
Nomi degli eventi:
@@ -165,6 +181,15 @@ boolean shiftKey
```
### Eventi di Selezione
Nomi degli eventi:
```
onSelect
```
### Eventi del Tocco
Nomi degli eventi:

View File

@@ -31,8 +31,33 @@ string type
> 주의:
>
> v0.12 시점에서, 이벤트 핸들러에서 `false` 를 리턴하는 것은 더 이상 이벤트의 전달(propagation)을 멈추지 않습니다. 대신, `e.stopPropagation()`나 `e.preventDefault()`로 적절히 수동으로 트리거해야 합니다.
> v0.14 시점에서, 이벤트 핸들러에서 `false` 를 리턴하는 것은 더 이상 이벤트의 전달(propagation)을 멈추지 않습니다. 대신, `e.stopPropagation()`나 `e.preventDefault()`로 적절히 수동으로 트리거해야 합니다.
## 이벤트 풀링
`SyntheticEvent`는 풀링됩니다. 이는 `SyntheticEvent` 객체가 재사용될 것이며 이벤트 콜백이 호출된 후 모든 프로퍼티가 null 값을 갖게 된다는 것을 뜻합니다.
이는 성능을 위한 동작입니다.
이 때문에, 비동기 방식으로는 이벤트에 접근할 수 없습니다.
```javascript
function onClick(event) {
console.log(event); // => null이 된 객체.
console.log(event.type); // => "click"
var eventType = event.type; // => "click"
setTimeout(function() {
console.log(event.type); // => null
console.log(eventType); // => "click"
}, 0);
this.setState({clickEvent: event}); // 작동하지 않습니다. this.state.clickEvent 는 null값들만을 갖고 있습니다.
this.setState({eventType: event.type}); // 여전히 이벤트 프로퍼티를 내보낼 수 있습니다.
}
```
> 주의:
>
> 만약 비동기 방식으로 이벤트 프로퍼티에 접근하길 원한다면, 이벤트의 `event.persist()`를 호출해야 합니다, 이는 풀로부터 통합적인 이벤트를 제거하고 이벤트에 대한 참조는 사용자의 코드에 의해 유지 될 수 있도록 합니다.
## 지원되는 이벤트
@@ -56,6 +81,22 @@ DOMDataTransfer clipboardData
```
### Composition Events
이벤트 이름:
```
onCompositionEnd onCompositionStart onCompositionUpdate
```
프로퍼티:
```javascript
string data
```
### 키보드 이벤트
이벤트 이름:
@@ -96,6 +137,7 @@ onFocus onBlur
DOMEventTarget relatedTarget
```
이 포커스 이벤트는 폼 엘리먼트뿐만 아니라 모든 React DOM 엘리먼트에서 작동합니다.
<a name="form-events"></a>
### 폼 이벤트
@@ -114,11 +156,12 @@ onChange 이벤트에 대한 더 자세한 정보는 [폼](/react/docs/forms-ko-
이벤트 이름:
```
onClick onContextMenu onDoubleClick onDrag onDragEnd onDragEnter onDragExit onDragLeave onDragOver onDragStart onDrop onMouseDown onMouseEnter onMouseLeave
onClick onContextMenu onDoubleClick onDrag onDragEnd onDragEnter onDragExit
onDragLeave onDragOver onDragStart onDrop onMouseDown onMouseEnter onMouseLeave
onMouseMove onMouseOut onMouseOver onMouseUp
```
`onMouseEnter``onMouseLeave` 이벤트는 평범하게 일어나는(bubbling) 대신 입력된 컴포넌트에 남겨지도록 컴포넌트에서 전달되고 캡쳐 단계가 없습니다.
`onMouseEnter``onMouseLeave` 이벤트는 평범하게 일어나는(bubbling) 대신 입력된 엘리먼트에 남겨지도록 엘리먼트에서 전달되고 캡쳐 단계가 없습니다.
프로퍼티:
@@ -140,6 +183,15 @@ boolean shiftKey
```
### 셀렉션 이벤트
이벤트 이름:
```
onSelect
```
### 터치 이벤트
이벤트 이름:
@@ -202,3 +254,11 @@ number deltaZ
```
onAbort onCanPlay onCanPlayThrough onDurationChange onEmptied onEncrypted onEnded onError onLoadedData onLoadedMetadata onLoadStart onPause onPlay onPlaying onProgress onRateChange onSeeked onSeeking onStalled onSuspend onTimeUpdate onVolumeChange onWaiting
```
### 이미지 이벤트
이벤트 이름:
```
onLoad onError
```

View File

@@ -182,7 +182,7 @@ boolean shiftKey
```
### Selection events
### Selection Events
Event names:
@@ -191,7 +191,7 @@ onSelect
```
### Touch events
### Touch Events
Event names:

View File

@@ -138,6 +138,15 @@ boolean shiftKey
```
### Selection Events
事件名称:
```
onSelect
```
### 触控事件
事件名称:
@@ -192,3 +201,19 @@ number deltaX
number deltaY
number deltaZ
```
### Media Events
事件名称:
```
onAbort onCanPlay onCanPlayThrough onDurationChange onEmptied onEncrypted onEnded onError onLoadedData onLoadedMetadata onLoadStart onPause onPlay onPlaying onProgress onRateChange onSeeked onSeeking onStalled onSuspend onTimeUpdate onVolumeChange onWaiting
```
### Image Events
事件名称:
```
onLoad onError
```

View File

@@ -10,6 +10,7 @@ React has implemented a browser-independent events and DOM system for performanc
* All DOM properties and attributes (including event handlers) should be camelCased to be consistent with standard JavaScript style. We intentionally break with the spec here since the spec is inconsistent. **However**, `data-*` and `aria-*` attributes [conform to the specs](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes#data-*) and should be lower-cased only.
* The `style` attribute accepts a JavaScript object with camelCased properties rather than a CSS string. This is consistent with the DOM `style` JavaScript property, is more efficient, and prevents XSS security holes.
* Since `class` and `for` are reserved words in JavaScript, the JSX elements for built-in [DOM nodes](http://javascript.info/tutorial/dom-nodes) should use the attribute names `className` and `htmlFor` respectively, (eg. `<div className="foo" />` ). Custom elements should use `class` and `for` directly (eg. `<my-tag class="foo" />` ).
* All event objects conform to the W3C spec, and all events (including submit) bubble correctly per the W3C spec. See [Event System](/react/docs/events.html) for more details.
* The `onChange` event behaves as you would expect it to: whenever a form field is changed this event is fired rather than inconsistently on blur. We intentionally break from existing browser behavior because `onChange` is a misnomer for its behavior and React relies on this event to react to user input in real time. See [Forms](/react/docs/forms.html) for more details.
* Form input attributes such as `value` and `checked`, as well as `textarea`. [More here](/react/docs/forms.html).

View File

@@ -3,7 +3,7 @@ id: reconciliation-it-IT
title: Riconciliazione
permalink: reconciliation-it-IT.html
prev: special-non-dom-attributes-it-IT.html
next: glossary-it-IT.html
next: webcomponents.html
---
La decisione chiave del design di React è fare in modo che l'API sembri ripetere il rendering dell'intera applicazione per ciascun aggiornamento. Ciò rende la scrittura delle applicazione molto più semplice, ma è anche una sfida incredibile per renderlo trattabile. Questo articolo spiega come siamo riusciti a trasformare, tramite potenti euristiche, un problema O(n<sup>3</sup>) in uno O(n).

View File

@@ -3,7 +3,7 @@ id: reconciliation-ko-KR
title: 비교조정(Reconciliation)
permalink: reconciliation-ko-KR.html
prev: special-non-dom-attributes-ko-KR.html
next: glossary-ko-KR.html
next: webcomponents.html
---
React의 주요 설계 철학은 업데이트할 때마다 전체 앱을 다시 렌더하는 것처럼 보이게 API를 만드는 것입니다. 이렇게 하면 애플리케이션 작성이 훨씬 쉬워지지만 한편으로는 어려운 도전 과제이기도 합니다. 이 글에서는 강력한 휴리스틱으로 어떻게 O(n<sup>3</sup>) 복잡도의 문제를 O(n)짜리로 바꿀 수 있었는지 설명합니다.

View File

@@ -3,7 +3,7 @@ id: reconciliation
title: Reconciliation
permalink: reconciliation.html
prev: special-non-dom-attributes.html
next: glossary.html
next: webcomponents.html
---
React's key design decision is to make the API seem like it re-renders the whole app on every update. This makes writing applications a lot easier but is also an incredible challenge to make it tractable. This article explains how with powerful heuristics we managed to turn a O(n<sup>3</sup>) problem into a O(n) one.
@@ -129,5 +129,5 @@ Because we rely on two heuristics, if the assumptions behind them are not met, p
1. The algorithm will not try to match sub-trees of different components classes. If you see yourself alternating between two components classes with very similar output, you may want to make it the same class. In practice, we haven't found this to be an issue.
2. If you don't provide stable keys (by using Math.random() for example), all the sub-trees are going to be re-rendered every single time. By giving the users the choice to choose the key, they have the ability to shoot themselves in the foot.
2. Keys should be stable, predictable, and unique. Unstable keys (like those produced by Math.random()) will cause many nodes to be unnecessarily re-created, which can cause performance degradation and lost state in child components.

View File

@@ -0,0 +1,56 @@
---
id: webcomponents
title: Web Components
permalink: webcomponents.html
prev: reconciliation.html
next: glossary.html
---
Trying to compare and contrast React with WebComponents inevitably results in specious conclusions, because the two libraries are built to solve different problems. WebComponents provide strong encapsulation for reusable components, while React provides a declarative library that keeps the DOM in sync with your data. The two goals are complementary; engineers can mix-and-match the technologies. As a developer, you are free to use React in your WebComponents, or to use WebComponents in React, or both.
## Using Web Components in React
```javascript
class HelloMessage extends React.Component{
render() {
return <div>Hello <x-search>{this.props.name}</x-search>!</div>;
}
}
```
> Note:
>
> The programming models of the two component systems (web components vs. react components) differ in that
> web components often expose an imperative API (for instance, a `video` web component might expose `play()`
> and `pause()` functions). To the extent that web components are declarative functions of their attributes,
> they should work, but to access the imperative APIs of a web component, you will need to attach a ref to the
> component and interact with the DOM node directly. If you are using third-party web components, the
> recommended solution is to write a React component that behaves as a wrapper for your web component.
>
> At this time, events emitted by a web component may not properly propagate through a React render tree.
> You will need to manually attach event handlers to handle these events within your React components.
## Using React in your Web Components
```javascript
var proto = Object.create(HTMLElement.prototype, {
createdCallback: {
value: function() {
var mountPoint = document.createElement('span');
this.createShadowRoot().appendChild(mountPoint);
var name = this.getAttribute('name');
var url = 'https://www.google.com/search?q=' + encodeURIComponent(name);
ReactDOM.render(<a href={url}>{name}</a>, mountPoint);
}
}
});
document.registerElement('x-search', {prototype: proto});
```
## Complete Example
Check out the `webcomponents` example in the [starter kit](/react/downloads.html) for a complete example.

View File

@@ -2,7 +2,7 @@
id: glossary-it-IT
title: Terminologia del DOM (Virtuale)
permalink: glossary-it-IT.html
prev: reconciliation-it-IT.html
prev: webcomponents.html
---
Nella terminologia di React, esistono cinque tipi base che è importante distinguere:

View File

@@ -2,7 +2,7 @@
id: glossary-ko-KR
title: React (가상) DOM 용어
permalink: glossary-ko-KR.html
prev: reconciliation-ko-KR.html
prev: webcomponents-ko-KR.html
---
다음은 React에서 사용되는 용어들로, 이 다섯 가지의 타입을 구별하는 것은 중요합니다.
@@ -44,7 +44,7 @@ var root = <ul className="my-list">
ReactDOM.render(root, document.getElementById('example'));
```
__팩토리__
### 팩토리
`ReactElement` 팩토리는 그저 특정한 `type` 프로퍼티를 가지는 `ReactElement`를 만들어주는 함수입니다. React에는 팩토리를 만드는 헬퍼가 내장되어 있습니다. 그 함수는 사실상 다음과 같습니다:
@@ -105,7 +105,7 @@ var MyComponent = React.createClass({
var component = new MyComponent(props); // 절대 하지 마세요.
```
테스트 목적이 아니라면 __절대__ 이 생성자를 직접 호출하지 마십시오. React가 알아서 호출해줍니다.
테스트 목적이 아니라면 *절대* 이 생성자를 직접 호출하지 마십시오. React가 알아서 호출해줍니다.
대신 `ReactComponent` 클래스를 `createElement`에 넘겨 `ReactElement`를 받을 수 있습니다.
@@ -140,13 +140,13 @@ componentA === componentB; // true
## 형식 타입 정의
__진입점__
### 진입점
```
ReactDOM.render = (ReactElement, HTMLElement | SVGElement) => ReactComponent;
```
__노드와 엘리먼트__
### 노드와 엘리먼트
```
type ReactNode = ReactElement | ReactFragment | ReactText;
@@ -180,7 +180,7 @@ type ReactText = string | number;
type ReactEmpty = null | undefined | boolean;
```
__클래스와 컴포넌트__
### 클래스와 컴포넌트
```
type ReactClass<TProps> = (TProps) => ReactComponent<TProps>;

View File

@@ -2,7 +2,7 @@
id: glossary
title: React (Virtual) DOM Terminology
permalink: glossary.html
prev: reconciliation.html
prev: webcomponents.html
---
In React's terminology, there are five core types that are important to distinguish:
@@ -133,7 +133,7 @@ var componentB = ReactDOM.render(<MyComponent />, document.getElementById('examp
componentA === componentB; // true
```
This is why you shouldn't construct your own instance. Instead, `ReactElement` is a virtual `ReactComponent` before it gets constructed. An old and new `ReactElement` can be compared to see if a new `ReactComponent` instance is created or if the existing one is reused.
This is why you shouldn't construct your own instance. Instead, `ReactElement` is a virtual `ReactComponent` before it gets constructed. An old and new `ReactElement` can be compared to see if a new `ReactComponent` instance should be created or if the existing one should be reused.
The `render` method of a `ReactComponent` is expected to return another `ReactElement`. This allows these components to be composed. Ultimately the render resolves into `ReactElement` with a `string` tag which instantiates a DOM `Element` instance and inserts it into the document.

View File

@@ -81,7 +81,7 @@ There are two types of "model" data in React: props and state. It's important to
To make your UI interactive, you need to be able to trigger changes to your underlying data model. React makes this easy with **state**.
To build your app correctly, you first need to think of the minimal set of mutable state that your app needs. The key here is DRY: *Don't Repeat Yourself*. Figure out what the absolute minimal representation of the state of your application needs to be and compute everything else you need on-demand. For example, if you're building a TODO list, just keep an array of the TODO items around; don't keep a separate state variable for the count. Instead, when you want to render the TODO count, simply take the length of the TODO items array.
To build your app correctly, you first need to think of the minimal set of mutable state that your app needs. The key here is DRY: *Don't Repeat Yourself*. Figure out the absolute minimal representation of the state your application needs and compute everything else you need on-demand. For example, if you're building a TODO list, just keep an array of the TODO items around; don't keep a separate state variable for the count. Instead, when you want to render the TODO count, simply take the length of the TODO items array.
Think of all of the pieces of data in our example application. We have:

3
docs/docs/tutorial.it-IT.md Normal file → Executable file
View File

@@ -657,7 +657,7 @@ var CommentBox = React.createClass({
La nostra applicazione è adesso completa, ma aspettare che la richiesta completi prima di vedere il commento apparire nella lista la fa sembrare lenta. Possiamo aggiungere ottimisticamente questo commento alla lista per fare apparire l'applicazione più veloce.
```javascript{17-19}
```javascript{17-19,29}
// tutorial20.js
var CommentBox = React.createClass({
loadCommentsFromServer: function() {
@@ -686,6 +686,7 @@ var CommentBox = React.createClass({
this.setState({data: data});
}.bind(this),
error: function(xhr, status, err) {
this.setState({data: comments});
console.error(this.props.url, status, err.toString());
}.bind(this)
});

9
docs/docs/tutorial.ja-JP.md Normal file → Executable file
View File

@@ -249,7 +249,7 @@ var Comment = React.createClass({
});
```
このコードでは Showdown のライブラリを呼び出すことしかしていません。`this.props.children` は React によってラップされたテキストですが、これを Showdown が理解できる生の文字列に変換する必要があります。そのため、上のコードでは明示的に `toString()` を呼び出しているのです。
このコードでは marked のライブラリを呼び出すことしかしていません。`this.props.children` は React によってラップされたテキストですが、これを marked が理解できる生の文字列に変換する必要があります。そのため、上のコードでは明示的に `toString()` を呼び出しているのです。
しかし問題があります!ブラウザがレンダリングしたコメントは次のように表示されているはずです -- "`<p>`This is `<em>`another`</em>` comment`</p>`" このようなタグは実際に HTML としてレンダリングさせたいですね。
@@ -272,9 +272,9 @@ var Comment = React.createClass({
});
```
これは特別な API であり、生の HTML が挿入されにくくなるよう意図的に作ったものです。しかし、ここでは Showdown のためにこのバックドアを利用しています。
これは特別な API であり、生の HTML が挿入されにくくなるよう意図的に作ったものです。しかし、ここでは marked のためにこのバックドアを利用しています。
**注意:** この機能を使うことで、Showdown は安全なものと信頼することになります。
**注意:** この機能を使うことで、marked は安全なものと信頼することになります。
### データモデルとの連携
@@ -653,7 +653,7 @@ var CommentBox = React.createClass({
アプリケーションに必要な機能は一通り実装できました。しかし、フォームからコメントを送信しても、サーバからのレスポンスが来るまで自分のコメントはリストに載らないため、アプリの動作は遅く感じます。ここでは、送信したコメントをリストに先読みさせて、アプリの体感速度をアップさせましょう。
```javascript{17-19}
```javascript{17-19,29}
// tutorial20.js
var CommentBox = React.createClass({
loadCommentsFromServer: function() {
@@ -682,6 +682,7 @@ var CommentBox = React.createClass({
this.setState({data: data});
}.bind(this),
error: function(xhr, status, err) {
this.setState({data: comments});
console.error(this.props.url, status, err.toString());
}.bind(this)
});

70
docs/docs/tutorial.ko-KR.md Normal file → Executable file
View File

@@ -26,21 +26,21 @@ next: thinking-in-react-ko-KR.html
### 서버 구동하기
이 튜토리얼을 시작할 때 필요한 건 아니지만, 나중에 실행 중인 서버에 `POST` 요청을 하는 기능을 추가하게 될 것입니다. 서버를 구성하는 것이 익숙하다면, 본인이 편한 방식대로 서버를 구성해 주세요. 서버사이드에 대한 고민없이 React의 학습 그 자체에 집중하고 싶은 분들을 위해, 몇 가지 언어로 간단한 서버코드를 작성해 놓았습니다 - JavaScript (Node.js), Python, Ruby, Go, PHP 버전이 있고, GitHub에서 찾아보실 수 있습니다. [소스를 확인](https://github.com/reactjs/react-tutorial/)하거나 [zip 파일을 다운로드](https://github.com/reactjs/react-tutorial/archive/master.zip)하고 시작하세요.
이 튜토리얼을 시작하기 위해, 서버를 구동할 필요가 있습니다. 서버는 순수하게 우리가 받고 저장할 데이터의 API 엔드포인트로써만 사용합니다. 이를 가능한한 쉽게하기 위해, 필요한 것만 제공하는 간단한 서버를 몇가지 스크립트 언어로 만들었습니다. **시작하는데 필요한 모든 것이 들어있는 [소스](https://github.com/reactjs/react-tutorial/)를 보시거나 [zip 파일](https://github.com/reactjs/react-tutorial/archive/master.zip)을 다운로드 할 수 있습니다.**
튜토리얼을 시작하려면, `public/index.html`을 열고 바로 시작하세요.
단순하게 하기위해, 서버는 `JSON` 파일을 데이터베이스로 사용합니다. 프로덕션에서 사용할 수는 없지만 이렇게 하면 API를 사용할 때 시뮬레이션이 단순해집니다. 서버가 시작되면, API 엔드포인트를 제공하고 필요한 정적 페이지를 서빙합니다.
### 시작하기
이 튜토리얼에서는 CDN에 있는 미리 빌드된 JavaScript 파일들을 사용합니다. 선호하는 에디터에서 `public/index.html`을 열어, 아래의 내용을 채우세요:
이 튜토리얼에서는 가능한한 간단하게 만들겠습니다. 위에서 언급된 서버 패키지에 우리가 작업할 HTML 파일 포함되어 있습니다. 편한 편집기에서 `public/index.html`를 여세요. 이는 이런 내용이어야 합니다.(아마 조금 다를 수 있습니다만, 여기에 나중에 `<script>` 태그를 추가 할 것입니다.)
```html
<!-- index.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Hello React</title>
<meta charset="utf-8" />
<title>React Tutorial</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/{{site.react_version}}/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/{{site.react_version}}/react-dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script>
@@ -48,14 +48,16 @@ next: thinking-in-react-ko-KR.html
</head>
<body>
<div id="content"></div>
<script type="text/babel" src="scripts/example.js"></script>
<script type="text/babel">
// 여기에 코드를 작성합니다
// 이 튜토리얼을 시작하려면, 그냥 scripts/example.js를 로드하는 스크립트
// 태그를 제거하고 여기에 코드를 적으세요.
</script>
</body>
</html>
```
다음 진행을 위해, 위의 스크립트 태그안에 JavaScript 코드를 작성합니다. 각 단계를 추가한 다음 index.html 파일을 브라우저에서 열어서 진행을 확인하세요.
다음 진행을 위해, 위의 스크립트 태그안에 JavaScript 코드를 작성합니다. (이 튜토리얼에서는) 진보된 라이브 리로드가 없기 때문에, 수정 사항을 저장한 다음에는 브라우저를 새로고침해서 확인해야 합니다. 서버를 시작한 다음 브라우저에서 `http://localhost:3000`를 열어 따라해 보세요. 아무런 수정도 하지 않았다면, 최초 로드시 우리가 만들 제품의 완성품을 확인할 수 있을 것입니다. 작업할 준비가 되면, 이전의 `<script>` 태그를 삭제하고 진행하세요.
> 주의:
>
@@ -126,6 +128,8 @@ JSX의 사용은 선택적이지만 JSX 문법이 일반 JavsScript보다 사용
`ReactDOM.render()`는 최상위 컴포넌트의 인스턴스를 만들고, 두 번째 인수로 전달받은 DOM 엘리먼트에 마크업을 삽입해 프레임워크를 시작합니다.
`ReactDOM` 모듈은 DOM 특정 메소드를 노출해, `React`가 코어 툴을 다른 플렛폼(예를 들어, [React Native](http://facebook.github.io/react-native/))에 공유할 수 있게 합니다.
## 컴포넌트 조합하기
이제 `CommentList``CommentForm`을 위한 뼈대를 구축해 봅시다. 이전과 마찬가지로 단순히 `<div>` 태그 하나 입니다. 파일에 두 컴포넌트를 추가해, 이미 있는 `CommentBox` 선언을 참고로 `ReactDOM.render`를 호출합시다.
@@ -224,8 +228,8 @@ Markdown은 텍스트를 포맷팅하는 간단한 방식입니다. 예를 들
```html{9}
<!-- index.html -->
<head>
<meta charset="UTF-8" />
<title>Hello React</title>
<meta charset="utf-8" />
<title>React Tutorial</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/{{site.react_version}}/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/{{site.react_version}}/react-dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script>
@@ -258,17 +262,21 @@ var Comment = React.createClass({
React는 이런 식으로 [XSS 공격](https://en.wikipedia.org/wiki/Cross-site_scripting)을 예방합니다. 우회할 방법이 있긴 하지만 프레임워크는 사용하지 않도록 경고하고 있습니다:
```javascript{4,10}
```javascript{4,14}
// tutorial7.js
var Comment = React.createClass({
render: function() {
rawMarkup: function() {
var rawMarkup = marked(this.props.children.toString(), {sanitize: true});
return { __html: rawMarkup };
},
render: function() {
return (
<div className="comment">
<h2 className="commentAuthor">
{this.props.author}
</h2>
<span dangerouslySetInnerHTML={{"{{"}}__html: rawMarkup}} />
<span dangerouslySetInnerHTML={this.rawMarkup()} />
</div>
);
}
@@ -344,13 +352,15 @@ var CommentList = React.createClass({
```javascript{3}
// tutorial11.js
ReactDOM.render(
<CommentBox url="comments.json" />,
<CommentBox url="/api/comments" />,
document.getElementById('content')
);
```
이 컴포넌트는 이전 것과 다르게, 스스로 다시 렌더링해야 합니다. 컴포넌트는 서버에서 요청이 들어올때까지는 아무 데이터도 가지고 있지 않다가, 특정한 시점에서 새로운 댓글을 렌더할 필요가 있을 것입니다.
주의: 이 단계에서 코드는 아직 동작하지 않습니다.
### 반응적 state
지금까지, 각각의 컴포넌트는 props를 기반으로 한번 렌더되었습니다. `props`는 불변성을 갖습니다: 그것들은 부모에서 전달되어 부모에게 "소유" 되어 있습니다. 컴포넌트에 상호작용을 구현하기 위해서, 가변성을 갖는 **state**를 소개합니다. `this.state`는 컴포넌트에 한정(private)되며 `this.setState()`를 통해 변경할 수 있습니다. state가 업데이트 되면, 컴포넌트는 자신을 스스로 다시 렌더링합니다.
@@ -381,20 +391,15 @@ var CommentBox = React.createClass({
### state 업데이트하기
컴포넌트의 최초 생성 시에, 서버에서 GET 방식으로 JSON을 넘겨받아 최신의 데이터가 state에 반영되길 원했습니다. 실제 애플리케이션에선 이것이 동적인 엔드포인트이지만, 이 예제에서는 단순히하기 위해 comments의 배열이 담긴 정적 JSON 파일 `public/comments.json`을 사용하겠습니다.
컴포넌트의 최초 생성 시에, 서버에서 GET 방식으로 JSON을 넘겨받아 최신의 데이터가 state에 반영되길 원했습니다. jQuery를 사용해 서버에 비동기 요청을 만들어 필요한 데이터를 빨리 가져올 수 있게 하겠습니다. 이런 식입니다.
```javascript
// tutorial13.json
```json
[
{"author": "Pete Hunt", "text": "댓글입니다"},
{"author": "Jordan Walke", "text": "*또 다른* 댓글입니다"}
]
```
서버에 비동기 요청을 위해 jQuery를 사용합니다.
주의: 우리의 앱이 AJAX 애플리케이션으로 변화하고 있기 때문에, 이제 파일 시스템의 파일을 참조하는 대신 웹서버를 사용하도록 앱을 개발해야 합니다. [위에서 언급한 바와 같이](#running-a-server), 우리는 튜토리얼의 나머지 부분에 필요한 기능을 제공하는 서버를 몇 가지 준비해 놓았습니다. [GitHub에 올려놓았으니](https://github.com/reactjs/react-tutorial) 확인해 보세요.
```javascript{6-18}
// tutorial13.js
var CommentBox = React.createClass({
@@ -463,13 +468,13 @@ var CommentBox = React.createClass({
});
ReactDOM.render(
<CommentBox url="comments.json" pollInterval={2000} />,
<CommentBox url="/api/comments" pollInterval={2000} />,
document.getElementById('content')
);
```
우리가 여기서 한것은 AJAX 호출을 별도의 메소드로 분리하고 컴포넌트가 처음 로드된 시점부터 2초 간격으로 계속 호출되도록 한 것입니다. 브라우저에서 직접 돌려보고 `comments.json`파일을 수정해보세요; 2초 간격으로 변화되는 모습이 보일 것입니다!
우리가 여기서 한것은 AJAX 호출을 별도의 메소드로 분리하고 컴포넌트가 처음 로드된 시점부터 2초 간격으로 계속 호출되도록 한 것입니다. 브라우저에서 직접 돌려보고 `comments.json` 파일(서버의 같은 디렉토리에 있습니다)을 수정해보세요. 2초 간격으로 변화되는 모습이 보일 것입니다!
### 새로운 댓글 추가하기
@@ -497,14 +502,14 @@ var CommentForm = React.createClass({
var CommentForm = React.createClass({
handleSubmit: function(e) {
e.preventDefault();
var author = ReactDOM.findDOMNode(this.refs.author).value.trim();
var text = ReactDOM.findDOMNode(this.refs.text).value.trim();
var author = this.refs.author.value.trim();
var text = this.refs.text.value.trim();
if (!text || !author) {
return;
}
// TODO: 서버에 요청을 전송합니다
ReactDOM.findDOMNode(this.refs.author).value = '';
ReactDOM.findDOMNode(this.refs.text).value = '';
this.refs.author.value = '';
this.refs.text.value = '';
return;
},
render: function() {
@@ -527,7 +532,7 @@ React는 카멜케이스 네이밍 컨벤션으로 컴포넌트에 이벤트 핸
##### Refs
우리는 자식 컴포넌트의 이름을 지정하기 위해 `ref` 어트리뷰트를, 컴포넌트를 참조하기 위해 `this.refs`를 사용합니다. 고유한(native) 브라우저 DOM 엘리먼트를 얻기 위해 `ReactDOM.findDOMNode(component)`를 호출할 수 있습니다.
자식 컴포넌트의 이름을 지정하기 위해 `ref` 어트리뷰트를, DOM 노드를 참조하기 위해 `this.refs`를 사용합니다.
##### props으로 콜백 처리하기
@@ -580,14 +585,14 @@ var CommentBox = React.createClass({
var CommentForm = React.createClass({
handleSubmit: function(e) {
e.preventDefault();
var author = ReactDOM.findDOMNode(this.refs.author).value.trim();
var text = ReactDOM.findDOMNode(this.refs.text).value.trim();
var author = this.refs.author.value.trim();
var text = this.refs.text.value.trim();
if (!text || !author) {
return;
}
this.props.onCommentSubmit({author: author, text: text});
ReactDOM.findDOMNode(this.refs.author).value = '';
ReactDOM.findDOMNode(this.refs.text).value = '';
this.refs.author.value = '';
this.refs.text.value = '';
return;
},
render: function() {
@@ -657,7 +662,7 @@ var CommentBox = React.createClass({
우리의 애플리케이션은 이제 모든 기능을 갖추었습니다. 하지만 댓글이 목록에 업데이트되기 전에 완료요청을 기다리는 게 조금 느린듯한 느낌이 드네요. 우리는 낙관적 업데이트를 통해 댓글이 목록에 추가되도록 함으로써 앱이 좀 더 빨라진 것처럼 느껴지도록 할 수 있습니다.
```javascript{17-19}
```javascript{17-19,29}
// tutorial20.js
var CommentBox = React.createClass({
loadCommentsFromServer: function() {
@@ -686,6 +691,7 @@ var CommentBox = React.createClass({
this.setState({data: data});
}.bind(this),
error: function(xhr, status, err) {
this.setState({data: comments});
console.error(this.props.url, status, err.toString());
}.bind(this)
});

187
docs/docs/tutorial.md Normal file → Executable file
View File

@@ -31,7 +31,7 @@ For sake of simplicity, the server we will run uses a `JSON` file as a database.
### Getting started
For this tutorial, we're going to make it as easy as possible. Included in the server package discussed above is an HTML file which we'll work in. Open up `public/index.html` in your favorite editor. It should look something like this (with perhaps some minor differences, we'll add an additional `<script>` tag later):
For this tutorial, we're going to make it as easy as possible. Included in the server package discussed above is an HTML file which we'll work in. Open up `public/index.html` in your favorite editor. It should look something like this:
```html
<!-- index.html -->
@@ -44,6 +44,7 @@ For this tutorial, we're going to make it as easy as possible. Included in the s
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/{{site.react_version}}/react-dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/marked/0.3.2/marked.min.js"></script>
</head>
<body>
<div id="content"></div>
@@ -129,6 +130,8 @@ You do not have to return basic HTML. You can return a tree of components that y
The `ReactDOM` module exposes DOM-specific methods, while `React` has the core tools shared by React on different platforms (e.g., [React Native](http://facebook.github.io/react-native/)).
It is important that `ReactDOM.render` remain at the bottom of the script for this tutorial. `ReactDOM.render` should only be called after the composite components have been defined.
## Composing components
Let's build skeletons for `CommentList` and `CommentForm` which will, again, be simple `<div>`s. Add these two components to your file, keeping the existing `CommentBox` declaration and `ReactDOM.render` call:
@@ -221,22 +224,7 @@ Note that we have passed some data from the parent `CommentList` component to th
Markdown is a simple way to format your text inline. For example, surrounding text with asterisks will make it emphasized.
First, add the third-party library **marked** to your application. This is a JavaScript library which takes Markdown text and converts it to raw HTML. This requires a script tag in your head (which we have already included in the React playground):
```html{9}
<!-- index.html -->
<head>
<meta charset="utf-8" />
<title>React Tutorial</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/{{site.react_version}}/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/{{site.react_version}}/react-dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/marked/0.3.2/marked.min.js"></script>
</head>
```
Next, let's convert the comment text to Markdown and output it:
In this tutorial we use a third-party library **marked** which takes Markdown text and converts it to raw HTML. We already included this library with the original markup for the page, so we can just start using it. Let's convert the comment text to Markdown and output it:
```javascript{9}
// tutorial6.js
@@ -260,7 +248,7 @@ But there's a problem! Our rendered comments look like this in the browser: "`<p
That's React protecting you from an [XSS attack](https://en.wikipedia.org/wiki/Cross-site_scripting). There's a way to get around it but the framework warns you not to use it:
```javascript{4,14}
```javascript{3-6,14}
// tutorial7.js
var Comment = React.createClass({
rawMarkup: function() {
@@ -292,8 +280,8 @@ So far we've been inserting the comments directly in the source code. Instead, l
```javascript
// tutorial8.js
var data = [
{author: "Pete Hunt", text: "This is one comment"},
{author: "Jordan Walke", text: "This is *another* comment"}
{id: 1, author: "Pete Hunt", text: "This is one comment"},
{id: 2, author: "Jordan Walke", text: "This is *another* comment"}
];
```
@@ -325,9 +313,9 @@ Now that the data is available in the `CommentList`, let's render the comments d
// tutorial10.js
var CommentList = React.createClass({
render: function() {
var commentNodes = this.props.data.map(function (comment) {
var commentNodes = this.props.data.map(function(comment) {
return (
<Comment author={comment.author}>
<Comment author={comment.author} key={comment.id}>
{comment.text}
</Comment>
);
@@ -388,7 +376,7 @@ var CommentBox = React.createClass({
`getInitialState()` executes exactly once during the lifecycle of the component and sets up the initial state of the component.
#### Updating state
When the component is first created, we want to GET some JSON from the server and update the state to reflect the latest data. We're going to use jQuery to make an asynchronous request to the server we started earlier to fetch the data we need. It will look something like this:
When the component is first created, we want to GET some JSON from the server and update the state to reflect the latest data. We're going to use jQuery to make an asynchronous request to the server we started earlier to fetch the data we need. The data is already included in the server you started (based on the `comments.json` file), so once it's fetched, `this.state.data` will look something like this:
```json
[
@@ -428,7 +416,7 @@ var CommentBox = React.createClass({
});
```
Here, `componentDidMount` is a method called automatically by React when a component is rendered. The key to dynamic updates is the call to `this.setState()`. We replace the old array of comments with the new one from the server and the UI automatically updates itself. Because of this reactivity, it is only a minor change to add live updates. We will use simple polling here but you could easily use WebSockets or other technologies.
Here, `componentDidMount` is a method called automatically by React after a component is rendered for the first time. The key to dynamic updates is the call to `this.setState()`. We replace the old array of comments with the new one from the server and the UI automatically updates itself. Because of this reactivity, it is only a minor change to add live updates. We will use simple polling here but you could easily use WebSockets or other technologies.
```javascript{3,15,20-21,35}
// tutorial14.js
@@ -492,28 +480,39 @@ var CommentForm = React.createClass({
});
```
Let's make the form interactive. When the user submits the form, we should clear it, submit a request to the server, and refresh the list of comments. To start, let's listen for the form's submit event and clear it.
#### Controlled components
```javascript{3-14,16-19}
With the traditional DOM, `input` elements are rendered and the browser manages the state (its rendered value). As a result, the state of the actual DOM will differ from that of the component. This is not ideal as the state of the view will differ from that of the component. In React, components should always represent the state of the view and not only at the point of initialization.
Hence, we will be using `this.state` to save the user's input as it is entered. We define an initial `state` with two properties `author` and `text` and set them to be empty strings. In our `<input>` elements, we set the `value` prop to reflect the `state` of the component and attach `onChange` handlers to them. These `<input>` elements with a `value` set are called controlled components. Read more about controlled components on the [Forms article](/react/docs/forms.html#controlled-components).
```javascript{3-11,15-26}
// tutorial16.js
var CommentForm = React.createClass({
handleSubmit: function(e) {
e.preventDefault();
var author = this.refs.author.value.trim();
var text = this.refs.text.value.trim();
if (!text || !author) {
return;
}
// TODO: send request to the server
this.refs.author.value = '';
this.refs.text.value = '';
return;
getInitialState: function() {
return {author: '', text: ''};
},
handleAuthorChange: function(e) {
this.setState({author: e.target.value});
},
handleTextChange: function(e) {
this.setState({text: e.target.value});
},
render: function() {
return (
<form className="commentForm" onSubmit={this.handleSubmit}>
<input type="text" placeholder="Your name" ref="author" />
<input type="text" placeholder="Say something..." ref="text" />
<form className="commentForm">
<input
type="text"
placeholder="Your name"
value={this.state.author}
onChange={this.handleAuthorChange}
/>
<input
type="text"
placeholder="Say something..."
value={this.state.text}
onChange={this.handleTextChange}
/>
<input type="submit" value="Post" />
</form>
);
@@ -521,24 +520,70 @@ var CommentForm = React.createClass({
});
```
##### Events
#### Events
React attaches event handlers to components using a camelCase naming convention. We attach an `onSubmit` handler to the form that clears the form fields when the form is submitted with valid input.
React attaches event handlers to components using a camelCase naming convention. We attach `onChange` handlers to the two `<input>` elements. Now, as the user enters text into the `<input>` fields, the attached `onChange` callbacks are fired and the `state` of the component is modified. Subsequently, the rendered value of the `input` element will be updated to reflect the current component `state`.
#### Submitting the form
Let's make the form interactive. When the user submits the form, we should clear it, submit a request to the server, and refresh the list of comments. To start, let's listen for the form's submit event and clear it.
```javascript{12-21,24}
// tutorial17.js
var CommentForm = React.createClass({
getInitialState: function() {
return {author: '', text: ''};
},
handleAuthorChange: function(e) {
this.setState({author: e.target.value});
},
handleTextChange: function(e) {
this.setState({text: e.target.value});
},
handleSubmit: function(e) {
e.preventDefault();
var author = this.state.author.trim();
var text = this.state.text.trim();
if (!text || !author) {
return;
}
// TODO: send request to the server
this.setState({author: '', text: ''});
},
render: function() {
return (
<form className="commentForm" onSubmit={this.handleSubmit}>
<input
type="text"
placeholder="Your name"
value={this.state.author}
onChange={this.handleAuthorChange}
/>
<input
type="text"
placeholder="Say something..."
value={this.state.text}
onChange={this.handleTextChange}
/>
<input type="submit" value="Post" />
</form>
);
}
});
```
We attach an `onSubmit` handler to the form that clears the form fields when the form is submitted with valid input.
Call `preventDefault()` on the event to prevent the browser's default action of submitting the form.
##### Refs
We use the `ref` attribute to assign a name to a child component and `this.refs` to reference the DOM node.
##### Callbacks as props
#### Callbacks as props
When a user submits a comment, we will need to refresh the list of comments to include the new one. It makes sense to do all of this logic in `CommentBox` since `CommentBox` owns the state that represents the list of comments.
We need to pass data from the child component back up to its parent. We do this in our parent's `render` method by passing a new callback (`handleCommentSubmit`) into the child, binding it to the child's `onCommentSubmit` event. Whenever the event is triggered, the callback will be invoked:
```javascript{16-18,31}
// tutorial17.js
// tutorial18.js
var CommentBox = React.createClass({
loadCommentsFromServer: function() {
$.ajax({
@@ -577,26 +622,43 @@ var CommentBox = React.createClass({
Let's call the callback from the `CommentForm` when the user submits the form:
```javascript{10}
// tutorial18.js
```javascript{19}
// tutorial19.js
var CommentForm = React.createClass({
getInitialState: function() {
return {author: '', text: ''};
},
handleAuthorChange: function(e) {
this.setState({author: e.target.value});
},
handleTextChange: function(e) {
this.setState({text: e.target.value});
},
handleSubmit: function(e) {
e.preventDefault();
var author = this.refs.author.value.trim();
var text = this.refs.text.value.trim();
var author = this.state.author.trim();
var text = this.state.text.trim();
if (!text || !author) {
return;
}
this.props.onCommentSubmit({author: author, text: text});
this.refs.author.value = '';
this.refs.text.value = '';
return;
this.setState({author: '', text: ''});
},
render: function() {
return (
<form className="commentForm" onSubmit={this.handleSubmit}>
<input type="text" placeholder="Your name" ref="author" />
<input type="text" placeholder="Say something..." ref="text" />
<input
type="text"
placeholder="Your name"
value={this.state.author}
onChange={this.handleAuthorChange}
/>
<input
type="text"
placeholder="Say something..."
value={this.state.text}
onChange={this.handleTextChange}
/>
<input type="submit" value="Post" />
</form>
);
@@ -607,7 +669,7 @@ var CommentForm = React.createClass({
Now that the callbacks are in place, all we have to do is submit to the server and refresh the list:
```javascript{17-28}
// tutorial19.js
// tutorial20.js
var CommentBox = React.createClass({
loadCommentsFromServer: function() {
$.ajax({
@@ -659,8 +721,8 @@ var CommentBox = React.createClass({
Our application is now feature complete but it feels slow to have to wait for the request to complete before your comment appears in the list. We can optimistically add this comment to the list to make the app feel faster.
```javascript{17-19}
// tutorial20.js
```javascript{17-23,33}
// tutorial21.js
var CommentBox = React.createClass({
loadCommentsFromServer: function() {
$.ajax({
@@ -677,6 +739,10 @@ var CommentBox = React.createClass({
},
handleCommentSubmit: function(comment) {
var comments = this.state.data;
// Optimistically set an id on the new comment. It will be replaced by an
// id generated by the server. In a production application you would likely
// not use Date.now() for this and would have a more robust system in place.
comment.id = Date.now();
var newComments = comments.concat([comment]);
this.setState({data: newComments});
$.ajax({
@@ -688,6 +754,7 @@ var CommentBox = React.createClass({
this.setState({data: data});
}.bind(this),
error: function(xhr, status, err) {
this.setState({data: comments});
console.error(this.props.url, status, err.toString());
}.bind(this)
});

Some files were not shown because too many files have changed in this diff Show More