├── LICENSE
└── README.md
/LICENSE:
--------------------------------------------------------------------------------
1 |
2 | GNU Free Documentation License
3 | Version 1.3, 3 November 2008
4 |
5 |
6 | Copyright (C) 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
7 |
8 | Everyone is permitted to copy and distribute verbatim copies
9 | of this license document, but changing it is not allowed.
10 |
11 | 0. PREAMBLE
12 |
13 | The purpose of this License is to make a manual, textbook, or other
14 | functional and useful document "free" in the sense of freedom: to
15 | assure everyone the effective freedom to copy and redistribute it,
16 | with or without modifying it, either commercially or noncommercially.
17 | Secondarily, this License preserves for the author and publisher a way
18 | to get credit for their work, while not being considered responsible
19 | for modifications made by others.
20 |
21 | This License is a kind of "copyleft", which means that derivative
22 | works of the document must themselves be free in the same sense. It
23 | complements the GNU General Public License, which is a copyleft
24 | license designed for free software.
25 |
26 | We have designed this License in order to use it for manuals for free
27 | software, because free software needs free documentation: a free
28 | program should come with manuals providing the same freedoms that the
29 | software does. But this License is not limited to software manuals;
30 | it can be used for any textual work, regardless of subject matter or
31 | whether it is published as a printed book. We recommend this License
32 | principally for works whose purpose is instruction or reference.
33 |
34 |
35 | 1. APPLICABILITY AND DEFINITIONS
36 |
37 | This License applies to any manual or other work, in any medium, that
38 | contains a notice placed by the copyright holder saying it can be
39 | distributed under the terms of this License. Such a notice grants a
40 | world-wide, royalty-free license, unlimited in duration, to use that
41 | work under the conditions stated herein. The "Document", below,
42 | refers to any such manual or work. Any member of the public is a
43 | licensee, and is addressed as "you". You accept the license if you
44 | copy, modify or distribute the work in a way requiring permission
45 | under copyright law.
46 |
47 | A "Modified Version" of the Document means any work containing the
48 | Document or a portion of it, either copied verbatim, or with
49 | modifications and/or translated into another language.
50 |
51 | A "Secondary Section" is a named appendix or a front-matter section of
52 | the Document that deals exclusively with the relationship of the
53 | publishers or authors of the Document to the Document's overall
54 | subject (or to related matters) and contains nothing that could fall
55 | directly within that overall subject. (Thus, if the Document is in
56 | part a textbook of mathematics, a Secondary Section may not explain
57 | any mathematics.) The relationship could be a matter of historical
58 | connection with the subject or with related matters, or of legal,
59 | commercial, philosophical, ethical or political position regarding
60 | them.
61 |
62 | The "Invariant Sections" are certain Secondary Sections whose titles
63 | are designated, as being those of Invariant Sections, in the notice
64 | that says that the Document is released under this License. If a
65 | section does not fit the above definition of Secondary then it is not
66 | allowed to be designated as Invariant. The Document may contain zero
67 | Invariant Sections. If the Document does not identify any Invariant
68 | Sections then there are none.
69 |
70 | The "Cover Texts" are certain short passages of text that are listed,
71 | as Front-Cover Texts or Back-Cover Texts, in the notice that says that
72 | the Document is released under this License. A Front-Cover Text may
73 | be at most 5 words, and a Back-Cover Text may be at most 25 words.
74 |
75 | A "Transparent" copy of the Document means a machine-readable copy,
76 | represented in a format whose specification is available to the
77 | general public, that is suitable for revising the document
78 | straightforwardly with generic text editors or (for images composed of
79 | pixels) generic paint programs or (for drawings) some widely available
80 | drawing editor, and that is suitable for input to text formatters or
81 | for automatic translation to a variety of formats suitable for input
82 | to text formatters. A copy made in an otherwise Transparent file
83 | format whose markup, or absence of markup, has been arranged to thwart
84 | or discourage subsequent modification by readers is not Transparent.
85 | An image format is not Transparent if used for any substantial amount
86 | of text. A copy that is not "Transparent" is called "Opaque".
87 |
88 | Examples of suitable formats for Transparent copies include plain
89 | ASCII without markup, Texinfo input format, LaTeX input format, SGML
90 | or XML using a publicly available DTD, and standard-conforming simple
91 | HTML, PostScript or PDF designed for human modification. Examples of
92 | transparent image formats include PNG, XCF and JPG. Opaque formats
93 | include proprietary formats that can be read and edited only by
94 | proprietary word processors, SGML or XML for which the DTD and/or
95 | processing tools are not generally available, and the
96 | machine-generated HTML, PostScript or PDF produced by some word
97 | processors for output purposes only.
98 |
99 | The "Title Page" means, for a printed book, the title page itself,
100 | plus such following pages as are needed to hold, legibly, the material
101 | this License requires to appear in the title page. For works in
102 | formats which do not have any title page as such, "Title Page" means
103 | the text near the most prominent appearance of the work's title,
104 | preceding the beginning of the body of the text.
105 |
106 | The "publisher" means any person or entity that distributes copies of
107 | the Document to the public.
108 |
109 | A section "Entitled XYZ" means a named subunit of the Document whose
110 | title either is precisely XYZ or contains XYZ in parentheses following
111 | text that translates XYZ in another language. (Here XYZ stands for a
112 | specific section name mentioned below, such as "Acknowledgements",
113 | "Dedications", "Endorsements", or "History".) To "Preserve the Title"
114 | of such a section when you modify the Document means that it remains a
115 | section "Entitled XYZ" according to this definition.
116 |
117 | The Document may include Warranty Disclaimers next to the notice which
118 | states that this License applies to the Document. These Warranty
119 | Disclaimers are considered to be included by reference in this
120 | License, but only as regards disclaiming warranties: any other
121 | implication that these Warranty Disclaimers may have is void and has
122 | no effect on the meaning of this License.
123 |
124 | 2. VERBATIM COPYING
125 |
126 | You may copy and distribute the Document in any medium, either
127 | commercially or noncommercially, provided that this License, the
128 | copyright notices, and the license notice saying this License applies
129 | to the Document are reproduced in all copies, and that you add no
130 | other conditions whatsoever to those of this License. You may not use
131 | technical measures to obstruct or control the reading or further
132 | copying of the copies you make or distribute. However, you may accept
133 | compensation in exchange for copies. If you distribute a large enough
134 | number of copies you must also follow the conditions in section 3.
135 |
136 | You may also lend copies, under the same conditions stated above, and
137 | you may publicly display copies.
138 |
139 |
140 | 3. COPYING IN QUANTITY
141 |
142 | If you publish printed copies (or copies in media that commonly have
143 | printed covers) of the Document, numbering more than 100, and the
144 | Document's license notice requires Cover Texts, you must enclose the
145 | copies in covers that carry, clearly and legibly, all these Cover
146 | Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on
147 | the back cover. Both covers must also clearly and legibly identify
148 | you as the publisher of these copies. The front cover must present
149 | the full title with all words of the title equally prominent and
150 | visible. You may add other material on the covers in addition.
151 | Copying with changes limited to the covers, as long as they preserve
152 | the title of the Document and satisfy these conditions, can be treated
153 | as verbatim copying in other respects.
154 |
155 | If the required texts for either cover are too voluminous to fit
156 | legibly, you should put the first ones listed (as many as fit
157 | reasonably) on the actual cover, and continue the rest onto adjacent
158 | pages.
159 |
160 | If you publish or distribute Opaque copies of the Document numbering
161 | more than 100, you must either include a machine-readable Transparent
162 | copy along with each Opaque copy, or state in or with each Opaque copy
163 | a computer-network location from which the general network-using
164 | public has access to download using public-standard network protocols
165 | a complete Transparent copy of the Document, free of added material.
166 | If you use the latter option, you must take reasonably prudent steps,
167 | when you begin distribution of Opaque copies in quantity, to ensure
168 | that this Transparent copy will remain thus accessible at the stated
169 | location until at least one year after the last time you distribute an
170 | Opaque copy (directly or through your agents or retailers) of that
171 | edition to the public.
172 |
173 | It is requested, but not required, that you contact the authors of the
174 | Document well before redistributing any large number of copies, to
175 | give them a chance to provide you with an updated version of the
176 | Document.
177 |
178 |
179 | 4. MODIFICATIONS
180 |
181 | You may copy and distribute a Modified Version of the Document under
182 | the conditions of sections 2 and 3 above, provided that you release
183 | the Modified Version under precisely this License, with the Modified
184 | Version filling the role of the Document, thus licensing distribution
185 | and modification of the Modified Version to whoever possesses a copy
186 | of it. In addition, you must do these things in the Modified Version:
187 |
188 | A. Use in the Title Page (and on the covers, if any) a title distinct
189 | from that of the Document, and from those of previous versions
190 | (which should, if there were any, be listed in the History section
191 | of the Document). You may use the same title as a previous version
192 | if the original publisher of that version gives permission.
193 | B. List on the Title Page, as authors, one or more persons or entities
194 | responsible for authorship of the modifications in the Modified
195 | Version, together with at least five of the principal authors of the
196 | Document (all of its principal authors, if it has fewer than five),
197 | unless they release you from this requirement.
198 | C. State on the Title page the name of the publisher of the
199 | Modified Version, as the publisher.
200 | D. Preserve all the copyright notices of the Document.
201 | E. Add an appropriate copyright notice for your modifications
202 | adjacent to the other copyright notices.
203 | F. Include, immediately after the copyright notices, a license notice
204 | giving the public permission to use the Modified Version under the
205 | terms of this License, in the form shown in the Addendum below.
206 | G. Preserve in that license notice the full lists of Invariant Sections
207 | and required Cover Texts given in the Document's license notice.
208 | H. Include an unaltered copy of this License.
209 | I. Preserve the section Entitled "History", Preserve its Title, and add
210 | to it an item stating at least the title, year, new authors, and
211 | publisher of the Modified Version as given on the Title Page. If
212 | there is no section Entitled "History" in the Document, create one
213 | stating the title, year, authors, and publisher of the Document as
214 | given on its Title Page, then add an item describing the Modified
215 | Version as stated in the previous sentence.
216 | J. Preserve the network location, if any, given in the Document for
217 | public access to a Transparent copy of the Document, and likewise
218 | the network locations given in the Document for previous versions
219 | it was based on. These may be placed in the "History" section.
220 | You may omit a network location for a work that was published at
221 | least four years before the Document itself, or if the original
222 | publisher of the version it refers to gives permission.
223 | K. For any section Entitled "Acknowledgements" or "Dedications",
224 | Preserve the Title of the section, and preserve in the section all
225 | the substance and tone of each of the contributor acknowledgements
226 | and/or dedications given therein.
227 | L. Preserve all the Invariant Sections of the Document,
228 | unaltered in their text and in their titles. Section numbers
229 | or the equivalent are not considered part of the section titles.
230 | M. Delete any section Entitled "Endorsements". Such a section
231 | may not be included in the Modified Version.
232 | N. Do not retitle any existing section to be Entitled "Endorsements"
233 | or to conflict in title with any Invariant Section.
234 | O. Preserve any Warranty Disclaimers.
235 |
236 | If the Modified Version includes new front-matter sections or
237 | appendices that qualify as Secondary Sections and contain no material
238 | copied from the Document, you may at your option designate some or all
239 | of these sections as invariant. To do this, add their titles to the
240 | list of Invariant Sections in the Modified Version's license notice.
241 | These titles must be distinct from any other section titles.
242 |
243 | You may add a section Entitled "Endorsements", provided it contains
244 | nothing but endorsements of your Modified Version by various
245 | parties--for example, statements of peer review or that the text has
246 | been approved by an organization as the authoritative definition of a
247 | standard.
248 |
249 | You may add a passage of up to five words as a Front-Cover Text, and a
250 | passage of up to 25 words as a Back-Cover Text, to the end of the list
251 | of Cover Texts in the Modified Version. Only one passage of
252 | Front-Cover Text and one of Back-Cover Text may be added by (or
253 | through arrangements made by) any one entity. If the Document already
254 | includes a cover text for the same cover, previously added by you or
255 | by arrangement made by the same entity you are acting on behalf of,
256 | you may not add another; but you may replace the old one, on explicit
257 | permission from the previous publisher that added the old one.
258 |
259 | The author(s) and publisher(s) of the Document do not by this License
260 | give permission to use their names for publicity for or to assert or
261 | imply endorsement of any Modified Version.
262 |
263 |
264 | 5. COMBINING DOCUMENTS
265 |
266 | You may combine the Document with other documents released under this
267 | License, under the terms defined in section 4 above for modified
268 | versions, provided that you include in the combination all of the
269 | Invariant Sections of all of the original documents, unmodified, and
270 | list them all as Invariant Sections of your combined work in its
271 | license notice, and that you preserve all their Warranty Disclaimers.
272 |
273 | The combined work need only contain one copy of this License, and
274 | multiple identical Invariant Sections may be replaced with a single
275 | copy. If there are multiple Invariant Sections with the same name but
276 | different contents, make the title of each such section unique by
277 | adding at the end of it, in parentheses, the name of the original
278 | author or publisher of that section if known, or else a unique number.
279 | Make the same adjustment to the section titles in the list of
280 | Invariant Sections in the license notice of the combined work.
281 |
282 | In the combination, you must combine any sections Entitled "History"
283 | in the various original documents, forming one section Entitled
284 | "History"; likewise combine any sections Entitled "Acknowledgements",
285 | and any sections Entitled "Dedications". You must delete all sections
286 | Entitled "Endorsements".
287 |
288 |
289 | 6. COLLECTIONS OF DOCUMENTS
290 |
291 | You may make a collection consisting of the Document and other
292 | documents released under this License, and replace the individual
293 | copies of this License in the various documents with a single copy
294 | that is included in the collection, provided that you follow the rules
295 | of this License for verbatim copying of each of the documents in all
296 | other respects.
297 |
298 | You may extract a single document from such a collection, and
299 | distribute it individually under this License, provided you insert a
300 | copy of this License into the extracted document, and follow this
301 | License in all other respects regarding verbatim copying of that
302 | document.
303 |
304 |
305 | 7. AGGREGATION WITH INDEPENDENT WORKS
306 |
307 | A compilation of the Document or its derivatives with other separate
308 | and independent documents or works, in or on a volume of a storage or
309 | distribution medium, is called an "aggregate" if the copyright
310 | resulting from the compilation is not used to limit the legal rights
311 | of the compilation's users beyond what the individual works permit.
312 | When the Document is included in an aggregate, this License does not
313 | apply to the other works in the aggregate which are not themselves
314 | derivative works of the Document.
315 |
316 | If the Cover Text requirement of section 3 is applicable to these
317 | copies of the Document, then if the Document is less than one half of
318 | the entire aggregate, the Document's Cover Texts may be placed on
319 | covers that bracket the Document within the aggregate, or the
320 | electronic equivalent of covers if the Document is in electronic form.
321 | Otherwise they must appear on printed covers that bracket the whole
322 | aggregate.
323 |
324 |
325 | 8. TRANSLATION
326 |
327 | Translation is considered a kind of modification, so you may
328 | distribute translations of the Document under the terms of section 4.
329 | Replacing Invariant Sections with translations requires special
330 | permission from their copyright holders, but you may include
331 | translations of some or all Invariant Sections in addition to the
332 | original versions of these Invariant Sections. You may include a
333 | translation of this License, and all the license notices in the
334 | Document, and any Warranty Disclaimers, provided that you also include
335 | the original English version of this License and the original versions
336 | of those notices and disclaimers. In case of a disagreement between
337 | the translation and the original version of this License or a notice
338 | or disclaimer, the original version will prevail.
339 |
340 | If a section in the Document is Entitled "Acknowledgements",
341 | "Dedications", or "History", the requirement (section 4) to Preserve
342 | its Title (section 1) will typically require changing the actual
343 | title.
344 |
345 |
346 | 9. TERMINATION
347 |
348 | You may not copy, modify, sublicense, or distribute the Document
349 | except as expressly provided under this License. Any attempt
350 | otherwise to copy, modify, sublicense, or distribute it is void, and
351 | will automatically terminate your rights under this License.
352 |
353 | However, if you cease all violation of this License, then your license
354 | from a particular copyright holder is reinstated (a) provisionally,
355 | unless and until the copyright holder explicitly and finally
356 | terminates your license, and (b) permanently, if the copyright holder
357 | fails to notify you of the violation by some reasonable means prior to
358 | 60 days after the cessation.
359 |
360 | Moreover, your license from a particular copyright holder is
361 | reinstated permanently if the copyright holder notifies you of the
362 | violation by some reasonable means, this is the first time you have
363 | received notice of violation of this License (for any work) from that
364 | copyright holder, and you cure the violation prior to 30 days after
365 | your receipt of the notice.
366 |
367 | Termination of your rights under this section does not terminate the
368 | licenses of parties who have received copies or rights from you under
369 | this License. If your rights have been terminated and not permanently
370 | reinstated, receipt of a copy of some or all of the same material does
371 | not give you any rights to use it.
372 |
373 |
374 | 10. FUTURE REVISIONS OF THIS LICENSE
375 |
376 | The Free Software Foundation may publish new, revised versions of the
377 | GNU Free Documentation License from time to time. Such new versions
378 | will be similar in spirit to the present version, but may differ in
379 | detail to address new problems or concerns. See
380 | http://www.gnu.org/copyleft/.
381 |
382 | Each version of the License is given a distinguishing version number.
383 | If the Document specifies that a particular numbered version of this
384 | License "or any later version" applies to it, you have the option of
385 | following the terms and conditions either of that specified version or
386 | of any later version that has been published (not as a draft) by the
387 | Free Software Foundation. If the Document does not specify a version
388 | number of this License, you may choose any version ever published (not
389 | as a draft) by the Free Software Foundation. If the Document
390 | specifies that a proxy can decide which future versions of this
391 | License can be used, that proxy's public statement of acceptance of a
392 | version permanently authorizes you to choose that version for the
393 | Document.
394 |
395 | 11. RELICENSING
396 |
397 | "Massive Multiauthor Collaboration Site" (or "MMC Site") means any
398 | World Wide Web server that publishes copyrightable works and also
399 | provides prominent facilities for anybody to edit those works. A
400 | public wiki that anybody can edit is an example of such a server. A
401 | "Massive Multiauthor Collaboration" (or "MMC") contained in the site
402 | means any set of copyrightable works thus published on the MMC site.
403 |
404 | "CC-BY-SA" means the Creative Commons Attribution-Share Alike 3.0
405 | license published by Creative Commons Corporation, a not-for-profit
406 | corporation with a principal place of business in San Francisco,
407 | California, as well as future copyleft versions of that license
408 | published by that same organization.
409 |
410 | "Incorporate" means to publish or republish a Document, in whole or in
411 | part, as part of another Document.
412 |
413 | An MMC is "eligible for relicensing" if it is licensed under this
414 | License, and if all works that were first published under this License
415 | somewhere other than this MMC, and subsequently incorporated in whole or
416 | in part into the MMC, (1) had no cover texts or invariant sections, and
417 | (2) were thus incorporated prior to November 1, 2008.
418 |
419 | The operator of an MMC Site may republish an MMC contained in the site
420 | under CC-BY-SA on the same site at any time before August 1, 2009,
421 | provided the MMC is eligible for relicensing.
422 |
423 |
424 | ADDENDUM: How to use this License for your documents
425 |
426 | To use this License in a document you have written, include a copy of
427 | the License in the document and put the following copyright and
428 | license notices just after the title page:
429 |
430 | Copyright (c) YEAR YOUR NAME.
431 | Permission is granted to copy, distribute and/or modify this document
432 | under the terms of the GNU Free Documentation License, Version 1.3
433 | or any later version published by the Free Software Foundation;
434 | with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
435 | A copy of the license is included in the section entitled "GNU
436 | Free Documentation License".
437 |
438 | If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,
439 | replace the "with...Texts." line with this:
440 |
441 | with the Invariant Sections being LIST THEIR TITLES, with the
442 | Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.
443 |
444 | If you have Invariant Sections without Cover Texts, or some other
445 | combination of the three, merge those two alternatives to suit the
446 | situation.
447 |
448 | If your document contains nontrivial examples of program code, we
449 | recommend releasing these examples in parallel under your choice of
450 | free software license, such as the GNU General Public License,
451 | to permit their use in free software.
452 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # react-primer-draft
2 |
3 | A primer for building *Single-Page Applications* with [React](http://facebook.github.io/react/).
4 |
5 | ## Status
6 |
7 | This is a work in progress.
8 |
9 | At the time of writing, the examples were written for `React 0.12.x`. This guide will be updated with examples for `React 0.13` `ES6 classes` soon!
10 |
11 | ## Progress
12 |
13 | - [x] Part 1: Intro to React (completed)
14 | - [ ] Part 2: Harmony aka ES6 aka ES2015 (in progress)
15 |
16 | ## Table of Contents
17 | - [Author's Note](#authors-note)
18 | - [Part 0: Preface](#preface)
19 | - [0.1: What People are saying about React](#what-people-are-saying-about-react)
20 | - [0.2: React Community](#react-community)
21 | - [0.3: React Documentation](#react-documentation)
22 | - [Part 1: Intro to React](#intro-to-react)
23 | - [1.0: React Component](#react-component)
24 | - [1.1: React JSX](#react-jsx)
25 | - [1.2: React Supported Attributes](#react-supported-attributes)
26 | - [1.3: React Supported Events](#react-supported-events)
27 | - [1.4: React Supported Events Continued](#react-supported-events-continued)
28 | - [1.5: React Props](#react-props)
29 | - [1.5.1: getDefaultProps](#getdefaultprops)
30 | - [1.5.2: propTypes](#proptypes)
31 | - [1.5.3: refs](#refs)
32 | - [1.5.4: children](#children)
33 | - [1.5.5: className](#classname)
34 | - [1.5.6: Passing a Prop](#passing-a-prop)
35 | - [1.6: React State](#react-state)
36 | - [1.7: React Lifecycle Events](#react-lifecycle-events)
37 | - [1.7.1: Mounting: componentWillMount](#mounting-componentwillmount)
38 | - [1.7.2: Mounting: componentDidMount](#mounting-componentdidmount)
39 | - [1.7.3: Updating: componentWillReceiveProps](#updating-componentwillreceiveprops)
40 | - [1.7.4: Updating: shouldComponentUpdate](#updating-shouldcomponentupdate)
41 | - [1.7.5: Updating: componentWillUpdate](#updating-componentwillupdate)
42 | - [1.7.6: Updating: componentDidUpdate](#updating-componentdidupdate)
43 | - [1.7.7: Unmounting: componentWillUnmount](#unmounting-componentwillunmount)
44 | - [1.8: React Dynamic Children](#react-dynamic-children)
45 | - [1.8.1: key](#key)
46 | - [1.9: React Nested Views](#react-nested-views)
47 | - [1.10: React Mixins](#react-mixins)
48 | - [1.11: React Pure Render](#react-pure-render)
49 | - [1.12: React and 3rd Party Libraries](#react-and-3rd-party-libraries)
50 | - [1.13: React Component Parent and Child Communication](#react-component-parent-and-child-communication)
51 | - [1.14: React Fetching Data](#react-fetching-data)
52 | - [1.15: React Developer Tools](#react-developer-tools)
53 | - [Part 2: Harmony aka ES6 aka ES2015](#harmony-aka-es6-aka-es2015)
54 | - [2.1: Modules](#modules)
55 | - [2.1.1: import](#import)
56 | - [2.1.2: export](#export)
57 | - [2.2: Variable Assignment](#variable-assignment)
58 | - [2.2.1: const](#const)
59 | - [2.2.2: let](#let)
60 | - [2.3: Fat Arrow](#fat-arrow)
61 | - [2.4: Enhanced Object Literals](#enhanced-object-literals)
62 | - [2.5: Spread Operator](#spread-operator)
63 | - [2.6: Classes](#classes)
64 | - [2.7: Babel](#babel)
65 | - [Part 3: Useful Libraries](#useful-libraries)
66 | - [3.1: SuperAgent](#superagent)
67 | - [3.2: Bluebird](#bluebird)
68 | - [3.3: lodash](#lodash)
69 | - [3.4: normalizr](#normalizr)
70 | - [Part 4: Webpack](#webpack)
71 | - [4.1: Hot Module Replacement and Hot Reloading](#hot-module-replacement-and-hot-reloading)
72 | - [4.2: AST Transformations](#ast-transformations)
73 | - [Part 5: React Router](#react-router)
74 | - [Part 6: Flux](#flux)
75 | - [6.1: Alt](#alt)
76 | - [6.1.1: Alt Actions](#alt-actions)
77 | - [6.1.2: Alt Stores](#alt-stores)
78 | - [Part 7: Testing](#testing)
79 | - [7.1: Mocha](#mocha)
80 | - [Part 8: Rails (Bonus Chapter)](#rails)
81 | - [8.1: React Rails](#react-rails)
82 | - [8.2: Writing an API](#writing-an-api)
83 | - [8.3: Session Handling in React](#session-handling-in-react)
84 | - [8.4: Rails and React Build Process](#rails-and-react-build-process)
85 |
86 | ---
87 |
88 | ## Authors Note
89 |
90 | This primer makes use of several libraries, but it is by no means a "_React the right way_". It's just a introduction to how I am building my own React applications. The goal of this primer to help developers get familiar with React and dive right in. Maybe you will come up with approaches that work better for you and I hope that you share them with the community! Or if you're already well versed, help improve this document so others in the community can benefit. Sharing is caring!
91 |
92 | This guide is dedicated to the engineers at [Jellyvision](http://www.jellyvision.com), we are [hiring](http://www.jellyvision.com/jobs/) so check us out. :D
93 |
94 | ~ Michael Chau (gh: [@mikechau](https://github.com/mikechau), twtr: [@money_mikec](https://twitter.com/money_mikec))
95 |
96 | ## Preface
97 |
98 | ### What people are saying about React:
99 |
100 | > ---
101 | > My favorite part of React is what I loved about MooTools: to use it effectively you learn JavaScript, not a DSL: useful your whole career.
102 | > - [Ryan Florence (@ryanflorence)](https://twitter.com/ryanflorence/status/577685415919898625)
103 | >
104 | > ---
105 | >
106 | > `#reactjs` Haven’t been so excited about programming since learned Rails: http://facebook.github.io/react ! Kudos [@floydophone](https://twitter.com/floydophone) & FB team!
107 | > - [Justin Gordon (@railsonmaui)](https://twitter.com/railsonmaui/status/503626150149492736)
108 | >
109 | > ---
110 | >
111 | > “It wasn’t my intention to use React for everything, but I found myself moving so quickly that I found I’d used it everywhere… had a blast”
112 | > - [Alan Hogan (@AlanHogan)](https://twitter.com/alanhogan/status/507307487062544384)
113 | >
114 | > ---
115 | >
116 |
117 | [Remember to just give it 5 minutes](https://signalvnoise.com/posts/3124-give-it-five-minutes).
118 |
119 | ---
120 |
121 | ### React Community
122 |
123 | The React community is super friendly!
124 |
125 | Connect with other React developers at:
126 |
127 | - [Reactiflux](https://reactiflux.slack.com/) - Slack for React developers
128 | - [Request an Invite](https://join-reactiflux.herokuapp.com/)
129 | - [Request an Invite Mirror](http://reactiflux.herokuapp.com/)
130 | - [#reactjs on irc.freenode.net](irc://chat.freenode.net/reactjs)
131 | - [Google Groups](http://groups.google.com/group/reactjs)
132 | - [Stack Overflow](http://stackoverflow.com/questions/tagged/reactjs)
133 | - [@reactjs](https://twitter.com/reactjs)
134 | - [#reactjs](https://twitter.com/search?q=%23reactjs)
135 |
136 | ### React Documentation
137 |
138 | The React documentation is very good. Use this primer as a introduction and then read more about React by viewing the official documentation:
139 |
140 | [React Documentation](https://facebook.github.io/react/docs/getting-started.html)
141 |
142 | There's also a ton of resources at: [Awesome React](https://github.com/enaqx/awesome-react)
143 |
144 | ---
145 |
146 | ## Intro to React
147 |
148 | React is a JavaScript library by Facebook, it describes itself as *__a javascript library for building user interfaces__*.
149 |
150 | Developers often call it *the V in MVC*, or talk about the *virtual DOM* (not to be confused with the *shadow DOM*). I like React for its declarative style, lifecycle event hooks, and the fact that a React *component* describes its view at anytime. By breaking down the view into components, writing React starts to become very natural. React has been a pleasure to work with. You no longer need to understand the entire flow of the application at once, you can start at a component and work your way up or down.
151 |
152 | This primer is meant to get you rapidly ready to start working with a React application. Its goal is not to teach and explain everything, but merely introduce concepts and help you form the right questions to ask and to have an idea of where to look for an answer. It is OK if you do not understand everything at first, just keep working at it by commiting the code you see to muscle memory and reading up on the documentation. Hopefully through reflection, and incubation, the concepts here will start to make sense.
153 |
154 | Don't be afraid of React either. It may *seem* complex but is quite simple with a very small API of a dozen "essential" methods:
155 |
156 | 1. [render](https://facebook.github.io/react/docs/react-component.html#render)
157 | 2. [getInitialState](http://facebook.github.io/react/docs/component-specs.html#getinitialstate)
158 | 3. [getDefaultProps](https://facebook.github.io/react/docs/react-without-es6.html#declaring-prop-types-and-default-props)
159 | 4. [propTypes](https://facebook.github.io/react/docs/react-component.html#proptypes)
160 | 5. [mixins](https://facebook.github.io/react/docs/react-without-es6.html#mixins)
161 | 6. [componentWillMount](https://facebook.github.io/react/docs/react-component.html#componentwillmount)
162 | 7. [componentDidMount](https://facebook.github.io/react/docs/react-component.html#componentdidmount)
163 | 8. [componentWillReceiveProps](https://facebook.github.io/react/docs/react-component.html#componentwillreceiveprops)
164 | 9. [shouldComponentUpdate](https://facebook.github.io/react/docs/react-component.html#shouldcomponentupdate)
165 | 10. [componentWillUpdate](https://facebook.github.io/react/docs/react-component.html#componentwillupdate)
166 | 11. [componentDidUpdate](https://facebook.github.io/react/docs/react-component.html#componentdidupdate)
167 | 12. [componentWillUnmount](https://facebook.github.io/react/docs/react-component.html#componentwillunmount)
168 |
169 | ---
170 |
171 | ### React Component
172 |
173 | A React component encapsulates everything. It does not separate the *view* from the *view logic*, but rather merges the two together. Separating these does not really make sense when building a user interface: the view and its view logic are inevitably tightly coupled. Rather than jumping between a template file and some sort of view-controller it makes sense to keep them together. React *components* are usually small enough that this is not a big deal to have the two together, and if it does get to be too large you can break down your component into smaller components.
174 |
175 | A key point from [the React documentation](http://facebook.github.io/react/docs/):
176 |
177 | > #### [Components are Just State Machines](https://facebook.github.io/react/docs/interactivity-and-dynamic-uis.html#components-are-just-state-machines)
178 | > React thinks of UIs as simple state machines. By thinking of a UI as being in various states and rendering those states, it's easy to keep your UI consistent.
179 | >
180 | > In React, you simply update a component's state, and then render a new UI based on this new state. React takes care of updating the DOM for you in the most efficient way.
181 |
182 | Read more: [Interactivity and Dynamic UIs](https://facebook.github.io/react/docs/interactivity-and-dynamic-uis.html)
183 |
184 | ---
185 |
186 | ### React JSX
187 |
188 | **JSX** is pretty interesting. It basically allows using an HTML/XML-like syntax within JavaScript-based React components. Of course this wouldn't work if you tried to do that then serve it. Choosing to write your React component in JSX requires a *transform* process. This is typically handled through a build process or tool, like [webpack](http://webpack.github.io).
189 |
190 | ```js
191 | var Button = React.createClass({
192 | render: function() {
193 | return (
194 | I am a button! Click me!
195 | );
196 | }
197 | });
198 |
199 | React.render(, document.getElementById('content'));
200 | ```
201 |
202 | Here you can see a React component has a `render` method, which returns *markup*. It's easy to see the shape of the output at a glance.
203 |
204 | [JS Bin](http://jsbin.com/maragegesu/1/edit?html,js,output)
205 |
206 | **NOTE:** [As of version 0.13](https://github.com/facebook/react/issues/2127) React components can only ever return a single "root" element or sub-component.
207 |
208 | For example, this is forbidden:
209 |
210 | ```js
211 | return (
212 |
Test
213 |
Test 2
214 | );
215 | ```
216 |
217 | It has to be:
218 |
219 | ```js
220 | return (
221 |
222 |
Test
223 |
Test 2
224 |
225 | );
226 | ```
227 |
228 | To render a React component in the body all you need to do is:
229 |
230 | ```js
231 | React.render(, document.getElementById('content'));
232 | ```
233 |
234 | Simply call the render method, pass in the component, and the DOM node you want to render to.
235 |
236 | **NOTE:** You should avoid rendering your React component directly into `document.body`, as it can lead to [subtle bugs](https://medium.com/@dan_abramov/two-weird-tricks-that-fix-react-7cf9bbdef375).
237 |
238 | When rendering a React component inside a DOM node, React wants complete ownership of the node. You should not add children to or remove children from a node in which React inserted a component.
239 |
240 | So just create a `` and then use `document.getElementById('content')`.
241 |
242 | Like so:
243 |
244 | ```html
245 |
246 |
247 |
248 |
249 |
250 | ```
251 |
252 | ```js
253 | // App.jsx
254 |
255 | React.render(, document.getElementById('content'));
256 | ```
257 |
258 | Read more: [JSX in Depth](https://facebook.github.io/react/docs/jsx-in-depth.html)
259 |
260 | ---
261 |
262 | ### React Supported Attributes
263 |
264 | React works with most common HTML elements, for example:
265 |
266 | ```js
267 | var Link = React.createClass({
268 | render: function() {
269 | return (
270 | Google
271 | );
272 | }
273 | });
274 |
275 | React.render(, document.getElementById('content'));
276 | ```
277 |
278 | [JS Bin](http://jsbin.com/dayoqaxava/1/edit?html,js,output)
279 |
280 | You just made an `a` tag! It can now be called via ``.
281 |
282 | Read more: [React Tags and Attributes](http://facebook.github.io/react/docs/tags-and-attributes.html)
283 |
284 | ---
285 |
286 | ### React Supported Events
287 |
288 | React has a cross-compatibility layer for most specific browser events. Going back to our `Link`:
289 |
290 | ```js
291 | var Link = React.createClass({
292 | render: function() {
293 | return (
294 | Google
295 | );
296 | },
297 |
298 | handleClick: function(e) {
299 | e.preventDefault();
300 |
301 | alert('You clicked me!');
302 | }
303 | });
304 |
305 |
306 | React.render(, document.getElementById('content'));
307 | ```
308 | Now, I know what you're thinking. *Inline events, isn't that bad?* It looks like it's inline but it's really not. React will use *event delegation* behind the scenes. So now we have a very declarative way to associate events to DOM elements. Now there's no confusion as to what elements have what events and there is no hassle of managing binding hooks between DOM and javascript (e.g. ids or classes).
309 |
310 | [JS Bin](http://jsbin.com/dayoqaxava/1/edit?html,js,output)
311 |
312 | Here's a key point from the React documentation:
313 |
314 | > #### [Event Handling and Synthetic Events](http://facebook.github.io/react/docs/interactivity-and-dynamic-uis.html#event-handling-and-synthetic-events)
315 | > With React you simply pass your event handler as a camelCased prop similar to how you'd do it in normal HTML. React ensures that all events behave identically in IE8 and above by implementing a synthetic event system. That is, React knows how to bubble and capture events according to the spec, and the events passed to your event handler are guaranteed to be consistent with the W3C spec, regardless of which browser you're using.
316 | >
317 | > If you'd like to use React on a touch device such as a phone or tablet, simply call `React.initializeTouchEvents(true);` to enable touch event handling.
318 | >
319 | > ---
320 | >
321 | > #### [Under the Hood: Autobinding and Event Delegation](http://facebook.github.io/react/docs/interactivity-and-dynamic-uis.html#under-the-hood-autobinding-and-event-delegation)
322 | >
323 | > **Autobinding:** When creating callbacks in JavaScript, you usually need to explicitly bind a method to its instance such that the value of this is correct. With React, every method is automatically bound to its component instance. React caches the bound method such that it's extremely CPU and memory efficient. It's also less typing!
324 | >
325 | > **Event delegation:** React doesn't actually attach event handlers to the nodes themselves. When React starts up, it starts listening for all events at the top level using a single event listener. When a component is mounted or unmounted, the event handlers are simply added or removed from an internal mapping. When an event occurs, React knows how to dispatch it using this mapping. When there are no event handlers left in the mapping, React's event handlers are simple no-ops. To learn more about why this is fast, see [David Walsh's excellent blog post](http://davidwalsh.name/event-delegate).
326 |
327 | In the example, we defined a function, and simply passed the function to the `onClick` property.
328 |
329 | When the *click event* occurs, we receive back a *synthetic event* we can manipulate as usual e.g. call `#preventDefault()` to stop the event's default action, or access the event's `#target`.
330 |
331 | Read more: [React Events](http://facebook.github.io/react/docs/events.html)
332 |
333 | ---
334 |
335 | #### React Supported Events Continued
336 |
337 | To use the same event handler in multiple bindings and contexts, you may want to attach custom data to DOM nodes as you'd do in native javascript:
338 |
339 | ```js
340 | var Link = React.createClass({
341 | render: function() {
342 | return (
343 |
374 | );
375 | },
376 |
377 | handleClick: function(linkName, e) {
378 | e.preventDefault();
379 |
380 | alert('You clicked ' + linkName);
381 | }
382 | });
383 |
384 | React.render(, document.getElementById('content'));
385 | ```
386 |
387 | [JS Bin](http://jsbin.com/dikizexixu/1/edit?html,js,output)
388 |
389 | According to [Javascript Is Sexy](http://javascriptissexy.com):
390 |
391 | > Partial function application is the use of a function (that accept one or more arguments) that returns a new function with some of the arguments already set. The function that is returned has access to the stored arguments and variables of the outer function. This sounds way more complex than it actually is, so let’s code.
392 | > ...
393 |
394 | An explanation of `.bind(this, ...)` vs `.bind(null, ...)` by `Morhaus` on `#reactjs`:
395 |
396 | > React autobinds methods in the object you pass to `React.createClass()` to the component instance, so using `this.handleClick.bind(null, 'test')` will ensure that behavior is not messed with
397 | >
398 | > ...
399 | >
400 | > pass null instead, unless you're not using `React.createClass()` but `class extends React.Component`, in which case methods are not auto bound
401 |
402 | `this` can be passed to preserve the current context, or we can pass `null` if it is not necessary. In this case, since we are using `React.createClass`, React will *autobind* the method for us so we can just pass `null` and whatever arguments we want applied.
403 |
404 | Read more: [Currying](http://javascriptissexy.com/javascript-apply-call-and-bind-methods-are-essential-for-javascript-professionals/)
405 |
406 | Read more: [Understand Javascript's "this" with Clarity and Master It](http://javascriptissexy.com/understand-javascripts-this-with-clarity-and-master-it/)
407 |
408 | Read more: [React Autobinding](https://facebook.github.io/react/docs/react-without-es6.html#autobinding)
409 |
410 | Read more: [bind(): React component methods may only be bound to the component instance](https://groups.google.com/forum/#!topic/reactjs/Xv9_kVoJJOw)
411 |
412 | Read more: [Partial application in JavaScript with `bind`](https://coderwall.com/p/nw9cxg/partial-application-in-javascript-with-bind)
413 |
414 | ---
415 |
416 | ### React Props
417 |
418 | *Props* are immutable parameters passed by a parent component to a child sub-component. A component can not alter its `#props` object (and should not alter the props themselves), the only way for props to change is for a new render to be triggered, where the parent component passes new props to the child.
419 |
420 | Props flow downwards, and in JSX they are provided as *attributes* of the component node:
421 |
422 | ```js
423 | // Parent Component
424 | var LikeList = React.createClass({
425 | render: function() {
426 | return (
427 |
442 | );
443 | }
444 | });
445 |
446 | React.render(, document.getElementById('content'));
447 | ```
448 |
449 | Here we have the *Parent Component*, `LikeList`, render an unordered list, with one child, a `LikeListItem`. To the `LikeListItem` we pass a `text` property.
450 |
451 | A component can access its props through `this.props`, `text` would be accessed via `this.props.text`. Here, the `text` prop is simply accessed during rendering.
452 |
453 | [JS Bin](http://jsbin.com/sanivitehu/1/edit?html,js,output)
454 |
455 | Read more: [Transferring Props](https://facebook.github.io/react/docs/transferring-props.html)
456 |
457 | #### getDefaultProps
458 |
459 | `getDefaultProps` will be called to get a default set of props, which will be overridden by the props eventually provided by a parent component. This is useful for optional props which have a sensible default value.
460 |
461 | ```js
462 | // Parent Component
463 | var LikeList = React.createClass({
464 | render: function() {
465 | return (
466 |
487 | );
488 | }
489 | });
490 |
491 | React.render(, document.getElementById('content'));
492 | ```
493 |
494 | If no `text` prop is passed, we give it a default value of `N/A`. If defined, `getDefaultProps` must return an object.
495 |
496 | [JS Bin](http://jsbin.com/kipejudici/1/edit?html,js,output)
497 |
498 | Read more: [Default Prop Values](https://facebook.github.io/react/docs/react-without-es6.html#declaring-prop-types-and-default-props)
499 |
500 | #### propTypes
501 |
502 | `propTypes` documents the props expected by a component and defines validators for generating warnings in the dev console.
503 |
504 | It is recommended that you define `propTypes` in any component that expects props. It is useful not only for validation during development but can be a way of documenting the component. It also makes it clear to others what the component expects.
505 |
506 | A key point from the React `documentation`:
507 |
508 | > ##### [Prop Validation](https://facebook.github.io/react/docs/reusable-components.html#prop-validation)
509 | > As your app grows it's helpful to ensure that your components are used correctly. We do this by allowing you to specify propTypes. React.PropTypes exports a range of validators that can be used to make sure the data you receive is valid. When an invalid value is provided for a prop, a warning will be shown in the JavaScript console. Note that for performance reasons propTypes is only checked in development mode. Here is an example documenting the different validators provided:
510 | > ...
511 |
512 | Example:
513 |
514 | ```js
515 | // Child Component
516 | var LikeListItem = React.createClass({
517 | propTypes: {
518 | text: React.PropTypes.string
519 | },
520 |
521 | getDefaultProps: function() {
522 | return {
523 | text: 'N/A'
524 | };
525 | },
526 |
527 | render: function() {
528 | return (
529 |
{this.props.text}
530 | );
531 | }
532 | });
533 | ```
534 |
535 | Here we declare that the `text` property must be a `string`. By default, props are optional and should have a default value (provided through `getDefaultProps`).
536 |
537 | It is also possible to mandate that a prop be provided with the `isRequired` validator:
538 |
539 | ```js
540 | // Child Component
541 | var LikeListItem = React.createClass({
542 | propTypes: {
543 | text: React.PropTypes.string.isRequired
544 | },
545 | ...
546 | ```
547 |
548 | `getDefaultProps` was removed: since the property is required, there is no reason to provide a default value for it.
549 |
550 | Read more: [Prop Validation](https://facebook.github.io/react/docs/typechecking-with-proptypes.html)
551 |
552 | #### refs
553 |
554 | React documentation introduction:
555 |
556 | > React supports a very special property that you can attach to any component that is output from render(). This special property allows you to refer to the corresponding backing instance of anything returned from render(). It is always guaranteed to be the proper instance, at any point in time.
557 |
558 | Here is an example of how you can treat a `ref` like an `id`:
559 |
560 | ```js
561 | // Parent Component
562 | var LikeList = React.createClass({
563 | componentDidMount: function() {
564 | console.log(this.refs.first.getDOMNode());
565 | },
566 |
567 | render: function() {
568 | return (
569 |
584 | );
585 | }
586 | });
587 |
588 | React.render(, document.getElementById('content'));
589 | ```
590 |
591 | [JS Bin](http://jsbin.com/lemodizizi/1/edit?html,js,output)
592 |
593 | **NOTE:** In React 0.13, `Component#getDOMNode()` should be replaced by `React.findDOMNode(Component)`, the first one generates a warning in the console.
594 |
595 | In this example, we can access the `ref` of `first` via `this.refs.first`. After `componentDidMount` has been called, the console output will be:
596 |
597 | ```html
598 |
turtles.
599 | ```
600 |
601 | Read more: [More About Refs](http://facebook.github.io/react/docs/more-about-refs.html)
602 |
603 | #### children
604 |
605 | There may be situations where you want components to wrap provided components rather than generate those from props:
606 |
607 | ```js
608 | var Likes = React.createClass({
609 | render: function() {
610 | return (
611 |
640 | );
641 | }
642 | });
643 |
644 | React.render(, document.getElementById('content'));
645 | ```
646 |
647 | Children are placed between a component's opening and ending tags, like regular HTML elements. The wrapper component can access those children via `this.props.children`.
648 |
649 | [JS Bin](http://jsbin.com/nafoqitazi/1/edit?html,js,output)
650 |
651 | Read more: [Children in JSX](https://facebook.github.io/react/docs/jsx-in-depth.html#children-in-jsx)
652 |
653 | #### className
654 |
655 | Because `class` is a reserved JavaScript keyword, to set the `class` of an element you will need to use the `className` property name instead.
656 |
657 | ```js
658 | render: function() {
659 | return (
660 | I am a button with a class!
661 | );
662 | }
663 | ```
664 |
665 | Review: [Tags and Attributes](https://facebook.github.io/react/docs/tags-and-attributes.html) for more details on the supported `HTML` tags and `attributes`.
666 |
667 | Review: [Events](https://facebook.github.io/react/docs/events.html) for the supported browser events.
668 |
669 | #### Passing a Prop
670 |
671 | When providing a boolean prop in JSX, passing the value is not necessary, as in HTML you can just add the key:
672 |
673 | ```js
674 | // SomeComponent.jsx
675 | var SomeComponent = React.createClass({
676 | render: function() {
677 | return (
678 |
679 | );
680 | }
681 | });
682 | ```
683 |
684 | `AnotherComponent`'s `this.props.checked` would resolve to `true`.
685 |
686 | ---
687 |
688 | ### React State
689 |
690 | As *Pete Hunt* noted, *shared mutable state is the root of evil*. Yet (mutable) state is often necessary. To that end, React components provide mutable state but *not shared* mutable state: only a component can alter its state, and a component can only alter its own state.
691 |
692 | On a component's state change, a re-render of the tree will be automatically triggered.
693 |
694 | State is useful for intermediate or self-contained component data, which should not or needs not be published externally. For instance a choice between liking something or not:
695 |
696 | ```html
697 |
698 |
699 |
Do you like fish sticks?
700 |
Response: I ______ fishsticks.
701 | I like them.
702 | I dislike them.
703 |
704 |
705 | ```
706 |
707 | ```js
708 | // logic.js
709 | $('#like').on('click', function(e) {
710 | e.preventDefault();
711 |
712 | $('#response').text('like');
713 | });
714 |
715 | $('#dislike').on('click', function(e) {
716 | e.preventDefault();
717 |
718 | $('#response').text('dislike');
719 | });
720 | ```
721 |
722 | The state of having liked or disliked fish sticks is fully internal, it does not come from an external source (a parent component) and is not published anywhere, thus in React:
723 |
724 | ```js
725 | var LikeComponent = React.createClass({
726 | getInitialState: function() {
727 | return {
728 | response: ''
729 | };
730 | },
731 |
732 | render: function() {
733 | return (
734 |
746 | );
747 | },
748 |
749 | handleLike: function(e) {
750 | e.preventDefault();
751 |
752 | this.setState({
753 | response: 'like'
754 | });
755 | },
756 |
757 | handleDislike: function(e) {
758 | e.preventDefault();
759 |
760 | this.setState({
761 | response: 'dislike'
762 | });
763 | }
764 | });
765 |
766 | React.render(, document.getElementById('content'));
767 | ```
768 |
769 | [JS Bin](http://jsbin.com/deburinesa/1/edit?html,js,output)
770 |
771 | `getInitialState` has the same purpose as `getDefaultProps`, but because state is not shared rather than providing a default it provides the complete internal state of the component. State items can then be accessed through `this.state`, much like props via `this.props`.
772 |
773 | State **must not be altered directly**.
774 |
775 | It should generally be altered via [`setState`](https://facebook.github.io/react/docs/component-api.html#setstate), which *merges* the provided object into the existing state then triggers a re-render: if the state is `{foo: 1, bar: 2}`, `this.setState({foo: 2})` will result in a new state of `{foo: 2, bar: 2}`.
776 |
777 | **NOTE:** although sometimes tempting, setting up the initial state from props is generally an anti-pattern, it's usually better to compute from props on the fly.
778 |
779 | For example:
780 |
781 | ```js
782 | getInitialState: function() {
783 | return {
784 | count: this.props.initialCount // this is fine because we make it clear that it is an initial value
785 | }
786 | }
787 | ```
788 |
789 | Key Point:
790 |
791 | > #### [Props in getInitialState Is an Anti-Pattern](https://facebook.github.io/react/tips/props-in-getInitialState-as-anti-pattern.html)
792 | >
793 | > ---
794 | >
795 | > Using props, passed down from parent, to generate state in getInitialState often leads to duplication of "source of truth", i.e. where the real data is. Whenever possible, compute values on-the-fly to ensure that they don't get out of sync later on and cause maintenance trouble.
796 |
797 | Read more: [Props in getInitialState Is an Anti-Pattern](http://stackoverflow.com/questions/28785106/reactjs-why-is-passing-the-component-initial-state-a-prop-an-anti-pattern)
798 |
799 | Read more: [State](https://facebook.github.io/react/docs/interactivity-and-dynamic-uis.html)
800 |
801 | ---
802 |
803 | ### React Lifecycle Events
804 |
805 | React components have a somewhat involved lifecycle, but React provides a number of events/methods to hook in and act at various lifecycle points. The React documentation covers this section very well, so we will just quote it for convenience.
806 |
807 | Read more: [Component Specs and Lifecycle Events](https://facebook.github.io/react/docs/component-specs.html)
808 |
809 | #### Mounting: componentWillMount
810 |
811 | `componentWillMount()`
812 |
813 | > Invoked once, both on the client and server, immediately before the initial rendering occurs. If you call `setState` within this method, `render()` will see the updated state and will be executed only once despite the state change.
814 |
815 | Read more: [componentWillMount](https://facebook.github.io/react/docs/react-component.html#componentwillmount)
816 |
817 | #### Mounting: componentDidMount
818 |
819 | `componentDidMount()`
820 |
821 | > Invoked once, only on the client (not on the server), immediately after the initial rendering occurs. At this point in the lifecycle, the component has a DOM representation which you can access via `React.findDOMNode(this) [React 0.13+]` or `this.getDOMNode() [React 0.12.x]`.
822 | >
823 | > If you want to integrate with other JavaScript frameworks, set timers using setTimeout or setInterval, or send AJAX requests, perform those operations in this method.
824 |
825 | Read more: [componentDidMount](https://facebook.github.io/react/docs/react-component.html#componentdidmount)
826 |
827 | #### Updating: componentWillReceiveProps
828 |
829 | `componentWillReceiveProps(object nextProps)`
830 |
831 | > Invoked when a component is receiving new props. This method is not called for the initial render.
832 | >
833 | > Use this as an opportunity to react to a prop transition before `render()` is called by updating the state using `this.setState()`. The old props can be accessed via `this.props`. Calling `this.setState()` within this function will not trigger an additional render.
834 | >
835 | > **NOTE:**
836 | > There is no analogous method `componentWillReceiveState`. An incoming prop transition may cause a state change, but the opposite is not true. If you need to perform operations in response to a state change, use `componentWillUpdate`.
837 |
838 | Read more: [componentWillReceiveProps](https://facebook.github.io/react/docs/react-component.html#componentwillreceiveprops)
839 |
840 | #### Updating: shouldComponentUpdate
841 |
842 | `boolean shouldComponentUpdate(object nextProps, object nextState)`
843 |
844 | > Invoked before rendering when new props or state are being received. This method is not called for the initial render or when `forceUpdate` is used.
845 | >
846 | > Use this as an opportunity to `return false` when you're certain that the transition to the new props and state will not require a component update.
847 | >
848 | > If `shouldComponentUpdate` `returns` `false`, then `render()` will be completely skipped until the next state change. (In addition, `componentWillUpdate` and `componentDidUpdate` will not be called.)
849 | >
850 | > By default, `shouldComponentUpdate` always `returns` `true` to prevent subtle bugs when state is mutated in place, but if you are careful to always treat state as immutable and to read only from props and state in `render()` then you can override `shouldComponentUpdate` with an implementation that compares the old props and state to their replacements.
851 | >
852 | > If performance is a bottleneck, especially with dozens or hundreds of components, use `shouldComponentUpdate` to speed up your app.
853 |
854 | #### Updating: componentWillUpdate
855 |
856 | `componentWillUpdate(object nextProps, object nextState)`
857 |
858 | > Invoked immediately before rendering when new props or state are being received. This method is not called for the initial render.
859 | >
860 | > Use this as an opportunity to perform preparation before an update occurs.
861 | >
862 | > **Note:**
863 | > You cannot use `this.setState()` in this method. If you need to update state in response to a prop change, use `componentWillReceiveProps` instead.
864 |
865 |
866 | Read more: [componentWillUpdate](https://facebook.github.io/react/docs/react-component.html#componentwillupdate)
867 |
868 | #### Updating: componentDidUpdate
869 |
870 | `componentDidUpdate(object prevProps, object prevState)`
871 |
872 | > Invoked immediately after the component's updates are flushed to the DOM. This method is not called for the initial render.
873 | >
874 | > Use this as an opportunity to operate on the DOM when the component has been updated.
875 |
876 | Read more: [componentDidUpdate](https://facebook.github.io/react/docs/react-component.html#componentdidupdate)
877 |
878 | #### Unmounting: componentWillUnmount
879 |
880 | `componentWillUnmount()`
881 |
882 | > Invoked immediately before a component is unmounted from the DOM.
883 | >
884 | > Perform any necessary cleanup in this method, such as invalidating timers or cleaning up any DOM elements that were created in componentDidMount.
885 |
886 | Read more: [componentWillUnmount](https://facebook.github.io/react/docs/react-component.html#componentwillunmount)
887 |
888 | ---
889 |
890 | ### React Dynamic Children
891 |
892 | React is great for rendering dynamic children. It's never been so easy.
893 |
894 | Let's take the example:
895 |
896 | ```js
897 | var animalsListData = [
898 | { id: 1, animal: 'tiger', name: 'Vee' },
899 | { id: 2, animal: 'lion', name: 'Simba' },
900 | { id: 3, animal: 'dog', name: 'Buck' },
901 | { id: 4, animal: 'sealion', name: 'Seel' }
902 | ];
903 |
904 | var AnimalsList = React.createClass({
905 | getInitialState: function() {
906 | return {
907 | animals: []
908 | };
909 | },
910 |
911 | render: function() {
912 | if (!this.state.animals.length) {
913 | return (
914 |
1000 | );
1001 | },
1002 |
1003 | handleResetClick: function(e) {
1004 | e.preventDefault();
1005 | this.setState({
1006 | animals: []
1007 | });
1008 | },
1009 |
1010 | handleFetchClick: function(e) {
1011 | e.preventDefault();
1012 | this._fetchRemoteData();
1013 | },
1014 |
1015 | _fetchRemoteData: function() {
1016 | setTimeout(function() {
1017 | this.setState({
1018 | animals: animalsListData
1019 | });
1020 | }.bind(this), 2000);
1021 | }
1022 | });
1023 |
1024 | React.render(, document.getElementById('content'));
1025 | ```
1026 |
1027 | [JS Bin](http://jsbin.com/zejijonobo/1/edit?html,js,output)
1028 |
1029 | For the purpose of this example, we'll emulate data fetching with a `setTimeout` call. In a real-world situation, you would use whatever AJAX library you prefer.
1030 |
1031 | As soon as the component mounts, we "fetch" the remote data, which will update the internal state and re-render the component 2 seconds later. The fetching is done inline but could be split into a separate method (e.g. `_fetchRemoteData`), and while we're fetching everything on mount, it could also be fetched only on a user action.
1032 |
1033 | This example is a bit verbose, but hopefully it drives home how you can build your components. Do you see how intertwined your view and view logic end up being? Right from the `render` method, you can see exactly what it is going to output and what events are attached to what.
1034 |
1035 | So let's summarize what is happening here:
1036 |
1037 | 1. The `state` is initialized, `this.state.animals` set to an empty array.
1038 | 2. The component will mount, we do nothing here.
1039 | 3. When `render` is called, we check if there is anything inside `this.state.animals`, if there is nothing, we render the special case noting the lack of animals.
1040 | 4. The component did mount, we call `this._fetchRemoteData()`
1041 | 5. When `this._fetchRemoteData()` completes, `this.setState(...)` is called and a new `render` happens! The update lifecycle events are also triggered.
1042 | 6. The user can use the available buttons to reset or update the list of animals.
1043 |
1044 | To render dynamic children, simply `map` over your collection and return the components you want rendered by passing in the collection's item attributes as props.
1045 |
1046 | **NOTE:** When mapping over an array, the result components must be given a `key`.
1047 |
1048 | #### key
1049 |
1050 | Think of the `key` property as a unique identifier for the components being returned from `map`.
1051 |
1052 | Key point:
1053 |
1054 | > When React reconciles the keyed children, it will ensure that any child with key will be reordered (instead of clobbered) or destroyed (instead of reused).
1055 |
1056 | So let's review:
1057 |
1058 | ```js
1059 | render: function() {
1060 | return (
1061 |
1072 | );
1073 | }
1074 | ```
1075 |
1076 | As we map over `this.state.animals`, we set the `key` prop to the current index in the array.
1077 |
1078 | In general, it is recommended you pass the current index to `key`, instead of generating a unique identifier or using one from the object.
1079 |
1080 | **funkiee** from Hacker News explains why ([Marko vs. React: Performance Benchmark](https://news.ycombinator.com/item?id=9066065)):
1081 |
1082 | > Not necessarily addressing the speed portion, but if you're going to give a key to a repeated item in React, it is best to use the index instead of a unique identifier(if the overall DOM structure does not change much between renders) so that React does not destroy and recreate each item on tree change.
1083 | > ~ [funkiee](https://news.ycombinator.com/user?id=funkiee) - Hacker News
1084 |
1085 | As a follow up, you are probably thinking:
1086 |
1087 | > It re-creates items even when they have unique identifiers? Is that a bug?
1088 | > ~ [myhf](https://news.ycombinator.com/item?id=9066196) - Hacker News
1089 |
1090 | To which, **funkiee** responds:
1091 |
1092 | > It's as intended. If the ID in a list of 100 changes, and that ID is the key, React is going to assume the tree is different during reconciliation. If you were to use an index, like 0, on pagination the key is still 0 and as such the DOM nodes will be reused. [http://facebook.github.io/react/docs/reconciliation.html](http://facebook.github.io/react/docs/reconciliation.html) See #2 in the Trade-offs section.
1093 | > ~ [funkiee](https://news.ycombinator.com/user?id=funkiee) - Hacker News
1094 |
1095 | For your convenience, here are the trade-offs quoted from the React documentation:
1096 |
1097 | > #### [Trade-offs](http://facebook.github.io/react/docs/reconciliation.html#trade-offs)
1098 | > It is important to remember that the reconciliation algorithm is an implementation detail. React could re-render the whole app on every action; the end result would be the same. We are regularly refining the heuristics in order to make common use cases faster.
1099 | >
1100 | > In the current implementation, you can express the fact that a sub-tree has been moved amongst its siblings, but you cannot tell that it has moved somewhere else. The algorithm will re-render that full sub-tree.
1101 | >
1102 | > Because we rely on two heuristics, if the assumptions behind them are not met, performance will suffer.
1103 | >
1104 | > 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.
1105 | > 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.
1106 |
1107 | This will probably make more sense after reviewing the [Reconciliation](https://facebook.github.io/react/docs/reconciliation.html) section in the React documentation.
1108 |
1109 | **NOTE:** You only need to set the `key` for the parent container component, it does not matter if it is a custom React component or an HTML container.
1110 |
1111 | Example:
1112 |
1113 | ```js
1114 | // CORRECT
1115 | render: function() {
1116 | return (
1117 |
1149 | );
1150 | }
1151 | ```
1152 |
1153 | `key` just needs to be set in the outermost component.
1154 |
1155 | Read more: [Recursing on Children](https://facebook.github.io/react/docs/reconciliation.html#recursing-on-children)
1156 |
1157 | Read more: [Reconciliation](https://facebook.github.io/react/docs/reconciliation.html)
1158 |
1159 | Read more: [Trade-offs](https://facebook.github.io/react/docs/reconciliation.html#tradeoffs)
1160 |
1161 | Read more: [Marko vs. React: Performance Benchmark](https://news.ycombinator.com/item?id=9066065)
1162 |
1163 | Read more: [React.js and Dynamic Children - Why the Keys are Important](http://blog.arkency.com/2014/10/react-dot-js-and-dynamic-children-why-the-keys-are-important/)
1164 |
1165 | Read more: [React vs. Ember by Alex Matchneer](https://docs.google.com/presentation/d/1afMLTCpRxhJpurQ97VBHCZkLbR1TEsRnd3yyxuSQ5YY/edit#slide=id.p)
1166 |
1167 | ---
1168 |
1169 | ### React Nested Views
1170 |
1171 | React is great for working with a tree structure like HTML. You can nest to your heart's content, it's encouraged. Remember: everything is a component. It's just like working in HTML, so it should start to come naturally to you.
1172 |
1173 | Consider this `App` component:
1174 |
1175 | ```js
1176 | React.render(, document.getElementById('content'));
1177 | ```
1178 |
1179 | We render it to `#content`.
1180 |
1181 | Inside the `App` component its `render` could have an assortment of components. Maybe it looks like this:
1182 |
1183 | ```js
1184 | // App.jsx
1185 | ...
1186 | render: function() {
1187 | return (
1188 |
1222 |
1223 |
1224 |
1225 | );
1226 | }
1227 | ...
1228 | ```
1229 |
1230 | Each component could keep going. Eventually you'd reach a point it actually returns the HTML, for example, `Grid` might actually just be an abstraction for:
1231 |
1232 | ```js
1233 | // Grid.jsx
1234 | render: function() {
1235 | return (
1236 |
1237 | {this.props.children}
1238 |
1239 | );
1240 | }
1241 | ```
1242 |
1243 | ---
1244 |
1245 | ### React Mixins
1246 |
1247 | Mixins are a way of sharing reusable functionality between components.
1248 |
1249 | Key point from React documentation:
1250 |
1251 | > 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](http://en.wikipedia.org/wiki/Cross-cutting_concern). React provides mixins to solve this problem.
1252 |
1253 | **NOTE:** The validity of mixins, is currently debated in the community. While you may continue to use them with `React.createClass`, mixins are not currently available when using ES6 classes. The community seems to be leaning toward the idea of containers aka [*higher-order components*](https://medium.com/@dan_abramov/mixins-are-dead-long-live-higher-order-components-94a0d2f9e750) or *decorators* (functions or components which manipulate or alter other components).
1254 |
1255 | Mixin example:
1256 |
1257 | ```js
1258 | var Mixin1 = {
1259 | componentDidMount: function() {
1260 | console.log('Mixin1, component did mount!');
1261 | }
1262 | };
1263 |
1264 | var Mixin2 = {
1265 | componentDidMount: function() {
1266 | console.log('Mixin2, component did mount!');
1267 | }
1268 | };
1269 |
1270 |
1271 | var Greeter = React.createClass({
1272 | mixins: [Mixin1, Mixin2],
1273 |
1274 | componentDidMount: function() {
1275 | console.log('Greeter, component did mount!');
1276 | },
1277 |
1278 | render: function() {
1279 | return (
1280 |
Hi!
1281 | );
1282 | }
1283 | });
1284 |
1285 | React.render(, document.getElementById('content'));
1286 | ```
1287 | [JS Bin](http://jsbin.com/galefibomo/1/edit?js,console,output)
1288 |
1289 | After `componentDidMount`, the console should display:
1290 |
1291 | ```
1292 | "Mixin1, component did mount!"
1293 | "Mixin2, component did mount!"
1294 | "Greeter, component did mount!"
1295 | ```
1296 |
1297 | Mixins are a way of sharing functionality in lifecycle events between components. They can also be used to add custom methods to your React components.
1298 |
1299 | Read more: [Mixins](https://facebook.github.io/react/docs/reusable-components.html#mixins)
1300 |
1301 | Read more: [Higher-Order Components (HOC)](https://medium.com/@dan_abramov/mixins-are-dead-long-live-higher-order-components-94a0d2f9e750)
1302 |
1303 | ---
1304 |
1305 | ### React Pure Render
1306 |
1307 | A simple performance boost you can get out of React is through the `PureRenderMixin`.
1308 |
1309 | Per the React documentation:
1310 |
1311 | > 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 mixin for a performance boost in some cases.
1312 | >
1313 | > Under the hood, the mixin implements `shouldComponentUpdate`, in which it compares the current props and state with the next ones and returns false if the equalities pass.
1314 | >
1315 | > **Note:**
1316 | > This only shallowly compares the objects. If these contain complex data structures, it may produce false-negatives for deeper differences. Only mix into components which have simple props and state, or use forceUpdate() when you know deep data structures have changed. Or, consider using immutable objects to facilitate fast comparisons of nested data.
1317 | > Furthermore, shouldComponentUpdate skips updates for the whole component subtree. Make sure all the children components are also "pure".
1318 |
1319 | Let's check out an example:
1320 |
1321 | ```js
1322 |
1323 | var Greeter = React.createClass({
1324 | mixins: [React.addons.PureRenderMixin],
1325 |
1326 | getInitialState: function() {
1327 | return {
1328 | greeting: 'Hi'
1329 | };
1330 | },
1331 |
1332 | componentDidUpdate: function() {
1333 | console.log('Component updated!');
1334 | },
1335 |
1336 | render: function() {
1337 | console.log('Component rendered!');
1338 | return (
1339 |
1359 | );
1360 | },
1361 |
1362 | handleGreetingClick: function(greeting, e) {
1363 | e.preventDefault();
1364 |
1365 | console.log('click event', greeting);
1366 |
1367 | this.setState({
1368 | greeting: greeting
1369 | });
1370 | }
1371 | });
1372 |
1373 | React.render(, document.getElementById('content'));
1374 | ```
1375 |
1376 | [JS Bin](http://jsbin.com/jafakogeha/1/edit?js,console,output)
1377 |
1378 | The initial state of `this.state.greeter` is set to `Hi`.
1379 |
1380 | If we clicked the *Say Hi* action, the console would display:
1381 |
1382 | ```
1383 | "click event"
1384 | "Hi"
1385 | ```
1386 |
1387 | **No updates were applied** because the previous state is `{greeting: 'Hi'}`, and the new state is the exact same `{greeting: 'Hi'}`. If the props and state haven't visibly changed since the last `render`, `PureRenderMixin` will just **skip** the new one.
1388 |
1389 | If we clicked *Say Hey*, the console would say the following instead:
1390 |
1391 | ```
1392 | "click event"
1393 | "Hey"
1394 | "Component rendered!"
1395 | "Component updated!"
1396 | ```
1397 |
1398 | Read more: [PureRenderMixin](https://facebook.github.io/react/docs/pure-render-mixin.html)
1399 |
1400 | ---
1401 |
1402 | ### React and 3rd Party Libraries
1403 |
1404 | The neat thing about React is you don't have to commit your whole application to using it. You can sprinkle it in and eventually... you'll want to write to everything in React. ;)
1405 |
1406 | You can use third party libraries with React, even if they were not specifically written for React, some examples include [jQuery UI](https://jqueryui.com), your favorite charting library or [DataTables](https://www.datatables.net).
1407 |
1408 | We will use *DataTables* as an example of how you could use it with React.
1409 |
1410 | ```js
1411 | var accountingData = function() {
1412 | var data = [];
1413 |
1414 | var random = (Math.floor(Math.random() * 10));
1415 |
1416 | for (i = 0; i < random; i++) {
1417 | data.push({
1418 | name: 'Transaction ' + (i + 1),
1419 | amount: (Math.floor(Math.random() * 100))
1420 | });
1421 | }
1422 |
1423 | return data;
1424 | };
1425 |
1426 |
1427 | var AccountingTable = React.createClass({
1428 | getInitialState: function() {
1429 | return {
1430 | transactions: []
1431 | };
1432 | },
1433 |
1434 | componentDidMount: function() {
1435 | $(this.refs.table.getDOMNode()).DataTable();
1436 | },
1437 |
1438 | componentWillUpdate: function() {
1439 | var table = $(this.refs.table.getDOMNode()).DataTable();
1440 | table.destroy();
1441 | },
1442 |
1443 | componentDidUpdate: function() {
1444 | $(this.refs.table.getDOMNode()).DataTable();
1445 | },
1446 |
1447 | componentWillUnmount: function() {
1448 | var table = $(this.refs.table.getDOMNode()).DataTable();
1449 | table.destroy();
1450 | },
1451 |
1452 | render: function() {
1453 | return (
1454 |
1476 | );
1477 | },
1478 |
1479 | handleGetTransactionsClick: function(e) {
1480 | e.preventDefault();
1481 |
1482 | this.setState({
1483 | transactions: accountingData()
1484 | });
1485 | }
1486 | });
1487 |
1488 | React.render(, document.getElementById('content'));
1489 | ```
1490 |
1491 | [JS Bin](http://jsbin.com/soqikucoda/1/edit?js,output)
1492 |
1493 | This example is incredibly arbitrary. You would probably update the table via ajax instead, or write your own table component, or use something off the shelf for React like [FixedDataTable](https://facebook.github.io/fixed-data-table/) from Facebook or [Griddle](http://dynamictyped.github.io/Griddle/), etc.
1494 |
1495 | In this example, our initial state, `this.state.transactions`, is an empty array.
1496 |
1497 | After `componentDidMount`, we initialize and render `DataTable`.
1498 |
1499 | Then on *Get Transactions*, we update the `state` with the data.
1500 |
1501 | Before the component updates, we destroy `DataTable`, and reinitialize it on `componentDidUpdate`. When the component unmounts we will also destroy the `DataTable` to clean up any associated event handler or resource.
1502 |
1503 | If there are more interactions with the table, instead of asking React for the DOM node every time, we could store a reference in something like `this._dataTableRef`.
1504 |
1505 | You could also have a React component which doesn't render anything to the DOM (aside from a required component root) but uses its lifecycle events to trigger commands on a third party library to manipulate the DOM. This concept is what *Ryan Florence* calls a **portal**.
1506 |
1507 | Read more: [React.js Conf 2015 - Hype! (Portals)](https://youtu.be/z5e7kWSHWTg?t=15m22s) - Video.
1508 |
1509 | Read more: [Portals Example Repo](https://github.com/ryanflorence/reactconf-2015-HYPE/tree/master/demos/03-portals)
1510 |
1511 | Read more: ["Portals" in React.js](http://joecritchley.svbtle.com/portals-in-reactjs)
1512 |
1513 | ---
1514 |
1515 | ### React Component Parent and Child Communication
1516 |
1517 | As you start to build out your React application, you may find yourself asking: *how do I get this child component to update the state of my parent component?*
1518 |
1519 | You can simply pass down a callback function from the Parent Component to the Child Component.
1520 |
1521 | For example:
1522 |
1523 | ```js
1524 | var ShoppingList = React.createClass({
1525 | getInitialState: function() {
1526 | return {
1527 | items: [
1528 | { id: 1, name: 'Apple', qty: 2 },
1529 | { id: 2, name: 'Orange', qty: 3 },
1530 | { id: 3, name: 'Chicken', qty: 1 }
1531 | ]
1532 | };
1533 | },
1534 |
1535 | render: function() {
1536 | return (
1537 |
1541 | );
1542 | },
1543 |
1544 | handleItemClick: function(name, e) {
1545 | e.preventDefault();
1546 | console.log('click event', name);
1547 | }
1548 | });
1549 |
1550 | var List = React.createClass({
1551 | propTypes: {
1552 | items: React.PropTypes.array.isRequired,
1553 | onClick: React.PropTypes.func.isRequired
1554 | },
1555 |
1556 | render: function() {
1557 | return (
1558 |
1571 | );
1572 | }
1573 | });
1574 |
1575 | React.render(, document.getElementById('content'));
1576 | ```
1577 |
1578 | [JS Bin](http://jsbin.com/jamadofeni/3/edit?js,console,output)
1579 |
1580 | In this example, we have a `ShoppingList` parent component, that renders a `List` child component.
1581 |
1582 | Let's walk through the process:
1583 |
1584 | 1. `ShoppingList` sets its initial state of `items` to an array:
1585 |
1586 | ```js
1587 | [
1588 | { id: 1, name: 'Apple', qty: 2 },
1589 | { id: 2, name: 'Orange', qty: 3 },
1590 | { id: 3, name: 'Chicken', qty: 1 }
1591 | ]
1592 | ```
1593 |
1594 | 2. It passes `this.state.items` to the `List` component, along with the callback function `#handleItemClick`.
1595 |
1596 | 3. `List` component, expects the `propTypes` of `items` (array) and `onClick` (function), both are required.
1597 |
1598 | 4. `List` creates dynamic children via map, which is binded. It returns `
` tags, passing in the index as the `key`. Inside of the `
1742 | );
1743 | },
1744 |
1745 | nextVideo: function(e){
1746 | e.preventDefault();
1747 | this.props.onChange(1);
1748 | },
1749 |
1750 | prevVideo: function(e){
1751 | e.preventDefault();
1752 | this.props.onChange(-1);
1753 | },
1754 |
1755 | _handleArrowKeys: function(e) {
1756 | if (e.keyCode === 37) {
1757 | this.prevVideo(e);
1758 | };
1759 |
1760 | if (e.keyCode === 39) {
1761 | this.nextVideo(e);
1762 | }
1763 | }
1764 | });
1765 |
1766 | React.render(, document.getElementById('content'));
1767 | ```
1768 |
1769 | [JSBin](http://jsbin.com/focanezude/3/edit?js,output)
1770 |
1771 | You can see that [*App*] is the entry point, the AJAX request gets called, and then we pass down the relevant props down to [*HeaderView*] and [*StageView*].
1772 |
1773 | If you commented out `#_retrieveVideos` inside [*App*], you would see there wouldn't be anything there.
1774 |
1775 | You can also see that a `#_updateIndex` function gets passed down to [*StageView*] to manage the moving between videos.
1776 |
1777 | Also if you look at [*StageView*], when the component mounts we attach a `#keydown` event listener to the body so we can move between videos when the left or right arrow key is pressed.
1778 |
1779 | **Remember**: When attaching events on mount, you should clean them up on `componentWillUnmount`.
1780 |
1781 | Feel free to mess around with this example and experiment with things! One area of improvement is the logic for [*App*]'s `#_updateIndex`. There should be guards to prevent one from going back past the first video and the last or perhaps it should loopback.
1782 |
1783 | ---
1784 |
1785 | ### React Developer Tools
1786 |
1787 | React has a handy developer debug tool, for *Chrome*, check it out: [React Developer Tools](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en).
1788 |
1789 | ---
1790 |
1791 | ## Harmony aka ES6 aka ES2015
1792 |
1793 | Initially known as **Harmony** or **ES6**, **ES2015** is an update to the [ECMAScript](http://en.wikipedia.org/wiki/ECMAScript) standard.
1794 |
1795 | This document will refer to the new upcoming standard for ECMAScript as **ES6**.
1796 |
1797 | While ES6 browser support is still in progress, many developers are taking advantage of it today. They are doing so through the use of a [transpiler](http://en.wikipedia.org/wiki/Source-to-source_compiler) like [Babel](https://babeljs.io/). Babel will take your ES6 code and convert it into ES5, so developers can start taking advantage of ES6 while browsers work to implement the ES6 standard.
1798 |
1799 | This section will cover some of the new syntax you may commonly see in React projects taking advantage of ES6.
1800 |
1801 | It is recommended you review one of the following overviews (or maybe look at all of them) to get a better understanding about ES6's features.
1802 |
1803 | Read more: [ECMAScript 6 Overview](https://github.com/lukehoban/es6features#readme)
1804 |
1805 | Read more: [Using ECMAScript 6 today](http://www.2ality.com/2015/02/es6-classes-final.html)
1806 |
1807 | Read more: [You Don't Know JS: ES6 & Beyond](https://github.com/getify/You-Dont-Know-JS/tree/master/es6%20%26%20beyond)
1808 |
1809 | Read more: [ES6 compatibility table](https://kangax.github.io/compat-table/es6/)
1810 |
1811 | ### Modules
1812 |
1813 | If you are unfamiliar with modules, it is a way of declaring dependencies. The idea is similar to `require` in Ruby or `import` in Python.
1814 |
1815 | Read more: [ECMAScript 6 modules: the final syntax](http://www.2ality.com/2014/09/es6-modules-final.html)
1816 |
1817 | Read more: [Understanding Javascript Modules](https://spring.io/understanding/javascript-modules)
1818 |
1819 | Read more: [Node.js modules](https://nodejs.org/api/modules.html) - Review this if you are unfamiliar with node modules.
1820 |
1821 | #### import
1822 |
1823 | You may already be familiar with [CommonJS](http://en.wikipedia.org/wiki/CommonJS) modules, especially if you have done work with [Node.js](https://nodejs.org/api/modules.html).
1824 |
1825 | To refresh your memory, it looks like this:
1826 |
1827 | ```js
1828 | var React = require('react');
1829 |
1830 | var MyComponent = React.createClass(...);
1831 | ```
1832 |
1833 | You can now instead do:
1834 |
1835 | ```js
1836 | import React from 'react';
1837 | ```
1838 |
1839 | To import a specific function:
1840 |
1841 | ```js
1842 | // ES6
1843 | import { Grid, Row, Column } from 'react-bootstrap';
1844 |
1845 | // CommonJS Equivalent
1846 | var ReactBootstrap = require('react-bootstrap');
1847 | var Grid = ReactBootstrap.Grid;
1848 | var Row = ReactBootstrap.Row;
1849 | var Column = ReactBootstrap.Column;
1850 | ```
1851 |
1852 | #### export
1853 |
1854 | To specify what you want to export by default, observe the following:
1855 |
1856 | ```js
1857 | // MyReactComponent.jsx
1858 | //ES6
1859 | export default MyReactComponent;
1860 |
1861 | // CommonJS Equivalent
1862 | module.exports = MyReactComponent;
1863 |
1864 | // Import the default
1865 | import MyReactComponent from './MyReactComponent';
1866 | ```
1867 |
1868 | You can also export multiple things.
1869 |
1870 | ```js
1871 | // MyReactComponent.jsx
1872 | export SOME_CONST;
1873 | export someFunction;
1874 | export default MyReactComponent;
1875 |
1876 | // Import something specific
1877 | import { SOME_CONST, someFunction } from './MyReactComponent';
1878 | ```
1879 |
1880 | ### Variable Assignment
1881 |
1882 | `var` can be replaced with either `let` or `const`. In most cases, you will probably want to use `const`.
1883 |
1884 | Read more: [Let + Const](https://github.com/lukehoban/es6features#let--const)
1885 |
1886 | #### const
1887 |
1888 | `const` is single-assignment. This means that it is read-only.
1889 |
1890 | [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const) explanation:
1891 |
1892 | > ##### Summary
1893 | >
1894 | > The const declaration creates a read-only named constant.
1895 | >
1896 | > ###### Description
1897 | >
1898 | > This declaration creates a constant that can be global or local to the function in which it is declared. Constants are block-scoped. The value of a constant cannot change through re-assignment, and a constant cannot be re-declared. An initializer for a constant is required. A constant cannot share its name with a function or a variable in the same scope.
1899 |
1900 |
1901 | ```js
1902 | const test = "x";
1903 |
1904 | // error cant reassign a const
1905 | test = "y";
1906 | ```
1907 |
1908 | ```js
1909 | const test = {key: 'value'};
1910 |
1911 | // OK (object attributes are not protected)
1912 | test.key2 = '1';
1913 | ```
1914 |
1915 | Read more: [MDN - const](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const)
1916 |
1917 | #### let
1918 |
1919 | [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let) explanation:
1920 |
1921 | > ##### Summary
1922 | >
1923 | > The let statement declares a block scope local variable, optionally initializing it to a value.
1924 | >
1925 | > ###### Description
1926 | >
1927 | > let allows you to declare variables that are limited in scope to the block, statement, or expression on which it is used. This is unlike the var keyword, which defines a variable globally, or locally to an entire function regardless of block scope.
1928 |
1929 | Example from [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let):
1930 |
1931 | ```js
1932 | function letTest() {
1933 | let x = 31;
1934 | if (true) {
1935 | let x = 71; // different variable
1936 | console.log(x); // 71
1937 | }
1938 | console.log(x); // 31
1939 | }
1940 | ```
1941 |
1942 | Read more: [MDN - let](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let)
1943 |
1944 | ### Fat Arrow
1945 |
1946 | The arrow function, or fat arrow works similar to how it does in Coffeescript.
1947 |
1948 | According to [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#Lexical_this):
1949 |
1950 | > An arrow function expression (also known as fat arrow function) has a shorter syntax compared to function expressions and lexically binds the this value. Arrow functions are always anonymous.
1951 |
1952 | Example:
1953 |
1954 | ```js
1955 | const ListComponent = React.createClass({
1956 | propTypes: {
1957 | items: React.PropTypes.array
1958 | },
1959 |
1960 | getInitialState: function() {
1961 | return { starredItemIndex: 0 }
1962 | },
1963 |
1964 | render: function() {
1965 | return (
1966 |
1976 | );
1977 | }
1978 | });
1979 | ```
1980 |
1981 | In the above example, you can see how we call the fat arrow within the map, instead of having to `#bind(this)`, so we have access to get `state#starredItemIndex`.
1982 |
1983 | ```js
1984 | this.props.items.map(function(item, index) {
1985 | ...
1986 | }).bind(this)
1987 | ```
1988 |
1989 | or doing something like:
1990 |
1991 | ```js
1992 | const self = this;
1993 | return (
1994 |