Compare commits

...

691 Commits

Author SHA1 Message Date
Paul O’Shannessy
f756cb3d9c 0.5.0 release
Updated README, CHANGELOG, blog post
2013-10-16 11:44:37 -07:00
Paul O’Shannessy
cadf8b786c Fix grunt npm:test 2013-10-16 11:44:37 -07:00
Paul O’Shannessy
953947a617 bump version for 0.5 2013-10-15 22:32:20 -07:00
Paul O’Shannessy
d8c949e4d8 Update browserify 2013-10-15 21:27:26 -07:00
JeffMo
243a2b816e bump baseline jstransform and esprima dependency versions 2013-10-15 18:54:01 -07:00
Paul O’Shannessy
451176665c Update docs with supported tags and attributes 2013-10-15 18:15:24 -07:00
Paul O’Shannessy
cff62f8d72 Enable linting for bitwise operators 2013-10-15 18:02:28 -07:00
Paul O'Shannessy
3f2ba221ef Use getActiveElement module
We had something that did the same sort of protection. The module
differs slightly (returns document.body instead of undefined) but
looking at the callers, that should be ok.
2013-10-15 18:00:05 -07:00
Paul O'Shannessy
46713c3d7d Fix Lint
Enabling bitwise linting caught another user. Also fixed a semicolon
misuse.
2013-10-15 17:59:14 -07:00
Paul O’Shannessy
b015204938 Updated AUTHORS for 0.5
closes #414
2013-10-15 15:01:14 -07:00
petehunt
24f6bed855 new addons docs
closes #403
2013-10-15 14:09:21 -07:00
Paul O’Shannessy
5325e944e9 Merge pull request #426 from SanderSpies/sspi-fix-jsx-doc-link
In-browser JSX warning linked to wrong anchor (should be lowercase)
2013-10-15 12:04:59 -07:00
Paul O’Shannessy
b488cb3d4b Merge branch 'SanderSpies-sspi-dom-attribute-process' 2013-10-15 12:00:52 -07:00
Paul O’Shannessy
087c2afed1 Make sure DOM components work in JSDOM 2013-10-15 11:38:26 -07:00
Paul O’Shannessy
b0645bd5d3 Be consistent with object naming in tests
This also fixes line length issues our linter was complaining about.
2013-10-15 11:38:26 -07:00
SanderSpies
5a13dd090d Standardize prop -> DOM attribute process
Allow more than strings and numbers to be used as attributes for DOM
nodes. This removes the special casing for `0` and `false` that was
being used in ReactDOMInput and ReactDOMTextarea.

Now we will just `toString` any object we try to insert into a DOM.

Closes #422, #372, #302
2013-10-15 11:38:25 -07:00
Paul O'Shannessy
b0455f4670 Ensure attribute values are strings
`jsdom` behavers differently than browsers here and we should ensure
that we are consistent. Browsers should be (and are) converting to
a string first, while `jsdom` doesn't.
2013-10-15 10:39:51 -07:00
Tim Yung
287f5b578c Add bitwise lint escape to DefaultDOMPropertyConfig 2013-10-15 10:38:31 -07:00
SanderSpies
6839704c4b #JSX => #jsx 2013-10-15 19:11:19 +02:00
Martin Konicek
5332422239 [docs] Fix a broken link to JSX syntax in README. 2013-10-14 17:10:26 -07:00
Ben Alpert
7909c3e71b Forcibly wrap SVG nodes with <svg> on creation
Forcing wrapping seems necessary here: I compared a <circle> created within a <div> with a <circle> created inside an <svg> and they appear to have exactly the same properties with the exception of .parentNode (and .parentElement), yet the former refuses to show up when appended to an <svg> element. As such, I can't find any useful way to write a unit test (testing getMarkupWrap's output doesn't seem particularly useful to me).

Fixes #311.

Test Plan:
With a component that adds a <circle> after mounting (such as http://jsfiddle.net/spicyj/hxFVe/), verify that the circle appears in both Chrome and IE9.
2013-10-14 13:44:36 -07:00
Paul O’Shannessy
b45c82c256 Merge pull request #419 from piranha/svg-attrs
svg properties -> attributes

Fixes #190
2013-10-14 11:24:36 -07:00
Alexander Solovyov
3a5a82fd18 DefaultDOMPropertyConfig: sort properties alphabetically 2013-10-14 20:45:00 +03:00
Josh Duck
1238f5f23a Remove DOM mutation listeners
Mutation listeners are known to be slow. Rough benchmarks show text
changes are now 50% faster.
2013-10-11 17:33:47 -07:00
Owen Coutts
ac9f5e9da4 Better click behavior for ff
Firefox created onClick events for right mouse clicks. This diff brings behavior on firefox inline with other browsers.
2013-10-11 15:42:22 -07:00
Josh Duck
58c392ae3b Check for null selection
getRangeAt(0) will throw on null selection. Add guard in
ReactDOMSelection and DocumentSelection.
2013-10-11 12:52:19 -07:00
Alexander Solovyov
aa38ffc22d svg attributes properly cased when assigned by react 2013-10-11 15:48:17 +03:00
Alexander Solovyov
6d300527c8 svg: rx/ry for rounded corners 2013-10-11 13:42:10 +03:00
Alexander Solovyov
a601c5cc81 svg properties -> attributes 2013-10-11 13:32:22 +03:00
Alexander Solovyov
4549fd7510 fix namesToPlugins for gcc advanced mode 2013-10-09 22:08:03 +03:00
Keito Uchiyama
ef60eee57a Make transferPropsTo() message easier to debug
Summary:
Made the transferPropsTo() error introduced in
325322898c easier to use to debug.
2013-10-09 11:28:35 -07:00
Sebastian Markbage
7a9c13dee8 Set _renderedComponent before it's fully mounted
For debugging so that we can inspect the currently rendering tree. I think this
should be safe and makes sense since it tried to mount.
2013-10-09 11:28:22 -07:00
Tim Yung
d652dd928a Add displayName for DOM Components 2013-10-09 11:28:12 -07:00
Jan Kassens
c99d6a8013 Make the injection of ReactPerf work
The injection was only evaluated when ReactCompositeComponent was first loaded.
This made it impossible to inject a custom measure and the injection pointless.
2013-10-09 11:27:40 -07:00
Ben Newman
f8c5752472 Merge pull request #374 from spicyj/workers
Test that React loads properly in a web worker.

Most of this code is open source-only, so I think it's safe to merge without figuring out how to translate it upstream first.
2013-10-09 08:50:41 -07:00
Paul O’Shannessy
44352a2861 Merge pull request #370 from zpao/addons
react-with-addons build
2013-10-08 16:54:31 -07:00
Paul O’Shannessy
7da874d835 Add TransitionGroup example 2013-10-08 16:49:11 -07:00
Paul O’Shannessy
de9e94de5f Make sure react-with-addons ends up in react-source gem 2013-10-08 16:49:11 -07:00
Paul O’Shannessy
a151133161 Make sure react-with-addons ends up in bower 2013-10-08 16:49:11 -07:00
Paul O’Shannessy
042a2723ff Make sure addons builds are sent to build server 2013-10-08 16:49:11 -07:00
Paul O’Shannessy
2e6092b217 react-with-addons build
This creates a new standalone build which should have everything the
default build has, plus a little extra. This is not a sustainable long
term solution (we shouldn't make people choose like this) but it fixes
the problem we have in the short term.

This also removes the terrible react-transitions build. This is better
anway.

Fixes #369
2013-10-08 16:49:11 -07:00
Ben Alpert
f658c32df1 Tweak verbiage about required polyfills
I found it weird how the es5-shim comment came after the list of functions; now it's before.
2013-10-08 16:25:29 -07:00
Paul O’Shannessy
b16874c5a8 Merge pull request #407 from Samangan/master
renamed ReactOnDOMReady module to ReactMountReady
2013-10-08 15:12:29 -07:00
Connor McSheffrey
b9a657db2c fixed broken link on Community Round-up #9 blog post
closes #409
2013-10-08 11:09:33 -07:00
Josh Duck
dbc613199b Fix SelectEventPlugin
There were 2 issues:

I was reusing event outside the original event handler (activeNativeEvent).
This is a bad idea. I've changed deferred dispatch to have an empty object
as the nativeEvent.

I didn't handle inputs without .selectionStart (e.g. file inputs). I extracted
a input type check from ChangeEventPlugin and reuse it here.
2013-10-08 10:28:43 -07:00
Paul O’Shannessy
920c4206f4 Sync getActiveElement module from FB. 2013-10-07 15:32:47 -07:00
Paul O’Shannessy
fdb10c0679 React.__internals
We need access to internal modules in order to provide a single way for some
projects to work internally with @providesModule and externally.
2013-10-07 15:07:20 -07:00
Pete Hunt
325322898c Throw when calling transferPropsTo() on a component you don't own
This is dangerous because it means that data is flowing into the component from two components, only one of which is the actual "owner". While we may be able to figure out how to
support this someday, let's be strict and prevent it for now.
2013-10-07 15:07:04 -07:00
Sebastian Markbage
27669c09ca Move flattenChildren into MultiChild 2013-10-07 15:06:44 -07:00
Tim Yung
0c59c57d66 Speed Key Validation (by over 9000)
Use a valid identifier (and non-string) to reduce chance of de-optimizing in V8 and Nitro.
2013-10-07 15:05:56 -07:00
Christopher Chedeau
26d7c4275a Add warning when using componentShouldUpdate 2013-10-07 15:05:44 -07:00
Josh Duck
2b7a7599bb Add select event plugin
Polyfill 'onSelect' behavior for React.

Use non-standard 'selectionchange' event rather than 'select' event.
This allows us to fire the event when user moves the cursor via arrow
keys, and not just when they select multiple chars.

Add methods to ReactDOMSelection to make getting current selection
easier, so we can do a fast check for change without having to
calculate char offsets for selection start and end.
2013-10-07 15:02:57 -07:00
Sebastian Markbage
ed9c0ca87c Expose bound function, context and arguments
Exposes the bound context, original method and bound arguments for any
auto-bound methods, for debugging purposes.
2013-10-07 15:02:47 -07:00
Sebastian Markbage
68abbacc39 Expose the rendered children before they're actually mounted
Exposing the _renderedChildren property before all the children are fully
mounted. This allows us to debug a partially mounted tree when the debugger
has a breakpoint in the one of the mounting children.

This only has a functional difference in the case where mounting throws. This
will end up not mounting the component anyway. Any remounting shouldn't be
affected by this change.
2013-10-07 15:02:27 -07:00
Samangan
84d8e1841a renamed ReactOnDOMReady module to ReactMountReady
fix

renamed ReactOnDOMReady module to ReactMountReady
2013-10-05 01:35:56 -05:00
Vjeux
a9b3139ff8 Community round-up #9
http://fooo.fr:4000/react/blog/2013/10/03/community-roundup-9.html
2013-10-03 15:18:21 -07:00
Vjeux
582b720183 Add app id for comments moderation
This way we can be notified when any new comment appear in the docs/blog and add moderators
2013-10-03 22:32:20 +02:00
Ben Newman
0a02b55d95 Use nodeContains where appropriate. 2013-10-01 17:55:13 -07:00
Tim Yung
20af6a7ce8 Speed Owner Access (by over 9000)
Use a valid identifier (and non-string) to reduce chance of de-optimizing in V8 and Nitro.
2013-10-01 16:32:06 -07:00
Ben Newman
7c0f5c3237 Fix isEventSupported in recent versions of jsdom.
Setting the `eventName` attribute of an element to the empty string is not
enough to cause `typeof element[eventName] === 'function'` in jsdom. The
attribute value actually has to look like a function body.
2013-10-01 16:31:46 -07:00
Paul O'Shannessy
f43449d333 ReactNativeComponent -> ReactDOMComponent
In an effort to break the DOMy parts of React away from the non-DOMy parts, I'm renaming this.
2013-10-01 16:31:32 -07:00
Ben Newman
e66287f92e Copy the nodeContains module from static_upstream. 2013-10-01 19:18:09 -04:00
Paul O’Shannessy
f20626f17a Merge pull request #378 from spicyj/html-reconciliation
Fix reconciling when switching to/from innerHTML
2013-10-01 13:38:08 -07:00
Andrew Zich
ab00f8d15c Removed "ajaxify" from DefaultDOMPropertyConfig
The `"ajaxify"` attribute is Facebook-specific and does not belong in this repo.
2013-10-01 13:34:26 -07:00
Pete Hunt
58de758a32 Sort batched updates by owner depth
If we reconcile components higher in the hierarchy they will likely reconcile components lower in the
hierarchy. If we sort by depth then when we reach those components there will be no more pending state or
props and it will no op.
2013-10-01 13:33:12 -07:00
Paul O’Shannessy
8beaa211fb Merge pull request #387 from spicyj/exec-fix
Actually make exec work
2013-10-01 13:14:56 -07:00
Paul O’Shannessy
7c217324a6 Merge pull request #384 from chenglou/doc-link
Add doc link to DOM differences from JSX gotchas
2013-10-01 11:25:34 -07:00
Paul O’Shannessy
15c1358aaf Merge pull request #386 from chenglou/unitless-line-height
add line-height to unitless css props, test cases
2013-10-01 10:35:21 -07:00
Ben Alpert
0a45325621 Actually make exec work
The spec for eval (http://es5.github.io/x15.1.html#x15.1.2.1) says "If Type(x) is not String, return x." and that's exactly what's happening here -- it gets {code: ...} and does nothing.
2013-09-30 18:51:39 -07:00
Cheng Lou
607eeaed4b Add doc link to DOM differences from JSX gotchas 2013-09-30 20:46:41 -04:00
Paul O’Shannessy
c764adc256 Merge pull request #376 from spicyj/noglobal
Fix lint errors including use of `global`
2013-09-30 14:21:12 -07:00
Cheng Lou
27ee9c6eb0 add line-height to unitless css props, test cases 2013-09-30 13:56:56 -04:00
Pete Hunt
8835e9d99f Update README.md 2013-09-28 19:57:18 -07:00
Ben Alpert
3ca507d73f Fix reconciling when switching to/from innerHTML
There's no way that this can work if _updateDOMChildren doesn't know about dangerouslySetInnerHTML, so tell it.

Fixes #377.
2013-09-27 16:22:46 -07:00
Ben Alpert
3dc1074908 Test that React loads properly in a web worker
This should catch top-level uses of `window` and `document`, while lint rules catch `global`.
2013-09-27 14:38:11 -07:00
Ben Alpert
94d2bbb221 Fix lint errors including use of global 2013-09-26 16:55:26 -07:00
Pete Hunt
84dea7e971 Fix server rendering 2013-09-26 15:49:19 -07:00
Pete Hunt
781bbe2916 Merge pull request #375 from danielmiladinov/master
Change spec policy for getDefaultProps to SpecPolicy.DEFINE_MANY_MERGED
2013-09-26 13:45:34 -07:00
Daniel Miladinov
b0ae800d64 Change spec policy for getDefaultProps to SpecPolicy.DEFINE_MANY_MERGED
This will allow multiple mixins for a component to define
getDefaultProps and their values will be merged.

See also:
https://groups.google.com/d/msg/reactjs/UzSiXw2Vo5s/FxK7AHWOzLMJ
2013-09-25 23:52:29 -04:00
Paul O’Shannessy
848a8e1180 Remove animation "example"
It was never a real example and shouldn't have been checked in.
2013-09-25 11:08:24 -07:00
Paul O’Shannessy
fc0b68af28 Fix 404s to non-existent API docs 2013-09-24 16:00:52 -07:00
Paul O’Shannessy
c6f831e85f Redirect docs/reference.html 2013-09-24 15:47:17 -07:00
Vjeux
58173edb16 Community round-up #8 2013-09-24 14:18:11 -07:00
Pete Hunt
fc73bf0a0a ReactLink: two-way binding for React
This introduces `ReactLink` which is a super lightweight way to do two-way binding for React.

If you want to use a controlled form input today, it's a lot of lines of code:

http://jsfiddle.net/T3z3v/

Look how many times `name` is repeated in there. And you have to remember to wire up event handles and pass the right state and
right event handler for *each* form field. It's really annoying.

With ReactLink, you can "link" a form value to a state field. It's just some simple sugar around the value prop/onChange
convention:

https://gist.github.com/petehunt/6689857

Ah, much nicer! And requires very little core changes or extra bytes. `ReactLink` just wraps the current value and "request
change" handler into a little object and provides some sugar to create some from composite component state.
2013-09-24 12:14:25 -07:00
Marshall Roch
458836abd3 Fix use of 'window' in CompositionEventPlugin
access to `window` needs to be guarded by `ExecutionEnvironment.canUseDOM`.
2013-09-23 23:01:14 -07:00
Josh Duck
5d7633d74c Move composition event to plugin with polyfill
Move compositionstart/compositionend to a new event plugin.

Add a polyfill that listens to key and mouse events and uses selection to
determine which text has changed.
2013-09-23 16:27:01 -07:00
Josh Duck
8f15eea910 Add ReactDOMSelection module
Add a DOM based selection module. This can both be used on its own and
in ReactInputSelection where our current implementation is lacking.

There is still some inconsistency with how IE and modern browsers
handle block nodes. Should be OK if we are just getting and setting
and not trying to set selection based on character offsets.
2013-09-23 16:23:35 -07:00
Paul O’Shannessy
d27746ee0b Docs: Give headers ids for easy linking
This gives markdown headers an id so that we can link directly to
sections of our docs. This is better than the alternative of adding them
all ourselves.
2013-09-23 10:30:51 -07:00
Keito Uchiyama
d13ce702a8 Fix typo in doc 2013-09-22 15:09:36 -07:00
Keito Uchiyama
d262285827 Fix use of "it's" in docs 2013-09-22 13:24:25 -07:00
Jeff Morrison
b5a11a431e Merge pull request #336 from spicyj/jsx-spacing
JSX: Respect original spacing and newlines better
2013-09-20 10:59:21 -07:00
Pete Hunt
832d9de037 Rename unmountAndReleaseReactRootNode() -> unmountComponentAtNode()
This is just a better name; we may revisit the name later.
2013-09-19 14:46:49 -07:00
Josh Duck
578863881f Add composition events to React.
Composition events make it possible to detect IME entry/exit.
https://developer.mozilla.org/en-US/docs/Web/API/CompositionEvent
2013-09-19 14:30:21 -07:00
Paul O’Shannessy
8875e1dc3b Merge pull request #359 from SanderSpies/master
Give the user a warning when using unoptimized JSX code
2013-09-19 13:14:12 -07:00
SanderSpies
cd79ed32cb - removed creation of the id within the tooling integration doc (expect this to be done by @zpao's pull request)
- removed the if statement and now always provide a warning message (as proposed by @spicyj)
- improved the warning message
2013-09-19 06:48:38 +02:00
SanderSpies
1924b7c945 Correcting the markdown anchor 2013-09-19 00:58:37 +02:00
SanderSpies
d2bf50c63d Give the user a warning when using unoptimized JSX code and send the user to the correct location in the documentation to optimize. 2013-09-19 00:55:10 +02:00
Ben Newman
b1dd4149a0 Merge pull request #343 from benjamn/fix-if-statement-pruning
Make constant propagation smarter about pruning if statements
2013-09-18 11:10:56 -07:00
Paul O’Shannessy
208ebd35b7 Don't update the docs version by default
This was leading to a lot of unnecessary churn in the config file since
different YAML versions were serializing differently.
2013-09-18 10:40:12 -07:00
Ben Newman
adda400602 Make constant propagation smarter about pruning if statements. 2013-09-18 13:33:45 -04:00
Pete Hunt
a9d53dae72 Merge pull request #351 from spicyj/api-docs
Flesh out reference documentation, more API info
2013-09-17 16:12:16 -07:00
Tim Yung
ea0cde2cf4 Fix PropTypes Documentation 2013-09-17 16:09:23 -07:00
Sebastian Markbage
e5ba82a44b Fix DOM node warning
bdf2a9bb12 broke the warning that children aren't suppose to be real DOM nodes.
2013-09-17 16:04:44 -07:00
Ben Alpert
364d6029b6 Flesh out reference documentation, more API info 2013-09-17 16:01:57 -07:00
Pete Hunt
735223fc9f Merge pull request #356 from yungsters/master
Add link to third-party `JavaScript (JSX).tmLanguage` in docs.
2013-09-17 13:35:59 -07:00
yungsters
be9ac236fd Add link to third-party JavaScript (JSX).tmLanguage in docs. 2013-09-17 13:30:53 -07:00
Josh Duck
ed7fa0ed22 Stop ReactInputSelection breaking in IE8
In the IE code path the method assumed that the input.value property
was non-null. A quick fix is to use either value or innerText; which means
the same code can be shared for textarea and contentEditable components.

The code is slightly buggy because the range.parentElement() !== input check
will fail for contentEditable components when the focus within a deep DOM tree.
2013-09-14 06:18:03 -07:00
Tim Yung
3e4302e6ae Fix lint errors in tests 2013-09-14 06:17:50 -07:00
Josh Duck
1a38cb9e07 Ensure selection range exists
The selection object doesn't always have ranges. In Chrome the
selection is not updated before 'focus' event handlers are fired. See
http://jsfiddle.net/t4DYA/ for example.

The selection will have rangeCount of 0 and calling getRangeAt(0) will
throw error "Uncaught IndexSizeError: Index or size was negative, or greater
than the allowed value."
2013-09-14 06:16:15 -07:00
Paul O’Shannessy
71ad5cb37a Update wording 2013-09-14 13:48:17 +02:00
Paul O’Shannessy
8a7c977942 Merge pull request #338 from spicyj/fullpage-tests
Fix ReactRenderDocument tests
2013-09-11 16:54:48 -07:00
Paul O’Shannessy
63bacfacfd Merge pull request #339 from spicyj/doc-rendering
Fix full-page rendering
2013-09-11 16:54:31 -07:00
Paul O’Shannessy
c8ec4595bb Merge pull request #344 from benjamn/fix-silent-test-failure-due-to-requiring-React
Use a regular expression to parse out React.version
2013-09-11 16:03:59 -07:00
Ben Newman
133ea3df09 Use a regular expression to parse out React.version.
This fixes a silent failure of the test suite that appears to be due to
the call require('./build/modules/React').
2013-09-11 18:41:56 -04:00
Paul O’Shannessy
f729a28f3c Delete version.js
This file is an artifact of a build process long abandoned.
2013-09-11 14:20:26 -07:00
Paul O’Shannessy
7ff11c3c88 Merge pull request #332 from spicyj/radio-test
Fix radio input test in Chrome
2013-09-11 13:45:47 -07:00
Paul O’Shannessy
5ab68d9a0d Hard code version instead of doing constant replacement
This isn't really ideal, but it makes it so that people managing to
build with @providesModule still get a consistent experience (since this
is what gets packed client-side with react-page-middleware anyway).
2013-09-11 09:51:43 -07:00
Ben Alpert
58fae896fe Fix full-page rendering
Closes #337.

Test Plan:
Opened react-page sample without any JS errors. Also ran grunt test after cherry-picking this changeset on top of #338.
2013-09-11 01:26:49 -07:00
Ben Alpert
fea4fec0bc Fix ReactRenderDocument tests
I am unsure how this was ever supposed to work, as testDocument is guaranteed to be undefined at that point since beforeEach doesn't run synchronously. (I don't think there's any way to have beforeEach halt the tests.)
2013-09-10 22:42:05 -07:00
Paul O’Shannessy
d853bbcf77 Merge pull request #205 from spicyj/version
Add React.version
2013-09-10 18:35:12 -07:00
Paul O’Shannessy
f82f2a0fe2 Merge pull request #274 from chenglou/textarea-patch
fix textarea `value` of number 0
2013-09-10 18:01:33 -07:00
Ben Alpert
f69112cb3f JSX: Respect original spacing and newlines better
Fixes #335.

Now this JSX:

```
/** @jsx React.DOM */
var HelloMessage = React.createClass({
  render: function() {
    return <div>
      Look!
      <a href=
        "http://www.facebook.com/">Facebook
      </a>
    </div>;
  }
});
```

produces

```
/** @jsx React.DOM */
var HelloMessage = React.createClass({displayName: 'HelloMessage',
  render: function() {
    return React.DOM.div(null,
      " Look! ",
      React.DOM.a( {href:
        "http://www.facebook.com/"}, "Facebook "
      )
    );
  }
});
```

rather than the less-desirable

```
/** @jsx React.DOM */
var HelloMessage = React.createClass({displayName: 'HelloMessage',
  render: function() {
    return React.DOM.div(null,
" Look! ",      React.DOM.a( {href:"http://www.facebook.com/"}, "Facebook "      ),
    );
  }
});
```
2013-09-10 17:14:36 -07:00
Paul O’Shannessy
6d77ad4be3 Merge pull request #330 from spicyj/warn-class-for
Warn for 'class' and 'for' property names
2013-09-10 16:21:33 -07:00
Jeff Morrison
7a6a508066 Merge pull request #328 from zpao/no-transform-class
Stop transforming class -> className
2013-09-10 08:23:08 -07:00
Cheng Lou
cd019871e3 Fix input/textarea value of number 0 and false
Previously, setting textarea `value` to number 0 is treated as if `value` wasn't set at all (thus the textarea is cleared from 0 to '' upon `onChange`). `false` also renders as `"false"` instead of `""` for both `defaultValue` and `value`, on textarea _and_ input.
2013-09-10 10:40:53 -04:00
Paul O’Shannessy
63b58cf6b5 AUTHORS
Created a .mailmap file with all of the associations, then used
git + perl to create the AUTHORS file. In theory these should all get
picked up by npm.

I used ABC order so it would remain unbiased and automatable. I wish we
could go back and fill out the history or at least fix the commits we
have from CommitSyncScript, but oh well.

This also includes the script I used to automate this process in the
future.
2013-09-09 23:42:54 -07:00
Ben Alpert
3bbd966a82 Fix radio input test in Chrome
It seems like the `form="pluto"` was throwing it off and making the input live outside the form it should have been contained in, causing it to uncheck A. I added it intending to test the form attribute but ended up not needing it so removing it should be fine. (The tests were passing in phantomjs since it doesn't support the `form` attribute and simply ignored it.)

Test Plan:
grunt test; grunt test --debug
2013-09-09 23:38:05 -07:00
Isaac Salier-Hellendag
5388d70bb1 Add cut, copy, paste
Add clipboard events to React.

For forms, these shouldn't really be necessary -- the onChange event should handle deletions and insertions. For contenteditables, however, we need to be able to access clipboard data.
2013-09-09 23:33:05 -07:00
Ben Alpert
5fd4467bf7 Add React.version
getConfig needs to be a function because grunt.config.data.pkg.version isn't available at the time that grunt/config/jsx/jsx.js is required.

Test Plan:
grunt build, grunt lint, grunt test all work. After building, both react.js and react.min.js contain the version number.
2013-09-09 17:01:06 -07:00
Timothy Yung
aa765e8fa3 Merge pull request #287 from spicyj/noglobal
Remove all uses of ExecutionEnvironment.global
2013-09-09 16:23:20 -07:00
Ben Alpert
232b61044c Warn for 'class' and 'for' property names
Also stroke-linecap, stroke-width, stop-color, stop-opacity.

Test Plan:
grunt test
2013-09-09 15:59:42 -07:00
Ben Alpert
426cdbb3ae Remove all uses of ExecutionEnvironment.global
Closes #271.

All three of these files are DOM-specific so it should be fine to use window. (ReactEventTopLevelCallback isn't obviously DOM-specific but it calls getEventTarget which is so I think we're fine here.)

Test Plan:
grunt test, tried events in a real browser and they seemed to work still.
2013-09-09 15:51:06 -07:00
Paul O’Shannessy
d83fe785c5 Stop transforming class -> className
Update the broken examples too (`git grep class=`)
2013-09-09 15:37:43 -07:00
Ben Newman
888cc309e0 Stop using comments as boundary markers in dangerouslyRenderMarkup.
Jordan warned (and StackOverflow confirmed) that IE8 doesn't respect HTML
comment nodes when setting `.innerHTML`:
http://stackoverflow.com/questions/15006001/inserting-a-comment-in-innerhtml

The virtue of the comment strategy was that the parser did all the work of
maintaining the boundaries between markup chunks, using comments as the
boundary markers.  The new strategy (of tagging the first node with a
special attribute) has a similar virtue, since the parser should preserve
that attribute only for the nodes we care about, and any rendered nodes
that do not have the attribute can be ignored (and complained about by
`console.error`).
2013-09-09 14:59:55 -07:00
Paul O'Shannessy
4ed7b85ed8 Log unknown props only when we have a match
Logging every unknown property got very noisy when combined with use of `transferPropsTo`. I knew this would be a potential issue initially but decided it was worth it. Others disagreed and it's resulting in some confusion.

This changes the logging to ensure that we have a potential correction, so only DOMish properties should result in warnings.
2013-09-09 14:57:56 -07:00
Pete Hunt
647731e399 Supporting mounting into iframes
Sencha says that separating big components into their own iframes was important for performance:
http://www.sencha.com/blog/the-making-of-fastbook-an-html5-love-story.

Today the only thing stopping us is that events don't bubble to our events system from an iframe. This diff
looks at the owning document of the container and adds top-level listeners to it. It should not change
existing behavior and should improve our support for this.
2013-09-09 14:57:33 -07:00
Ben Newman
cd7d863f20 Avoid unnecessary array allocations in dangerouslyRenderMarkup. 2013-09-09 14:56:27 -07:00
Paul O'Shannessy
9d0f3623c3 Cache length of NodeList when updating radios 2013-09-09 11:53:13 -07:00
Pete Hunt
e010a2d90b Fix bugs with CSS3 animation event in webkit
We were incorrectly sniffing the animationend event.
2013-09-09 11:52:59 -07:00
Paul O’Shannessy
d704bc24f4 Initial build of ReactTransitionGroup
This builds `ReactTransitionGroup` with it's own copy of `React`, which
it total clownshoes. This should be technically usable, but definitely
should not be used in any production environment.
2013-09-07 16:18:14 -07:00
Paul O’Shannessy
ff2fc586d5 Merge pull request #324 from chenglou/backbone-todo-ex
Fix backbone todo example bugs.
2013-09-07 14:53:01 -07:00
Cheng Lou
78d305eb16 Fix backbone todo example bugs.
Fixed:
- New todo not submitting correctly (page refreshes. `preventDefault`
wasn't there.
- Old checked todo being removed will leave the checkmark on the next
todo replacing its position.
- Cannot change todo (`value`'s now a controlled field).
- `autofocus` (should be `autoFocus`, how ironic given the current
situation) on new todo input isn't working. Switched to manual
`focus()` in `componentDidMount` for now.
- More consistent breathing space between lines.
- Gutter at 80.

Added:
- Use todomvc-common base.css. The old one had to change ids to
classes. No longer necessary.
- Give `cx` a better name and move it in `Utils`.
- Trim input upon finishing edit.
- Remove todo if the new edited value is empty.
- Submit edited todo value on input blur.
- README to explain the existence of this example. Being able to
maintain a non-compilant version allows nice deviations from the
todomvc specs, such as animations, in the future.
2013-09-07 17:44:05 -04:00
Paul O’Shannessy
6b5c1810c0 Merge pull request #323 from benjamn/simplify-bin/jsx
Simplify bin/jsx to perform just the JSX transform
2013-09-07 14:41:55 -07:00
Paul O’Shannessy
e41912d6d4 Merge pull request #325 from spicyj/elseifdev
Move else if (__DEV__) into two statements
2013-09-07 14:08:03 -07:00
Ben Alpert
97e0926696 Move else if (__DEV__) into two statements
The minification stage doesn't like `else if (__DEV__)`.
2013-09-07 14:03:48 -07:00
Paul O’Shannessy
8df407deb8 Merge pull request #281 from spicyj/radio
Fix controlled radio button behavior
2013-09-07 13:54:57 -07:00
Paul O’Shannessy
2ba405d5f8 Merge pull request #267 from spicyj/warn-props
Warn about unknown property values
2013-09-07 13:06:41 -07:00
Ben Newman
658f41cb30 Simplify bin/jsx to perform just the JSX transform.
We will continue using `bin/jsx-internal`, well, internally.

Note that this version no longer respects `@providesModule`, and it
doesn't do anything special with constants like `__DEV__`, so we can no
longer get to claim that `bin/jsx` can be used to build the core.

I'm happy about this, personally, because it demonstrates the flexibility
of Commoner.
2013-09-06 16:20:25 -04:00
Ben Newman
ebc0d09595 Merge pull request #322 from petehunt/build-animations
Add ReactTransitionGroup to the build
2013-09-06 10:49:30 -07:00
petehunt
f7ea031dac Add ReactTransitionGroup to the build 2013-09-06 10:47:18 -07:00
Ben Alpert
b56b5885d0 Fix controlled radio button behavior
Fixes #242.
2013-09-06 00:57:51 -07:00
Ben Alpert
a4c23d328c Warn about unknown property values
Fixes #255.
2013-09-06 00:33:01 -07:00
Paul O'Shannessy
3cf14e8f9b Remove ReactChildren methods from React object
These are not terribly useful on this object and the naming of
`React.forEachChildren` sucked anyway.
2013-09-05 18:35:59 -07:00
Pete Hunt
c8886a0424 Make mounting on the root of the page work correctly
This was apparently only partially supported. We had issues initially mounting if there was no HTML present and
also had issues if we had to update HTML that was already there. This diff fixes all of these cases and has
tests to prove it. NOTE: I removed a test that was actually erroneous. My bad.
2013-09-05 13:50:18 -07:00
Paul O’Shannessy
4f0dea3e7e Merge pull request #294 from clayallsopp/better_update_msg
More helpful message if you update an unrendered component
2013-09-05 11:54:07 -07:00
Clay Allsopp
9dd8ef4777 fix formatting and test for correct error 2013-09-04 18:13:33 -07:00
Paul O’Shannessy
65c4ef91c7 Sync CSSCore from upstream 2013-09-04 16:47:16 -07:00
Pete Hunt
32d3d7774a Use dumpCache() rather than manual reset
I forgot this module existed until @benjamn reminded we had a way to do it.
2013-09-04 15:54:27 -07:00
Pete Hunt
8664c8ac57 Test cases covering rendering onto document
There were some bug reports here, I couldn't reproduce but wrote tests anyway. We should definitely have these.
2013-09-04 15:54:11 -07:00
Ben Newman
dea0cc01cf Improve error behavior of Danger.dangerouslyRenderMarkup.
HTML comment nodes are now interspersed in the original markup list so
that we can tell which chunks of markup rendered as more or less than one
node, and give a more helpful error message in that case.

Regardless of how many nodes were rendered, we only take the first one. If
zero nodes were rendered, then `resultList` will contain `null` at the
corresponding position.

If we decide to revisit the idea of using document fragments, it will be
very easy to handle the `!== 1` case by returning a document fragment.
2013-09-04 15:54:09 -07:00
Pete Hunt
80f1590265 Add ReactTransitionGroup
This introduces <ReactTransitionGroup>, a component that works a lot
like Angular's ng-animate.

The problem we're currently facing is twofold:
1. We don't really have a great convention surrounding CSS transitions
   in React
2. (harder) we can't animate nodes that are leaving the DOM, as their
   nodes are instantly destroyed.

To solve the first issue I've adopted Angular's convention. It's
implemented in ReactTransitionableChild.

The second part is what's tricky. To do this I've implemented three modules:
- ReactTransitionableChild, which can keep its old children around if they
  change to null
- ReactTransitionKeySet, which can look at a prev and next set of child
  keys and merge them in a reasonable way
- ReactTransitionGroup, which combines ReactTransitionableChild and
  ReactTransitionKeySet to keep nodes that are leaving the DOM in the
  DOM until their animations are complete
2013-09-04 15:54:06 -07:00
Paul O’Shannessy
c25c5b543b Update wording 2013-09-04 15:26:31 -07:00
Cheng Lou
8852b86ad8 Add Stack Overflow link for doc support page. 2013-09-04 16:01:48 -04:00
Paul O'Shannessy
a42fd30fc2 Remove React.autoBind for real
This has been deprecated for a long while now, we should actually remove it.
2013-09-03 14:27:00 -07:00
Pete Hunt
406dcbd8da Fix a few GC leaks in events system
Summary:
    - Weren't pooling the Transaction in the batching strategy
    - Creating a new closure for every event tick due to batchedUpdates()
    - EnterLeaveEventPlugin creates a new array on each event.

I wonder if there is more optimization opportunity in accumulate(). Squinting at the fps graph this seems to be faster and waste less memory but it's hard to conclusively tell. I did verify that these were all hotspots though.
2013-09-03 14:27:00 -07:00
Paul O’Shannessy
de61f9fd81 Merge pull request #298 from vjeux/pagination
Add pagination to blog
2013-09-03 13:35:12 -07:00
Paul O’Shannessy
57fe412619 Merge pull request #305 from brianr/tutorial-explain-showdown
Tutorial: show how to add showdown.js
2013-09-03 13:33:05 -07:00
Pete Hunt
b4ff29ac78 Merge pull request #312 from zpao/docs-redirect
Redirect /docs to the right page
2013-09-03 13:30:16 -07:00
Paul O’Shannessy
ba460de7ed Redirect /docs to the right page
I've hit this a few times where I want to get to docs so I take whatever
my urlbar gives me and strip out the actual page so I can get to the
root, however that's a 404.

This introduces a super easy way to redirect, which could be handy in
the future as docs get rewritten.

I would much rather do this with a real htaccess file or even just
handle 404s gracefully, but that's not currently an option with GitHub
pages (since we generate our own and don't use a custom domain).
2013-09-03 13:25:23 -07:00
Pete Hunt
c7768fde5d Merge pull request #307 from chenglou/todomvc-director
sync with tastejs todomvc
2013-09-02 10:22:58 -07:00
Clay Allsopp
15f84a391d move lifecycle check into replaceProps instead of updateComponent 2013-09-01 18:42:01 -07:00
Cheng Lou
2b9c34b5c7 sync with tastejs todomvc 2013-08-31 21:54:37 -04:00
Brian Rue
403b087e97 Tutorial: show how to add showdown.js 2013-08-30 16:29:01 -07:00
Sebastian Markbage
75aee1714b Expose the instance cache
We need access to the instance cache for debugging tools. Ideally we want to
expose a more stable and supported interface but this seems like a quick win,
for now.
2013-08-30 13:21:04 -07:00
Pete Hunt
c41e86c990 Make ReactDefaultPerf work server-side
We were reading from window which was throwing when ReactDefaultPerf was injected.
2013-08-30 13:20:53 -07:00
Paul O'Shannessy
4d8f0449d9 React.isValidClass
Sometimes you may need to detect if a value is a valid React class constructor. This enables that and prevents future consumers from getting caught in the trap of depending on an internal implementation detail we might change.

Currently this works for classes created with `React.createClass` as well as `React.DOM.*`.
2013-08-30 13:20:51 -07:00
Pete Hunt
0db4077c3a Make React batching strategy injectable 2013-08-30 13:20:48 -07:00
Tim Yung
f88aa35187 Change vendored module isDOMNode -> isNode 2013-08-30 13:20:45 -07:00
Andrew Zich
7d34c09e17 Don't trigger mouse events on native button elements that are disabled
This adds a `ReactDOMButton` module that shims the native `<button>` React component so it doesn't receive mouseup, mousemove, mousedown, click, or double-click events when its disabled property is truthy.
2013-08-30 13:20:40 -07:00
Paul O’Shannessy
e11c4ecbaf [docs] Small tweaks as reported in comments
* highlight `</form>`
* use correct id in `getElementById` call
2013-08-28 14:42:07 -07:00
Paul O’Shannessy
553ed1416c Update package dependencies
Sometimes I look at https://david-dm.org/facebook/react
2013-08-27 14:46:06 -07:00
Paul O’Shannessy
688f5051e6 Sync objMap from upstream 2013-08-27 14:43:46 -07:00
Pete Hunt
adb666e67f Allow getInitialState() for mixins
Today mixins can't easily be stateful because they can't provide getInitialState(). This allows multiple getInitialState() methods as long as they don't return objects that have conflicting keys. In that case, we throw.
2013-08-27 14:17:26 -07:00
Paul O’Shannessy
07e2072692 Support props for <meta> elements.
`content`, `httpEquiv`, `charSet` are all needed. We're currently
working around this in `react-page`.

`content` is the risky one here since we previously supporting using
`content` to set the text content. We removed support for that in
e998041229 so the risk is minimal, there
just might be some lingering old code.

Fixes #292

Test Plan: Visit `data:text/html,<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" charset="utf-8"></head>`

```
var m = document.querySelector('meta');
m.httpEquiv; // Content-Type
m.httpEquiv = 'foo';
m.httpEquiv; // foo

m.charset; // undefined
m.charSet; // undefined
m.getAttribute('charset'); // utf-8
m.setAttribute('charset', 'bar');
m.getAttribute('charset'); // bar

m.content; // text/html; charset=utf-8
m.content = 'baz';
m.content; // baz
```
2013-08-27 11:45:59 -07:00
Vjeux
1c14cd6c8b Add pagination to blog
- Add pagination
- Display full content in /blog
- Truncate Recent posts
- Add permalink that lists all the blog posts
- Add spacing and bullet around recent posts to make it more readable
2013-08-27 02:14:17 +02:00
Paul O’Shannessy
744b54a829 Fix capitalization of Tooling Integration page 2013-08-26 14:53:56 -07:00
Vjeux
a90c463abe Update the tooling page to include pyReact, react-rails and react-page 2013-08-26 14:49:31 -07:00
Vjeux
6bf21f1610 Community round-up #7
http://fooo.fr:4000/react/blog/2013/08/26/community-roundup-7.html
2013-08-26 14:22:16 -07:00
Ben Alpert
364ee1ffae Add missing "use strict" statement to pass lint
Test Plan:
grunt lint; grunt test
2013-08-26 13:46:11 -07:00
Clay Allsopp
88faef3ba9 Add more helpful invariant if you're updating an unrendered component 2013-08-26 10:42:53 -07:00
Eric Clemmons
bcc6b524fb Add rowSpan DOM property 2013-08-25 13:32:38 -05:00
Sebastian Markbage
61b38b9f05 Explicit and Implicit Keys Need Separate Namespaces
There are certain cases where you can end up with a collision with an implicit
key (array index) if your explicit key prop is a number. They should use
different namespaces. Therefore I wrap explicit keys in curlies and implicit
array indices in brackets.

I added a simple test case, but another case came up on the mailing list. Where
undefined entries in an array actually results in an entry and therefore an
implicit key.
2013-08-23 14:05:18 -07:00
Danny Ben-David
fce57abeca Benchmarking tool for React application performance
ReactAppPerf wraps core methods and logs info from them; there's no real
UI at this point
2013-08-23 14:05:11 -07:00
Paul O’Shannessy
946e9b0c80 Merge pull request #289 from jordwalke/ServerRenderingFixes3
Server rendering: rendering of entire document using React.
2013-08-23 13:14:06 -07:00
Jordan Walke
748ed6cd81 adding better test - moving execution env module. 2013-08-23 12:32:35 -07:00
Jordan Walke
49f174cdad Server rendering: rendering of entire document using React.
Summary: Allows rendering of React into the "document" as opposed to into a
particular node. To recap some basics:

document: One level above the <html> tag - like the browser.
document.documentElement: <body>

To support full-page server side rendering, we need to be able to render
*everything* including the HTML/BODY tags. This allows that.
2013-08-23 02:04:07 -07:00
Paul O’Shannessy
6ca8d31c83 [react-tools] Add src/ to files
This is so it's possible to use the original @providesModule source
files in a toolchain that understands those.
2013-08-22 22:35:50 -07:00
Paul O’Shannessy
aa1fa7468b Merge pull request #280 from jeffmo/jstransform_npm
Move to using `jstransform` and `esprima-fb` npm modules
2013-08-22 15:43:59 -07:00
JeffMo
2d048f1f34 Move to using jstransform and esprima-fb npm modules 2013-08-22 15:28:41 -07:00
Clay Allsopp
3d1cc16a9b Add CDNJS to docs. Fixes #244 2013-08-22 11:07:50 -07:00
Paul O’Shannessy
cbe86e04b3 Docs: fix header 2013-08-22 11:02:09 -07:00
Paul O’Shannessy
a558e560bd Use script to find remaining 404s. Fix them. 2013-08-22 10:59:22 -07:00
Clay Allsopp
cfe4152b1d Fix broken tutorial link and change wording 2013-08-21 22:38:44 -07:00
Kunal Mehta
91c2a8d90b Added PyReact blog post. 2013-08-19 14:48:28 -07:00
Christopher Chedeau
2c8f907b2c Merge pull request #277 from stoyan/patch-1
typo fix
2013-08-19 11:45:51 -07:00
Tim Yung
669f4b867f Allow DOM Nodes in ImmutableObject
Currently, `ImmutableObject` will stack overflow while it tries to recurse and deep freeze all the properties of a DOM node.
2013-08-19 11:37:08 -07:00
Stoyan
5fae286cf4 typo fix 2013-08-19 11:35:46 -07:00
Timothy Yung
a2c90aad86 Merge pull request #275 from spicyj/input-private
Make getChecked, getValue, handleChange private
2013-08-19 11:20:52 -07:00
Ben Alpert
898621d0a1 Make getChecked, getValue, handleChange private
Test Plan: grunt test, enter text in ballmer-peak example without any JS errors.
2013-08-17 22:29:41 -07:00
Timothy Yung
e1c1d869de Merge pull request #251 from spicyj/select-value
Fix behavior of ReactDOMSelect with `defaultValue`
2013-08-17 21:50:13 -07:00
Ben Alpert
25e2cd0db6 Fix behavior of ReactDOMSelect
Closes #250.

Test Plan:
With multiple and not, verified: With defaultValue, the correct option is picked initially, user changes change the selection, and changes to defaultValue have no effect. With value, the correct option is picked initially, user changes do nothing, and changes to value change the selection.

Also ran the tests.
2013-08-17 16:57:49 -07:00
Paul O’Shannessy
1f8ef4c903 Sync modules to vendor/core
We haven't done this recently. Nothing has changed significantly, though
this does remove some files we weren't using.
2013-08-16 15:40:23 -07:00
James Ide
d9511d817a Move utils out of React that aren't being used
Many of React's util functions are non-redundant with Facebook's core
libraries, so move them out of React into a central location (out of
this repo).

These files were not getting used by any part of React core, so didn't
actually belong here anyway.
2013-08-16 15:40:11 -07:00
Cheng Lou
2fda70fb4a fix test case for rendering text node number 0 2013-08-16 13:51:17 -07:00
Sebastian Markbåge
02f618d52c Merge pull request #268 from spicyj/bind-null
Make .bind(null, ...) work on autobound methods
2013-08-16 12:06:49 -07:00
Jordan Walke
61c47e4cae Refactor ReactComponent to have no dependency on the DOM.
React is more than just a DOM app library, it is a component
abstraction library. This enforces that.
2013-08-15 10:56:39 -07:00
Jordan Walke
e6b216bdbb Extract out core ReactEmitter functionality.
Other environments can make use of some of the logic in ReactEventEmitter.
2013-08-15 10:56:30 -07:00
Ben Alpert
192727e152 Make .bind(null, ...) work on autobound methods
Fixes #266.
2013-08-15 09:58:38 -07:00
Paul O’Shannessy
cb00d3e66c Upgrade phantomjs to 1.9.1-4
This fixes the install and permissions issues we've been seeing with
other 1.9.1-x versions.
2013-08-13 15:37:26 -07:00
Paul O’Shannessy
987e5e8f13 Merge pull request #258 from chenglou/patch-3
defaultValue of 0 now displayed
2013-08-12 18:20:32 -07:00
Paul O’Shannessy
df0bc8c3af Merge pull request #261 from benjamn/phantomjs-1.9.0-1
Hold PhantomJS version at 1.9.0-1.
2013-08-12 15:21:50 -07:00
Ben Newman
983120102c Hold PhantomJS version at 1.9.0-1.
And don't attempt any chmod magic, either.
2013-08-12 17:47:31 -04:00
Cheng Lou
86c0b69390 separate new tests into respective file 2013-08-12 17:03:10 -04:00
Cheng Lou
d5989a0de4 tests for displaying defaultValue of 0 2013-08-12 16:08:16 -04:00
Cheng Lou
1b747c526c defaultValue of 0 now displayed
previously treated as empty string when passed to input text/textarea
2013-08-09 23:13:44 -04:00
Paul O'Shannessy
5cbabdf4c9 Support autocapitalize DOM Property
It's non-standard, but potentially useful on mobile.

See some discussion in google group: https://groups.google.com/forum/#!topic/reactjs/MBcCFohHHHA

Closes #247
2013-08-06 14:19:49 -07:00
Paul Shen
9ef4e74ba2 ReactChildren
Instead of changing `traverseAllChildren`, keep that around for perf
reasons (for the hot code path `flattenChildren`)

Introduce `ReactChildren.map` and `ReactChildren.forEach`
which mirrors `Array.prototype.map` and `Array.prototype.forEach`. This
involves a rename of `mapAllChildren`
2013-08-06 14:17:33 -07:00
Vjeux
0321171113 Community Round-up #6 2013-08-06 01:31:23 +02:00
Christopher Chedeau
d542621155 Fix 404 in Getting Started 2013-08-04 21:09:15 -07:00
Pete Hunt
4bbf8acc9b Merge pull request #249 from pcottle/fixLinks
Fix Github links in examples
2013-08-04 17:40:00 -07:00
Peter Cottle
a21556314d Fix Github links in examples
Looks like we link to github.com/facebook/react/ instead of react-js. This just fixes the links

`grep -r "facebook/react.js" .` comes up clean now
2013-08-04 16:40:12 -07:00
Paul O'Shannessy
99d3d7f914 Get rid of remaining ReactID references
It's gone. Also compacted a bit of code to match the other usage.
2013-08-01 13:58:28 -07:00
Paul O’Shannessy
86d9e0a97a Merge pull request #245 from chenglou/patch-3
Change ref from ReactID to ReactInstanceHandles
2013-08-01 13:41:10 -07:00
Cheng Lou
db0ff96200 Change ref from ReactID to ReactInstanceHandles 2013-08-01 14:52:08 -04:00
Tim Yung
808e625d9d Use createNodesFromMarkup
Pulled out markup rendering logic for better reuse.
2013-07-31 21:21:06 -07:00
Paul O’Shannessy
dc06704ec7 react-rails blog post 2013-07-30 15:25:44 -07:00
Tim Yung
5ef3c1b09b Fix Reconciling Components to Content
This fixes a reconciliation bug introduced by adffa9b0f4.

The new unit test case exhibits the bug. When a component that has rendered child components is updated to render inline text, we usually:

 # Unmount and remove all child components.
 # Set the new inline text content.

However, with batched child operations, we do not **remove all child components** until later. The current implementation will set the inline text content and blow away those nodes, causing a fatal when `ReactMultiChild` later tries to find and remove those nodes.

This fixes the bug by ensuring that text content changes are also enqueued.
2013-07-29 16:15:30 -07:00
Paul O’Shannessy
fe451c30f8 Merge pull request #241 from gasi/master
Fix incorrect port of standard Python server
2013-07-29 11:09:37 -07:00
Daniel Gasienica
6f2848f4a6 Fix incorrect port of standard Python server
/ht @zpao
2013-07-29 10:59:43 -07:00
Paul O’Shannessy
d63ce62916 Merge pull request #207 from thisishugo/patch-1
update dead jsx link to point to an extant page
2013-07-29 09:11:37 -07:00
Ben Newman
c7d6a5ae4d Merge pull request #237 from yungsters/master
Fix Test Failures
2013-07-28 07:02:17 -07:00
yungsters
d5e970b93f Fix Danger test failures.
The original tests were flawed because the `Danger` module exploits the fact that all React-generated markup has at least one attribute. This allows the module to extract node names from markup strings faster.

However, the tests were passing in strings of markup with no attributes.

Also, this fixes a test failure due to the test trying to set text content into a `<tr>` which is typically disallowed by browsers (and PhantomJS). This changes it to use `<td>` instead.
2013-07-28 01:05:13 -07:00
yungsters
4cb49f5561 Change ReactMultiChild test to check for innerHTML descriptor.
Not all testing environments will support setting the `innerHTML` descriptor. For example, PhantomJS initializes the `innerHTML` property as not configurable.
2013-07-28 01:04:24 -07:00
Paul O’Shannessy
c347b720a9 Updated Readme for 0.4.1 2013-07-26 15:57:37 -07:00
Paul O’Shannessy
27a1729f6d Blog post for v0.4.1 2013-07-26 15:56:52 -07:00
Paul O’Shannessy
a1f5c1dee7 Updated Changelog for 0.4.1 2013-07-26 15:56:22 -07:00
Paul O’Shannessy
20179b7991 Send branch info from travis for continuous builds 2013-07-26 14:28:33 -07:00
Tim Yung
adffa9b0f4 Batch Child Markup Generation
Setting `innerHTML` is slow: http://jsperf.com/react-child-creation/2

This reduces the number of times we set `innerHTML` by batching markup generation in a component tree.

As usual, I cleaned up the `ReactMultiChild` module significantly.

== Children Reconciliation ==

When a `ReactNativeComponent` reconciles, it compares currently rendered children, `prevChildren`, with the new children, `nextChildren`. It figures out the shortest series of updates required to render `nextChildren` where each update is one of:

 - Create nodes for a new child and insert it at an index.
 - Update an existing node and, if necessary, move it to an index.
 - Remove an existing node.

This serializable series of updates is sent to `ReactDOMIDOperations` where the actions are actually acted on.

== Problem ==

There are two problems:

 # When a `ReactNativeComponent` renders new children, it sets `innerHTML` once for each contiguous set of children.
 # Each `ReactNativeComponent` renders its children in isolation, so two components that both render new children will do so separately.

For example, consider the following update:

  React.renderComponent(<div><p><span /></p><p><span /></p></div>, ...);
  React.renderComponent(<div><p><img /><span /><img /></p><p><img /><span /><img /></p></div>, ...);

This will trigger setting `innerHTML` four times.

== Solution ==

Instead of enqueuing the series of updates per component, this diff changes `ReactMultiChild` to enqueue updates per component tree (which works by counting recursive calls to `updateChildren`). Once all updates in the tree are accounted for, we render all markup using a single `innerHTML` set.
2013-07-26 12:48:07 -07:00
Tim Yung
2e37f65bdc Delete throwIf
Deletes `throwIf()` in favor of having one way to throw errors: `invariant()`
2013-07-26 12:48:07 -07:00
Paul O'Shannessy
2e43de20cc Cleanup 2nd param to ReactEventEmitter.ensureListening
It was removed, so these callsites aren't actually doing anything.
2013-07-26 12:25:03 -07:00
Paul O’Shannessy
a41aa76ef3 Merge pull request #224 from spicyj/cb-context
Call callbacks from setState in component context
2013-07-25 09:04:17 -07:00
Tim Yung
bdf2a9bb12 Use invariant in react/utils
Just some therapeutic cleanup.
2013-07-24 17:41:54 -07:00
Tim Yung
8d48610b7e Typecheck ImmutableObject
Just some therapeutic cleanup.
2013-07-24 17:41:37 -07:00
Tim Yung
759425fc90 Use invariant in OrderedMap
Just some therapeutic cleanup.
2013-07-24 17:41:22 -07:00
Jordan Walke
2ee66262db Remove circular dependencies in React Core.
There is a circular dependency between `ReactID`, `ReactMount` and
`ReactInstanceHandles`. Ben and I talked about this today. It seems like the
simplest solution is to consolidate a lot of the code that Ben recently wrote
into `ReactMount`. We can later find ways to trim code out of this module
without causing circular deps.
2013-07-24 17:40:57 -07:00
Pete Hunt
260d90ba02 Warn when server-rendered markup is not what we expect on the client
As @leebyron and balpert pointed out, if the markup on the server is differnet than what the client expects undefined behavior and chaos may ensue. A good fallback
is for us to just inject the client-side markup (as it is the source of truth) and warn the user in __DEV__ that something is wrong. In order to do a fast
browser-independent check of the DOM I use an adler32 checksum of the generated markup. I believe this is better than a simple innerHTML compare because different
browsers massage innerHTML differently.
2013-07-24 17:39:59 -07:00
Jordan Walke
492407bcc9 Fix OrderedMap.
Tim caught a bug. Squashing it so he can rebase on top of it.
2013-07-24 17:39:37 -07:00
Paul O’Shannessy
ddb0ef98f7 Fix "Suppport" type in docs 2013-07-24 13:13:27 -07:00
Paul O’Shannessy
8dd4428c55 Merge pull request #217 from jakubmal/non-browser-env
Allow to execute JSXTransformer outside of browser environment
2013-07-23 17:29:14 -07:00
Jakub Malinowski
795a84d60f Do not export load in JSXTransformer unless in a browser environment 2013-07-23 23:01:38 +02:00
Jakub Malinowski
947e17154a Merge remote branch 'upstream/master' into non-browser-env 2013-07-23 22:31:48 +02:00
Cheng Lou
7f8b2885d9 fix jquery-bootstrap example bugs
Old one had some bugs:
- 'x' on modal wasn't showing.
- trying to close modal in unmount, but modal had a closing animation.
2013-07-23 11:01:42 -07:00
Paul O’Shannessy
d1c5cda93f Use the right home page for react-source gem 2013-07-23 10:55:41 -07:00
Vjeux
975b5d978f Community Round-up #5
http://fooo.fr:4000/react/blog/2013/07/20/community-roundup-5.html
2013-07-23 09:23:50 -07:00
Ben Alpert
f1231e60b0 Call callbacks from setState in component context
This is way more useful than the alternative.
2013-07-22 23:47:07 -05:00
Tim Yung
4deb0d619c Fix Clicks in Mobile Safari
This works around a bug with listening to clicks using event delegation on Mobile Safari using an event plugin.

NOTE: We don't enable touch events by default, so I don't know if would want to inject this plugin by default. In fact, I'm not sure what our strategy is at all for when to invoke `React.useTouchEvents(true)`.
2013-07-22 18:31:33 -07:00
Tim Yung
cf3ff07f92 Fix TypeError in SyntheticEvent
I suspect that plugins are modifying `Object.prototype` which is causing TypeErrors in `SyntheticEvent`. Let's fix it.
2013-07-22 18:31:08 -07:00
Paul O’Shannessy
bbb4a367be Run grunt build with npm test so that we can upload all files 2013-07-22 18:16:44 -07:00
Paul O’Shannessy
63d6cc013e Push builds from travis to remote host 2013-07-22 18:07:43 -07:00
Paul O'Shannessy
d1d2d8d463 Don't set DOM attributes to "undefined" on update
We already skip `null` and `undefined` when building up the stringified html on first render, but if you update a component to the *exact same* conditions, React will leave the DOM in a different state. We shouldn't do that.
2013-07-22 10:28:21 -07:00
Jordan Walke
74cfc9c274 Remove unused dependency on ReactMount
We don't really use these, and this will make our lives easier.
2013-07-22 10:28:12 -07:00
Ben Newman
add809be21 Add comment explaining internalGetID 2013-07-22 10:28:09 -07:00
Paul O’Shannessy
579d86f024 Merge pull request #218 from chenglou/patch-2
upgrade example to 0.4
2013-07-20 16:33:05 -07:00
Cheng Lou
73ceb5a401 upgrade example to 0.4
manually tested
2013-07-20 16:05:25 -04:00
Jakub Malinowski
2b9dd04f4d Allow to execute JSXTransformer outside of browser environment 2013-07-20 15:10:36 +02:00
Paul O’Shannessy
4f53fbf1a2 Merge pull request #216 from phleet/patch-1
Docs Typo Fix: s/pased/passed
2013-07-19 16:47:44 -07:00
Cheng Lou
64d72f8c4b fix typos 2013-07-19 16:40:09 -07:00
Jamie Wong
50a00662cf s/pased/passed 2013-07-19 18:48:46 -04:00
Paul O’Shannessy
d7fcbe0f96 Merge pull request #213 from benjamn/remove-stray-nodes-after-each-test
After each test, remove any stray nodes added to the document
2013-07-19 11:26:50 -07:00
Ben Newman
0441d4c7f5 Rename removeSiblings to removeNextSiblings. 2013-07-19 14:18:44 -04:00
Paul O’Shannessy
d9aa2bd12c Merge pull request #212 from spicyj/docfix
One-character typo fix
2013-07-19 11:02:40 -07:00
Ben Alpert
222faf4544 One-character typo fix 2013-07-19 10:55:31 -07:00
Ben Newman
36fbd8d941 After each test, remove any stray nodes added to the document.
This was not necessary when we were running each test in its own
`<iframe>`, and it doesn't seem to affect any test behavior currently, but
it seems wise for the sake of test isolation and hygiene.
2013-07-19 13:53:15 -04:00
Paul O’Shannessy
547079763e Merge pull request #211 from phleet/patch-1
Docs Typo Fix: s/distinciton/distinction
2013-07-19 10:36:25 -07:00
Paul O’Shannessy
a7dfe04406 Merge pull request #210 from benjamn/rewrite-Function.prototype.bind-polyfill
Pull in my rewritten Function.prototype.bind polyfill from upstream
2013-07-19 10:23:17 -07:00
Jamie Wong
bf275a9097 Docs Typo Fix: s/distinciton/distinction 2013-07-19 12:33:54 -04:00
Ben Newman
507e58ed96 Pull in my rewritten Function.prototype.bind polyfill from upstream.
We don't sync upstream polyfills (because we don't have a story for how
they would be used), so this needs to be updated manually.

Sacrificed some negligible performance optimizations to reduce the number
of different cases from four to one.

It's important to test this implementation in PhantomJS, since that's the
only browser that I know of where built-in functions sometimes do not have
a `.prototype`.
2013-07-19 12:28:44 -04:00
Paul O’Shannessy
d9c0be408b Merge pull request #209 from benjamn/speed-up-tests
Abandon <iframe> test isolation hack now that dumpCache works
2013-07-19 09:10:52 -07:00
Ben Newman
5beb481145 Abandon <iframe> test isolation hack now that we have dumpCache.
This cuts the running time of `grunt phantom:run` from 4.4s to 3.1s on my
machine, because we no longer have to load/execute a separate instance of
`react-test.js` in a separate `<iframe>` for each test.
2013-07-19 11:10:02 -04:00
Ben Newman
7ef5172d80 Don't call require("mock-modules").register("test/all", ...).
The "test/all" module will never be mocked, nor should it ever need to be
reset by `dumpCache`.
2013-07-19 11:10:02 -04:00
Hugo Jobling
4ab62a6bd2 remove dead link
the event handling doc page no longer exists
2013-07-18 11:05:39 +01:00
Hugo Jobling
07427ae9d0 put closing paren in correct place 2013-07-18 10:44:22 +01:00
Hugo Jobling
8f55d94d40 update dead jsx link to point to an extant page
syntax.html no longer exists, so point people at the in depth article instead.
2013-07-18 10:36:54 +01:00
Pete Hunt
e6812d7e36 Add iframe attributes to React
These are pretty useful for building apps and stuff.
2013-07-17 20:39:19 -07:00
Ben Newman
75ce576d3d Avoid some innocuous test warnings.
This reduces some console.warning spew from `grunt test` output.
2013-07-17 20:38:32 -07:00
Ben Newman
fa7cc57a6d Merge pull request #206 from benjamn/getAttribute-instead-of-getAttributeNode
Use getAttribute instead of getAttributeNode in ReactID.rawGetID
2013-07-17 18:24:27 -07:00
Ben Newman
fd2125ee94 Use getAttribute instead of getAttributeNode in ReactID.rawGetID.
Also known as internalGetID, internally.
2013-07-17 21:14:04 -04:00
Paul O’Shannessy
52e622f1db Version bump for 0.5.0 development 2013-07-17 16:45:38 -07:00
Paul O’Shannessy
3d7ac69c39 Merge pull request #203 from spicyj/homepage
Fix all errors and warnings on homepage
2013-07-17 13:32:52 -07:00
Ben Alpert
e379f8ec03 Fix all errors and warnings on homepage
Also onChange instead of onInput in two places!
2013-07-17 13:31:52 -07:00
Paul O’Shannessy
dbdf1cc296 Merge branch 'chenglou-master'
Conflicts:
	docs/_js/examples/markdown.js
2013-07-17 13:30:22 -07:00
Cheng Lou
dd14fdfdc5 todo fix 2013-07-17 16:28:04 -04:00
Cheng Lou
fc6a567e0e jsx 2013-07-17 16:25:25 -04:00
Paul O’Shannessy
96bd63cc4b Fix typo in blogpost
I fixed this in the changelog, but missed this one.
2013-07-17 13:23:18 -07:00
Cheng Lou
169b172ffc textarea format 2013-07-17 16:22:30 -04:00
Paul O’Shannessy
ec67076090 Update readme for 0.4.0 2013-07-17 11:52:29 -07:00
Paul O’Shannessy
9221b15bff Typo in changelog, update blog leading sentence. 2013-07-17 11:51:27 -07:00
Paul O’Shannessy
a54333842f Bump version for v0.4.0 2013-07-17 11:33:31 -07:00
Paul O’Shannessy
0c1f2720b3 Remove React.autoBind from examples 2013-07-17 11:33:31 -07:00
Paul O’Shannessy
75f7f1e9ba remove likebutton from docs for now
it has some facebook-ism in there and it's probably shouldn't be on the
site.
2013-07-17 11:21:33 -07:00
Paul O’Shannessy
09fbf8e0ca Blog post for 0.4 2013-07-17 11:20:21 -07:00
Paul O’Shannessy
d17d0d5f50 Changelog for 0.4.0 2013-07-17 11:19:58 -07:00
Paul O’Shannessy
1a7a8486ca [docs] Make sure JSX comments code is in block 2013-07-17 11:18:17 -07:00
Paul O’Shannessy
65548db916 Re-order entries in changelog
React is more important than react-tools so put it first!
2013-07-17 10:04:27 -07:00
Paul O’Shannessy
894bb03b23 Add CHANGELOG at the root, remove from downloads page 2013-07-17 10:01:16 -07:00
Paul O’Shannessy
94573545f3 [docs] Prop validation + cleanup default props 2013-07-17 09:47:09 -07:00
Paul O’Shannessy
7734429b89 [docs] Remove @benjamn's TODO for testing 2013-07-17 09:12:26 -07:00
Paul O’Shannessy
35f092afef Write Default Props section 2013-07-17 09:12:02 -07:00
Paul O’Shannessy
b837bb7bdd [docs] fix typo
"L" is not ":"
2013-07-17 08:45:27 -07:00
Paul O’Shannessy
c629a0c5ad Revert "Merge pull request #200 from spicyj/version"
This reverts commit d889322827, reversing
changes made to 156dffb961.
2013-07-17 08:26:59 -07:00
Ben Newman
d889322827 Merge pull request #200 from spicyj/version
Add React.version
2013-07-17 06:13:49 -07:00
Paul O’Shannessy
156dffb961 [docs] Fix broken links 2013-07-17 01:37:52 -07:00
Pete Hunt
e5befc0a73 Update DOM differences docs to include a note about the style attribute. 2013-07-17 01:00:01 -07:00
Paul O’Shannessy
e3f6a6d916 Merge pull request #188 from facebook/docs-refactor
Look ma, new docs!
2013-07-17 00:56:07 -07:00
Paul O’Shannessy
58fecc8cbe Merge branch 'master' into docs-refactor 2013-07-17 00:26:05 -07:00
Paul O’Shannessy
b5aad9479e re-bold some text so it stands out better 2013-07-17 00:25:23 -07:00
Paul O’Shannessy
5db3a0e481 Remove React.autoBind from examples 2013-07-16 23:44:09 -07:00
Paul O’Shannessy
0300f2aa22 em dashes 2013-07-16 23:38:15 -07:00
Paul O’Shannessy
17d36a4cc3 Standardized Markdown lists 2013-07-16 23:35:54 -07:00
Paul O’Shannessy
c222f57b00 Cleanup "Reference"
(unlinked likebutton tutorial - not updated enough for public)
2013-07-16 23:31:32 -07:00
Paul O’Shannessy
1b64508aab Cleanup "Tooling Integration" 2013-07-16 23:31:03 -07:00
Paul O’Shannessy
f2b92d4c7b Cleanup "More About Refs" 2013-07-16 23:30:41 -07:00
Paul O’Shannessy
82f82c7543 Cleanup "Working With the Browser" 2013-07-16 23:30:18 -07:00
Paul O’Shannessy
602623661a Cleanup "Forms" 2013-07-16 23:29:39 -07:00
Paul O’Shannessy
ca3564898d Cleanup "Reusable Components" 2013-07-16 23:29:14 -07:00
Paul O’Shannessy
5b662b43a0 Cleanup "Multiple Components" 2013-07-16 23:28:51 -07:00
Paul O’Shannessy
6ba6fc149a Cleanup "Interactivity and Dynamic UIs" 2013-07-16 23:28:25 -07:00
Paul O’Shannessy
5a3a39aba4 Cleanup "JSX Gotchas" 2013-07-16 23:27:36 -07:00
Paul O’Shannessy
b9b300fcbd Cleanup "JSX in Depth" 2013-07-16 23:24:56 -07:00
Paul O’Shannessy
59f52bce04 Cleanup "Displaying Data" 2013-07-16 23:24:22 -07:00
Paul O’Shannessy
8d3465060d Merge remote-tracking branch 'upstream/docs-refactor' into HEAD 2013-07-16 23:23:32 -07:00
Paul O’Shannessy
d0af08190e Merge pull request #199 from chenglou/patch-1
Tweaked the intro page
2013-07-16 23:01:45 -07:00
Cheng Lou
b343fcaba3 grammar error 2013-07-17 00:15:49 -04:00
Cheng Lou
526099c928 changing back to 'give it five minutes', tweak that sentence 2013-07-17 00:12:21 -04:00
Paul O’Shannessy
f0984cf789 Don't hard code React version anywhere 2013-07-16 21:08:10 -07:00
Ben Alpert
7be14d8155 Add React.version
getConfig needs to be a function because grunt.config.data.pkg.version isn't available at the time that grunt/config/jsx/jsx.js is required.

Test Plan:
grunt build, grunt lint, grunt test all work. After building, both react.js and react.min.js contain the version number.
2013-07-16 20:38:40 -07:00
Cheng Lou
28f6f034ff Tweaked the intro page
Here are some ideas that I think work better:
- 15 repetitions of "React". Removed a few.
- The "two main ideas" weren't clearly separated. I put them under different headers and simplified the wording.
- The "Give it Five Minutes section didn't sound as reassuring. Made it sound more certain.
2013-07-16 21:39:20 -04:00
Paul O’Shannessy
3be6083ea4 Autogen the docs nav
This is still the same amount of duplication, except way easier to
parse. Docs nav now lives in `_config.yml` and you must restart jekyll
to see changes to that list (since config is only read at jekyll launch)
2013-07-16 17:24:41 -07:00
Paul O’Shannessy
f367d0e707 Remove numbers from URLs.
This will let us keep docs in order on the filesystem but have
reasonable permalinks. If we add something at 02- it doesn't result in
lots of broken links.
2013-07-16 17:09:43 -07:00
Paul O’Shannessy
9694a0f7ea Fix title casing and heading levels 2013-07-16 14:52:57 -07:00
Paul O’Shannessy
04bfa545f7 Remove "Scaling Up" 2013-07-16 13:55:42 -07:00
Ben Newman
1971ae8cac Merge pull request #196 from zpao/fix-test-warnings
Fix tests to silence some warnings due to autobinding
2013-07-16 13:15:35 -07:00
Paul O’Shannessy
fd3d16d379 Fix tests to silence some warnings due to autobinding 2013-07-16 13:08:46 -07:00
Paul O’Shannessy
dfd406fe4c Merge pull request #195 from benjamn/force-upgrade-graceful-fs
Upgrade Commoner and Populist to force upgrade to graceful-fs v2.0.0
2013-07-16 12:53:46 -07:00
Ben Newman
301c571405 Upgrade Commoner and Populist to force upgrade to graceful-fs v2.0.0.
A silent upgrade from graceful-fs v1.2.2 to v1.2.3 (a dependency for both
Commoner and Populist) broke the build process, even though tests were
still passing. The 2.0.0 version fixes whatever was broken, though I won't
pretend to know exactly what the root cause was.
2013-07-16 15:42:17 -04:00
Paul O’Shannessy
3376d27915 Merge pull request #194 from benjamn/build-jasmine-bundle-with-populist
Use populist for building jasmine test harness bundle
2013-07-16 11:51:22 -07:00
Ben Newman
0827646695 Use populist for building jasmine test harness package.
We're using populist for building the bundle of test modules and their
dependencies, so it seems worthwhile for consistency to do the same for
the test harness.
2013-07-16 14:48:31 -04:00
Ben Newman
03578e66b5 Fix rootElementsByReactRootID bookkeeping in ReactMount.js.
It's not always possible to update `rootElementsByReactRootID` when the
contents of the container are re-rendered; for instance, when we call
`dangerouslyReplaceNodeWithMarkup` or `dangerouslySetInnerHTML`. Since
this bookkeeping is just trying to warn about potentially problematic
manipulations of the root element, and we can be relatively sure that a
new element with the same ID is logically the same element, this diff
avoids warning in such cases.
2013-07-16 11:43:43 -07:00
Jan Kassens
71e24455a3 add missing argument to invariant in ReactDOMSelect 2013-07-16 11:38:35 -07:00
Tim Yung
83a840656c Fix Markup Rendering in IE
This fixes known browser bugs with rendering markup using `innerHTML` in IE ([[http://support.microsoft.com/kb/276228 | here is an example of one]]).

This is a subset of what `HTML` (and jQuery) does, and we should eventually consider pulling it out into a separate module to reduce code duplication. For now, this is the minimal set of changes needed to unbreak React in production.

We can afford to use a subset of what `HTML` does because we have the luxury of knowing that the markup is generated sanely with proper closing tags, etc.
2013-07-16 11:37:26 -07:00
Tim Yung
ed54fff204 Controlled <select> and <option> Components
This implements a `<select>` component that supports `value` and `defaultValue`. It also changes `<option>` to warn when the `selected` prop is supplied.
2013-07-16 11:37:04 -07:00
Jordan Walke
5d4f903482 [React Children] Step Three: New test case for traverseChildren.
If we're going to build utilities off of this, we should have good test
coverage.
2013-07-16 11:36:53 -07:00
Jordan Walke
946029c921 [React Children] Step Two: Use traverseChildren to perform mapChildren
Use the new `traverseChildren` utility to perform `mapChildren`.
The goal is to get as close to the bavior of the semantics of
`Array.prototype.map`, but also in a way that understands deeply nested arrays
and objects.
2013-07-16 11:36:11 -07:00
Jordan Walke
f4321f8624 [React Children] Step One: Refactor flattenChildren
Refactoring `flattenChildren` so that the traversal code is reusable
for other purposes.
2013-07-16 11:35:43 -07:00
Paul O’Shannessy
46d05b1191 Sync vendor modules from FB.
Biggest win here is that we'll strip out the console.error from
EventListener and we won't need to suggest people use a console
polyfill with the minified build.
2013-07-15 21:04:43 -07:00
Ben Newman
558e8ca312 Merge pull request #193 from benjamn/use-populist-for-testing
Fix tests
2013-07-15 16:42:57 -07:00
Ben Newman
b763d7d029 Use a separate grunt/config/jsx config file for tests.
No longer injecting __MOCK__ as a global constant (it's just a config
property now).

Turns out the `grunt jsx:debug` task was never necessary for tests.
2013-07-15 19:41:40 -04:00
Ben Newman
2d61639f90 Store dirtyMocks array globally so it can survive dumpCache().
When require("mock-modules").dumpCache() is called, all mock functions
previously created continue to refer to the old dirtyMocks array.

If we replace that array with a new one, those mock functions will never
have their .mockClear() methods called again.

The upstream version of mocks.js pulls a similar global trick, and I never
understood why until now.
2013-07-15 19:41:40 -04:00
Ben Newman
204796868d Enable module.exports mocking in react-test.js.
We don't currently attempt to mock modules automatically, but we do
respect require("mock-modules").mock, .dontMock, and .dumpCache.

I'm going to keep investigating auto-mocking, since that would move us
much closer to the behavior used within Facebook.

Closes #154.
Closes #155.
2013-07-15 19:41:40 -04:00
Ben Newman
37014e1002 Call require("mock-modules").register in every mockable module.
Mocking happens only when config.constants.__MOCK__ is true.
2013-07-15 18:10:49 -04:00
Ben Newman
c6c4657f83 Use populist v0.1.2 to bundle test modules instead of browserify.
This will allow full support for mocking, dumpCache, and correct line
numbers in error messages.
2013-07-15 18:10:49 -04:00
Ben Newman
f457394362 Remove remaining calls to ReactCompositeComponent.autoBind.
This is causing console.warning spew in the open source tests.
2013-07-15 15:09:01 -07:00
Tim Yung
2b97c608f8 Normalize DefaultDOMPropertyConfig
For consistency, use lowerCamelCase for all props in `DefaultDOMPropertyConfig`.
2013-07-15 15:08:46 -07:00
Paul O’Shannessy
15493530f1 Revert "Update LICENSE"
This reverts commit dd1d49b360.

The license is actually supposed to look like that. That section is
boilerplate for others to apply the license to their own work. See
immediately above...

> To apply the Apache License to your work, attach the following
> boilerplate notice, with the fields enclosed by brackets "[]"
> replaced with your own identifying information. (Don't include
> the brackets!)
2013-07-15 10:40:27 -07:00
Pete Hunt
dd1d49b360 Update LICENSE 2013-07-15 00:28:36 -07:00
petehunt
e9e8934577 fix markup bugs 2013-07-14 18:46:50 -07:00
petehunt
2397e35cdd switch to guides 2013-07-14 18:43:33 -07:00
petehunt
0e585d8102 put it all together 2013-07-14 18:42:39 -07:00
petehunt
6009934176 cleanup some files, move tutorial 2013-07-14 18:35:59 -07:00
petehunt
b20c2641d4 move docs around, add likebutton 2013-07-14 18:31:46 -07:00
petehunt
445a0dac37 tweak the source 2013-07-14 18:25:51 -07:00
petehunt
33abe80b59 scaling up fix 2013-07-14 18:00:17 -07:00
petehunt
d7cf1c509b delete old docs 2013-07-14 17:57:39 -07:00
petehunt
7d97f26870 add more examples 2013-07-14 17:52:25 -07:00
petehunt
b2107ba80b update and move tutorial 2013-07-14 17:49:07 -07:00
petehunt
d0c431a2a3 Fix comma 2013-07-14 17:15:28 -07:00
Pete Hunt
ab7ef4ed3b Update 08-working-with-your-environment.md 2013-07-14 17:07:58 -07:00
petehunt
204edb4a27 fix some links 2013-07-14 17:07:57 -07:00
Pete Hunt
3c742d50b6 Update 03-interactivity-and-dynamic-uis.md 2013-07-14 17:07:57 -07:00
Pete Hunt
1c51cc34cd Update 02.1-jsx-in-depth.md 2013-07-14 17:07:57 -07:00
Pete Hunt
64b9b55a0d Update 02.2-jsx-gotchas.md 2013-07-14 17:07:57 -07:00
Pete Hunt
f9741b0728 Update 01-motivation.md 2013-07-14 17:07:57 -07:00
petehunt
3085254a91 reorg 2013-07-14 17:07:57 -07:00
petehunt
0de35588c1 jsx gotchas, reference 2013-07-14 17:07:57 -07:00
petehunt
21ea1ac61e add working with your environment section 2013-07-14 17:07:57 -07:00
petehunt
4fccaa514b @vjeux comments 2013-07-14 17:07:57 -07:00
petehunt
13ad0c500b antipatterns 2013-07-14 17:07:57 -07:00
petehunt
126a7f5c11 more jsx handholding 2013-07-14 17:07:57 -07:00
petehunt
bb3bd76fe9 Reorg docs, write a lot of content, import a lot of stuff from dex 2013-07-14 17:07:57 -07:00
petehunt
4bbdcdb0b8 another comment 2013-07-14 17:07:57 -07:00
petehunt
d294a7f30f more scaling up 2013-07-14 17:07:57 -07:00
petehunt
de8d0e35a2 more state machiens 2013-07-14 17:07:57 -07:00
petehunt
faa84b5b85 further improvements 2013-07-14 17:07:57 -07:00
petehunt
e1e5f17b27 link to blog 2013-07-14 17:07:57 -07:00
petehunt
0e63000b5c even better toc 2013-07-14 17:07:57 -07:00
petehunt
151997b1e1 Start on section 04 2013-07-14 17:07:57 -07:00
petehunt
a36bcd33c6 more toc 2013-07-14 17:07:57 -07:00
petehunt
9194fea915 Add table of contents info 2013-07-14 17:07:57 -07:00
petehunt
67d9891926 add seconds 02.1 and 03 2013-07-14 17:07:56 -07:00
petehunt
05341fb3b3 Add more jsx docs rather than linking 2013-07-14 17:07:56 -07:00
petehunt
c82afd7e54 Some style changes 2013-07-14 17:07:56 -07:00
petehunt
ed98f2ca57 Make less facebooky 2013-07-14 17:07:56 -07:00
petehunt
462e450bb3 First two sections of newdocs 2013-07-14 17:07:56 -07:00
Paul O'Shannessy
06e5fcc010 "use strict" for ReactDoNotBindDeprecated 2013-07-12 15:42:46 -07:00
Paul O'Shannessy
ac84652e50 Cleanup console.* uses
* Stop doing `global.console && ...`
* Make sure all uses are behind `__DEV__` checks so they get stripped out
2013-07-12 15:42:25 -07:00
Tim Yung
eee3980749 Stringify value in ReactDOMInput / ChangeEventPlugin
This fixes two bugs related to string-casting in React:

 # Setting `<input value={0} />` would use an empty `value` because `0` is falsey.
 # Using `onChange` and `setState` with non-strings could lead to an infinite loop.

The latter is possible with controlled inputs when:

 - User changes input value.
 - `onpropertychange` fires.
 - `ChangeEventPlugin` dispatches `onChange`.
 - A handler responds via `this.setState` with a non-string value (e.g. a number).
 - The input re-renders and re-sets `value`.
 - The new `value` is not a string, but the current `value` (read from the element) is cast to a string automatically by the browser.
 - This triggers another `onpropertychange`.
 - `ChangeEventPlugin` dispatches another `onChange`.
 - ...
2013-07-12 15:40:55 -07:00
Paul O'Shannessy
cf83fbe397 Remove references to React.autoBind
Cleaned up a comment and removed a useless test.
2013-07-11 23:07:01 -07:00
Paul O’Shannessy
e221ff7cd4 Add exports to globals for jshint
This is a bit unfortunate, but it'll shut lint up for the time being. We
can't just change the modules to use `module.exports = { ... }` due to
how we handle circular dependencies internally (`ReactMount` require
`ReactID` and vice versa).
2013-07-11 17:20:21 -07:00
Paul O’Shannessy
607de16d82 New blog post: Props in v0.4 2013-07-11 15:52:29 -07:00
Paul O'Shannessy
d762627312 Rename props to propTypes
This does two things:

 - Rename `props` to `propTypes`.
 - Rename `ReactProps` to `ReactPropTypes` (and `React.Props` to `React.PropTypes`)
2013-07-10 15:06:18 -07:00
Tim Yung
10dab495f2 Stop Unnecessary Purging of Node Cache
When each component unmounts, it already cleans up its respective entry in the node cache. Let's stop blowing away the entire node cache unnecessarily.

This should improve performance because a React component's root will never need to be searched for more than once.
2013-07-10 15:05:18 -07:00
Tim Yung
ee1335b6a2 Delete setTextNodeValueAtIndexByParentID
This does not appear to be used anywhere.
2013-07-10 15:05:06 -07:00
Tim Yung
8687645c50 Reduce Lookup for Missing Lifecycle Methods
This is a micro-optimization that reduces the lookup time for missing lifecycle methods. The extra amount of memory is linear to the number of components that exist on a page which I think is a worthwile trade-off.
2013-07-10 15:04:44 -07:00
Tim Yung
7b68fcd408 Short-circuit updatePropertyByID
When `ReactNativeComponent` updates, it calls `updatePropertyByID` in `ReactDOMIDOperations` which calls `DOMPropertyOperations`. However, in `ReactDOMIDOperations`, we will lookup the node for an ID using `ReactID.getNode`. This wastes time looking for nodes when we may not need to ever update it (e.g. `children`).

This changes `ReactNativeComponent` to bail out sooner.
2013-07-10 15:04:23 -07:00
Pete Hunt
92dab0759c More autobind warnings and invariants
This adds two new warnings and one new invariant:

- Warn when using React.autoBind() that it is deprecated.
- Throw when calling bind() on an autobound method with the wrong value of "this". Today we'll silently ignore the provided value, which is confusing.
- Warn when calling bind() on an autobound method with the *right* value of "this" and no other arguments. This is already done for you by React.
2013-07-10 15:03:50 -07:00
Ben Newman
5c6e59f53c Don't ignore children of non-ancestor ID nodes in findComponentRoot. 2013-07-10 14:58:57 -07:00
Tim Yung
067fe27699 Fix Clowny Validation Code
ಠ_ಠ
2013-07-10 14:58:47 -07:00
Paul O’Shannessy
8db2ba9130 Upgrade other dependencies
Nothing groundbreaking. `semver` was likely already installed at 2.0.x
anyway (since >=) and `grunt-contrib-jshint` just gives us `jshint`
@ 2.1.3
2013-07-09 10:55:56 -07:00
Paul O’Shannessy
1500e9810c Upgrade browserify.
There are other changes I'm sure but the most important is that module
sorting results in deterministic builds.

The biggest win here comes for releases. Previously we had to jump
through hoops to make sure the files we put in bower were the same files
we put on the CDN, were the same files packaged in the Ruby gem, were
the same files we packaged into a zip file, were the same file we used
when create PRs to CDNJS. Rebuilding docs also resulted in conflicting
versions so we had to be careful when committing. This takes away all of
that pain. We can build from the same revision and get the same files.
2013-07-09 09:20:57 -07:00
Paul O’Shannessy
a3b21b10e4 Merge pull request #178 from paulshen/master
Add __benchmarks__ to .gitignore
2013-07-08 18:27:39 -07:00
Paul Shen
fa03e98426 Add __benchmarks__ to .gitignore 2013-07-08 16:40:21 -07:00
Paul O'Shannessy
203dba271b Add some missing attributes
Mostly this was to better support some HTML5 stuff. This was not a complete pass through though, and we should probably add more.
2013-07-08 13:58:42 -07:00
Paul O’Shannessy
91562ba934 Sync JSX tags from upstream
This is the other part of fc5f7e0e85. This
file isn't part of our sync process so needs to be done separately.
2013-07-08 12:51:11 -07:00
Paul O'Shannessy
fc5f7e0e85 Add support for missing html elements
We're missing a bunch of elements. So I scraped them from https://developer.mozilla.org/en-US/docs/Web/HTML/Element. Here's the script I used (run from Firefox scratchpad):

```
Array.prototype.slice.call(document.querySelectorAll('div.index.widgeted li'))
  .filter(function(li) {
    return !/deprecatedElement|obsoleteElement|nonStdElement/.test(li.firstChild.className)
  })
  .map(function(li) {
    // <tag> -> tag
    return li.querySelector('code').textContent.replace(/<(.+)>/,'$1');
  })
  .join(': false,\n  ');
```

I had to filter a couple more out (because there's some malformed content), but then it was simply merge with what we had and check to see if the new ones needed to omit the close tag.
2013-07-08 11:51:47 -07:00
Ben Newman
a4123a069e Continue over ID-less children in ReactMount.findComponentRoot.
This fixes our perf test by coping with edge cases like the
injection of `<tbody>` between `<table>` and `<tr>` nodes, which occurs
automatically in some browsers when we set `.innerHTML`.

Introducing more search branches would be risky if not for my previous
commit that made `findComponentRoot` breadth-first instead of depth-first.
2013-07-08 11:50:55 -07:00
Ben Newman
a5ddb07cb3 Make ReactMount.findComponentRoot breadth-first & non-recursive.
This function needs to be as fast as possible for those cases when
`ReactID.getNode` can't rely on the `nodeCache`.

Breadth-first search prevents us from diving too deeply down the wrong
branches when the sought-after node can be found at a shallower level.

The queue required for breadth-first search is implemented by a single
array indexed by `childIndex`. To save space, only the `.firstChild` nodes
are stored, and we use `.nextSibling` to iterate over the other siblings
in a `while` loop.
2013-07-08 11:50:34 -07:00
Ben Newman
917e101c2c Try harder to find container in ReactMount.findReactContainerForID.
When we render a new component into a container, we now record a reference to the rendered DOM node as `rootElementsByReactRootID[reactRootID]`, so that we can determine the actual container later on, in case `containersByReactRootID[reactRootID]` is no longer the true container.
2013-07-08 11:50:13 -07:00
Pete Hunt
5c624021ea Tweaks to make the Closure parser happy
This doesn't make it actually run with Closure, but passes its parser.
2013-07-08 11:50:02 -07:00
Pete Hunt
5676a486cf Allow nested ReactUpdates 2013-07-08 11:49:42 -07:00
Pete Hunt
1658feade8 Remove the check for console.warn
We already polyfill this at FB and we should recommend https://github.com/paulmillr/console-polyfill for open source.
2013-07-08 11:49:28 -07:00
Pete Hunt
5f1eceb1ee Merge pull request #176 from andreypopp/master
Add datetime to the list of known DOM attributes
2013-07-08 00:44:33 -07:00
Andrey Popp
fc3491e0d0 dateTime attr: camelCase and MUST_USE_ATTRIBUTE 2013-07-08 11:23:43 +04:00
Andrey Popp
9f94244994 add datetime to the list of known attributes
as per http://www.whatwg.org/specs/web-apps/current-work/multipage/text-level-semantics.html#attr-time-datetime
2013-07-08 00:09:38 +04:00
Pete Hunt
6ebdd0cfd2 Merge pull request #173 from chenglou/patch-4
Emphasis on single child.
2013-07-06 23:20:20 -07:00
Cheng Lou
858377946f Emphasis on single child. 2013-07-06 16:10:34 -04:00
Ben Newman
826d603b05 Merge pull request #167 from benjamn/issue-166-fix-phantomjs-executability
Ensure that the phantomjs binary has appropriate UNIX mode
2013-07-05 16:18:05 -07:00
Ben Newman
da4b761c45 Don't require tmp module unless we're going to use it. 2013-07-05 19:17:20 -04:00
Ben Newman
70a2f8046c Ensure that the phantomjs binary has appropriate UNIX mode.
The 755 mode corresponds to a UNIX mode string of -rwxr-xr-x.

Closes #166.
2013-07-05 19:06:49 -04:00
Christopher Chedeau
51bf95f6d1 Merge pull request #157 from vjeux/communit_4
Community Round-up #4
2013-07-03 18:32:36 -07:00
Vjeux
2246f530af Community Round-up #4 2013-07-04 03:25:35 +02:00
Paul O’Shannessy
4e04ef0769 Merge pull request #153 from lrowe/patch-2
Add `hidden` attribute to DOM properties.
2013-07-03 15:48:19 -07:00
Laurence Rowe
b2bbdf8cbf Add hidden attribute to DOM properties. 2013-07-03 14:05:44 -07:00
petehunt
9178208ba8 update docs 2013-07-03 13:09:10 -07:00
Pete Hunt
7d3db0e5ed Add finally block for clearing ReactUpdates state
If any component throws during reconciliation any subsequent reconciliation will break badly because ReactUpdates will be in an inconsistent state.
Add a finally block to prevent this.
2013-07-03 11:38:50 -07:00
Tim Yung
2869e5b4df Inject ReactDOMInput
Changes `<input>` in React to use `ReactDOMInput` which supports `value` and `defaultValue` instead of the current, arguably broken `value` behavior.
2013-07-03 11:38:45 -07:00
Tim Yung
510146eb6d Faster Listener Deletion
Whenever a component is unmounted, we delete all listeners that might have been attached. This sucks because most applications, Facebook included, do not use every listener. There's a lot of wasted computation, especially if many components are mounted and unmounted.

This changes `deleteAllListeners` to more delete listeners more efficiently.
2013-07-03 11:38:34 -07:00
Tim Yung
c692d9e844 Fix ChangeEventPlugin for IE8 and IE9
This fixes a bug with `ChangeEventPlugin` in IE8 and IE9. The extend of this bug includes:

 - On IE8, not firing `onChange` immediately after `value` of an input is changed.
 - On IE9, not firing `onChange` when backspacing.
2013-07-03 11:38:31 -07:00
Pete Hunt
32423a83fc Injectable DOMProperty configs, and add back ID attribute
https://github.com/facebook/react/pull/141
2013-07-02 18:30:04 -07:00
Sebastian Markbage
d50148591b Introduce a supported way to slice children
Introduces a counterpart to mapChildren. It excludes empty children just as
mapChildren for compatibility. With might introduce something like
sliceChildrenIncludingEmptyValues at some point.
2013-07-02 18:30:04 -07:00
Pete Hunt
b6451be582 Update syntax.md
Some inconsistencies pointed out in FB comments
2013-07-02 18:27:15 -07:00
Paul O’Shannessy
5e296d7af8 Merge pull request #150 from benjamn/commoner-dir-watcher
Upgrade Commoner to --watch directories instead of individual files
2013-07-02 17:21:39 -07:00
Pete Hunt
3093a476b1 Merge pull request #115 from spicyj/async-state
Batch together calls to setState, setProps, etc
2013-07-02 17:16:07 -07:00
Paul O’Shannessy
00e56c5155 Merge pull request #151 from spicyj/bq
Add blockquote tag (already in JSX)
2013-07-02 17:14:34 -07:00
Pete Hunt
8b9891aa8a Remove autobinding warning
I think this warns on many legitimate use cases. We should get rid of it I think.
2013-07-02 16:53:39 -07:00
Ben Alpert
f7901a2380 Add blockquote tag (already in JSX) 2013-07-02 16:19:41 -07:00
Ben Newman
5c4352b57b Upgrade Commoner to --watch directories instead of individual files.
This behavior is new in Commoner v0.8.3, following the incorporation of
@jeffreylin's `DirWatcher` implementation:
https://github.com/jeffreylin/jsx_transformer_fun/blob/master/dirWatcher.js

Watching directories instead of files reduces the total number of open
files, and copes better with editors that save files by deleting and then
immediately recreating them.

Closes #60.
Closes #71.
2013-07-02 17:47:52 -04:00
Paul O’Shannessy
9ca7c9631a Blog: Autobind by Default
Kicking off the series of posts previewing v0.4
2013-07-02 13:04:14 -07:00
Ben Alpert
d9e99d4688 Batch together calls to setState, setProps, etc
The end of ReactUpdates-test.js is probably most illuminating for seeing how this works.
2013-07-02 00:04:50 -07:00
Pete Hunt
3fd56b4038 Merge pull request #147 from lrowe/patch-1
Add figure and figcaption elements to React.DOM (already supported by jsx)
2013-07-01 17:51:42 -07:00
Laurence Rowe
44659df598 Add figure and figcaption elements to React.DOM (already supported by jsx.) 2013-07-01 17:03:54 -07:00
Ben Alpert
0e9ee239a9 Merge branch 'master' into async-state 2013-07-01 16:08:57 -07:00
Paul O’Shannessy
ce0704a491 Merge pull request #145 from benjamn/no-jsx-dependency-scanning-by-default
Bump Commoner version to disable dependency scanning by default
2013-07-01 13:57:12 -07:00
Paul O’Shannessy
0acc1d8c78 Merge pull request #144 from benjamn/fix-EMFILE-jsx-errors
Bump Commoner version to fix EMFILE errors
2013-07-01 13:54:09 -07:00
Ben Newman
18ef8962f1 Bump Commoner version to disable dependency scanning by default.
If you are using bin/jsx independently, you may need to pass
--follow-requires to it if you rely on its dependency scanning.

Dependency scanning is still a good idea, but it's difficult to make it
work perfectly for everyone the first time they try bin/jsx.

Closes #131.
2013-07-01 16:50:35 -04:00
Ben Newman
e748be32da Bump Commoner version to fix EMFILE errors.
Finally found a more robust solution for the "too many open files"
problem: https://github.com/benjamn/commoner/commit/ad72ba42db.

Closes #137.
Closes #138.
2013-07-01 16:31:56 -04:00
Paul O’Shannessy
0ad14fc038 Merge pull request #143 from spicyj/ie8-fixes-2
Use proper names for scroll metric properties
2013-07-01 13:12:14 -07:00
CommitSyncScript
dd61439061 Revert Flattening of Children
I still think the semantics of flattening children is valid but we'll
want to revert the flattening implementation while we solidify the
semantics and try another approach.

This reverts flattening so that this.props.children can once again be
either a single child, flat array or nested array.

mapChildren calls flattenChildren before doing anything else. This is
not the most efficient approach but I wanted to keep this inital diff
simple. It also ignores empty values for backwards compatibility.

We may want to try another approach where empty values are included
in the map.

Validation of keys is still done inside ReactComponent. Ideally I'd
like to extract that into a separate module but to avoid cyclic
dependencies, I'm keeping it in ReactComponent for now.
2013-07-01 13:01:52 -07:00
CommitSyncScript
40bebf0c86 Fix ReactDOMInput and ReactDOMTextarea Race Condition
This fixes a race condition if the `onClick` tries to update the input or textarea (e.g. by calling `setState`):

  <input
    onClick={function(event) {
      this.setState({somethingElse: true}); // Triggers an update.
      // event.target.value is now equal to the old value, fail...
      this.props.onChange(event);
    })
  />
2013-07-01 13:00:41 -07:00
Ben Alpert
2aa5631e2e Use proper names for scroll metric properties 2013-07-01 11:54:13 -07:00
Paul O’Shannessy
f39a0f8e40 Merge branch 'no-content' of git://github.com/spicyj/react into spicyj-no-content
Conflicts:
	src/core/ReactNativeComponent.js
2013-06-28 16:42:59 -07:00
CommitSyncScript
ca19ffb083 use .apply instead of .call in ReactCompositeComponent
This was a bit ridiculous.. let's just use arguments as it's supposed to
be used.
2013-06-28 16:36:54 -07:00
CommitSyncScript
15272f30f4 Don't keep the HTML escaped ID internally, only in HTML generation
A dynamic value can be provided as a key to a child. Either as part of an object
or key property. This becomes part of the component's ID.

We have to be careful to escape this key before inserting it into the DOM since
it could become a vulnerability. We fixed this by escaping just the keys.

However, the current implementation breaks when you used escaped keys. The
internal value is escaped and the value used by getAttributeNode and
getElementById are both unescaped.

This fixes that by keeping the unescaped value internally but escaping it right
before the HTML is generated (like any other attribute).

This is important since business logic IDs (that should be used as keys)
contains characters that need to be escaped.
2013-06-28 16:35:45 -07:00
CommitSyncScript
55176116a2 Implement ReactDOMTextarea
This changes `ReactDOMTextarea` to accept `defaultValue` and `value`. It will warn people about using children (but allow it and treat it as `defaultValue`, which is the current behavior).
2013-06-28 16:35:04 -07:00
CommitSyncScript
738de8cfa8 Improve findComponentRoot Error Message
Instead of simply logging the React ID of the `ancestorNode` when `findComponentRoot` fails, use a `try ... finally` to `console.error` the `ancestorNode`. This allows modern web inspectors to actually log a reference to the node (which may not have a React ID).

This means when people run into the problem, they will not have to execute:

  require('ReactID').getNode(<copy+paste>);

NOTE: Admittedly, this will not log anything in IE8. That's fine, since IE8 has shitty console logging anyway.
2013-06-28 16:34:27 -07:00
Paul O’Shannessy
bd150ec658 Clean up unused variables for lint 2013-06-28 16:34:19 -07:00
Paul O’Shannessy
ee21a604f3 Delete files that accidentally got merged in
ಠ_ಠ
2013-06-28 14:54:07 -07:00
yungsters
43358157cf Merge branch 'textarea-update-value' of git://github.com/spicyj/react
Conflicts:
	src/core/ReactDefaultInjection.js
2013-06-28 14:30:47 -07:00
Paul O’Shannessy
0b65d7555e Merge pull request #136 from jeffmo/empty_expressions
Add support for empty XJS expressions
2013-06-28 14:16:23 -07:00
CommitSyncScript
8bc2abd367 .reactRoot[base10] -> .r[base36]
Just a bit of byte savings for server rendering. Props to @benjamn for the base36 idea (and for making this diff easy).

With a little work we could probably get rid of the .r as well.
2013-06-28 13:48:08 -07:00
CommitSyncScript
6556881417 Throw on Missing Elements
This changes React to throw when `ReactID.getNode()` fails to find a node. This method is used by two call sites:

 - Implements `ReactComponent#getDOMNode`. This method already throws if a component is not mounted, and //all mounted components should be able to find their rendered root nodes//.
 - Used by `ReactDOMIDOperations`. These call sites aleady assume that `getNode` returns a non-null. Currently, if the node is not found, this is the site that fatals (and the stack trace is much harder to debug).

The error message should make it //a lot// easier to debug unexpected DOM trees. In particular, this will help track down all the places where the browser inserts `<tbody>` unexpectedly.
2013-06-28 13:47:31 -07:00
CommitSyncScript
c54900f63e Fix Composition Level of Components w/o Owners
This fixes a bug with components constructed with no owners, for example:

  // Both the <div> and <span> have no owners.
  React.renderComponent(<div><span /></div>, node);

They should have a composition level of 1 and their keys should be prefixed with 0 to indicate they were created without owners. However, they currently incorrectly get a composition level of 0 (which means that //their// children will have keys prefixed with 0, which is wrong).
2013-06-28 13:47:05 -07:00
JeffMo
9c35189ad1 Add support for empty XJS expressions 2013-06-28 13:10:20 -07:00
Ben Alpert
e998041229 Remove content property
Fixes #119.
2013-06-28 11:14:59 -07:00
Christopher Chedeau
431e1d5608 Merge pull request #135 from vjeux/bugbuster
Add link roundup
2013-06-28 09:36:45 -07:00
Vjeux
d4c7991aee Add link roundup 2013-06-28 18:35:52 +02:00
Christopher Chedeau
811df48756 Merge pull request #123 from vjeux/patch-2
Add @jsx common parser issues in the docs
2013-06-27 17:17:59 -07:00
CommitSyncScript
dbd9d99bcd Fix findComponentRoot w/ Unidentified Nodes
The current `ReactInstanceHandles` has a bug where `findComponentRoot` barfs if it comes across a node that was not identified by React (via `ReactID`). This fixes that.

This was always a bug, but it became more apparent once we switched to `data-reactid` because arbitrary `document.createElement`'d nodes are much more likely to have an `id` than they are to have a `data-reactid`.
2013-06-27 16:44:08 -07:00
Paul O’Shannessy
c032743b93 Bump version to 0.4.0a
This should have happened a while ago, but better late than never.
2013-06-27 13:30:09 -07:00
Christopher Chedeau
418c1fc427 Add @jsx common parser issues in the docs
Update getting-started.md
2013-06-27 22:27:54 +02:00
petehunt
fe30279ed0 Merge pull request #126 from vjeux/community_3
Community Roundup #3
2013-06-27 13:19:48 -07:00
Vjeux
b4f096364f Community Roundup #3 2013-06-27 22:18:26 +02:00
Paul O’Shannessy
9e6a581f68 Merge pull request #132 from petehunt/engines
Recommend Node v0.10.0 due to https://github.com/isaacs/npm/issues/2907
2013-06-27 13:14:28 -07:00
petehunt
f7e49f3b25 Recommend Node v0.10.0 due to https://github.com/isaacs/npm/issues/2907 2013-06-27 13:09:29 -07:00
Paul O’Shannessy
2fd5efd92b Merge pull request #128 from mathieumg/master
Double quotes for strings in JSON data
2013-06-26 15:52:44 -07:00
CommitSyncScript
67cf44e7c1 Change ReactID.ATTR_NAME to "data-reactid"
This final change is what we've all been waiting for.

Note that it no longer makes sense to use `document.getElementById` in
`getNode`, because that only ever worked with "id" attributes.
2013-06-26 14:31:50 -07:00
CommitSyncScript
9ceaff7318 Refactor of ChangeEventPlugin
some refactoring and also handle if `blur` doesn't fire on the form
input in IE8 (by always cleaning up on focus). per discussions with
@balpert
2013-06-26 14:31:33 -07:00
Mathieu M-Gosselin
703c825196 Changed JSON data in the tutorial to use double quotes for strings. 2013-06-26 16:24:51 -04:00
Ben Newman
86adcd6766 Merge pull request #124 from zpao/keep-compare-size-cache
The compare_size cache gets wiped out with `grunt clean`
2013-06-26 11:57:03 -07:00
CommitSyncScript
5a85c5e535 Don't pass a null context to Function.prototype.call.
This prevents PhantomJS tests from hanging in the open-source React repo.

Until the advent of `"use strict"`, passing `null` as the context object
to `.call` or `.apply` resulted in `this` taking on the value of the
global object inside the invoked function.

Technically the `"use strict"` directive is supposed to make it possible
that `this === null`, but strict mode is not respected by all browsers,
including (unfortunately) PhantomJS.

Since these `expect`-ations are just testing binding behavior, let's not
make them also test strict mode `this` handling.
2013-06-26 11:23:25 -07:00
CommitSyncScript
cf926338bf Fix onChange for File Input
Makes sure that `onChange` fires for file inputs.
2013-06-26 11:23:13 -07:00
CommitSyncScript
43930455de Cache Default Props
The `getDefaultProps` return value should not be dependent on any external data (including `this.props` and `this.state`), so the return value should be consistent everytime we call it.

This caches the return value so we do not do work and allocate memory unnecessarily.
2013-06-26 11:22:39 -07:00
Paul O’Shannessy
6f04bd9410 Merge pull request #112 from spicyj/check-dom-nodetype
Check that `container` is a valid DOM element
2013-06-25 14:22:21 -07:00
CommitSyncScript
59212a538e Remove deleted files again
These accidentally got re-added in a rebase
2013-06-25 14:15:35 -07:00
CommitSyncScript
a9b024330c Make @typechecks static-only 2013-06-25 14:01:15 -07:00
CommitSyncScript
d93761af62 Enforce nodeCache validity
A node is considered valid if it

  1. has the expected ID (more of a sanity check than something that is
     ever likely to go wrong), and

  2. is contained by a currently mounted container.

When these requirements are met, we can be confident that
`ReactMount.findReactRenderedDOMNodeSlow(node.id) === node`, which is
important for cache consistency because `findReactRenderedDOMNodeSlow` is
what we fall back to when we don't find a node in the cache.

Point 2 is a subtle requirement, because it allows nodes to be valid even
if they are not currently contained by a document. Rendering into a
detached node is okay, in other words (which is something that
`document.getElementById` never properly accounted for).

Containment testing takes linear time in the depth of the DOM, which
sounds unfortunate until you realize that virtually all browsers support a
native `ancestor.contains(descendant)` method, and in practice the vast
majority of nodes are either orphaned with `.parentNode === null` or not
very deep relative to their container.
2013-06-25 14:00:31 -07:00
CommitSyncScript
fb6381fb35 Upgrade TextChangeEventPlugin to ChangeEventPlugin and support more form elements
Upgrade `TextChangeEventPlugin` to be the `onChange` event that React
fires. In React, `onChange` will now fire when `input` fires for form elements in
modern browsers.

Handle this for:

  input[type=text]
  input[type=password]
  input[type=checkbox]
  input[type=radio]
  textarea
  select

Support:

- OSX Chrome
- OSX Safari
- OSX Firefox
- Win 7 / IE8
- Win 7 / IE9
- Win 7 / IE10

Everything works but caret selection / placement differs from browser to
browser.

For <select> elements, the event is fired with `change`. This is a
conscious decision, even though in some browsers (OSX firefox, IE), it
can be argued that the event should fire more due to how the UI looks.

Builds on https://github.com/facebook/react/pull/75, which handled only
text inputs.
2013-06-25 13:58:59 -07:00
CommitSyncScript
1d65f81b16 Remove ReactDOMNodeCache and getDOMNodeID.
These modules have been superseded by `ReactID`. Since they were only used
internally, and I have updated all client code that previously assumed
their existence, I believe they can be dropped for good.
2013-06-25 13:58:43 -07:00
CommitSyncScript
1c40dde782 Remove ReactID.primeTree in favor of priming in ReactID.getID.
Although it would have been nice to prime the entire tree and achieve a
cache hit rate of 100%, that cost would have to be paid up front, during
page rendering.

This patch avoids priming up front in favor of making the most of the work
done by `ReactMount.findReactRenderedDOMNodeSlow`, which calls
`ReactID.getID` while traversing the rendered DOM. The insight is this: if
`getID` simply primes the cache whenever it finds a new ID, then
`findReactRenderedDOMNodeSlow` will end up priming quite a few more nodes
that are actually involved in `ReactID.getNode` lookups, and we won't need
`primeTree` at all.
2013-06-25 13:57:54 -07:00
Ben Alpert
f6c4d2d161 Check that container is a valid DOM element 2013-06-25 10:54:28 -07:00
Paul O’Shannessy
b282a0f4f1 The compare_size cache gets wiped out with grunt clean
`.grunt/` is the directory that is suggested for storing task related
files, and this file is not useful if it gets wiped out often. So I'm
moving the compare_size cache into `.grunt/` so we keep it around
longer.
2013-06-24 21:35:00 -07:00
CommitSyncScript
c1886c6513 Use ReactID.ATTR_NAME as the React-specific ID attribute name.
Another step in the plan towards making `ReactID.ATTR_NAME` the central
source of truth regarding the React-specific ID attribute name.
2013-06-24 18:28:29 -07:00
CommitSyncScript
bd8ecc1caa Restore @spicyj's lifecycle tests
These got lost in a rebase.
2013-06-24 18:28:18 -07:00
CommitSyncScript
6bbcbc08cf Rename BrowserEnv to ViewportMetrics
Becuase that's what it is.
2013-06-24 18:28:16 -07:00
CommitSyncScript
f0a4ca5f69 Remove React.autoBind entirely 2013-06-24 18:28:12 -07:00
CommitSyncScript
de40842597 Use @return, not @returns 2013-06-24 16:16:46 -07:00
CommitSyncScript
76ec746341 Require Statement Nits 2013-06-24 16:16:38 -07:00
CommitSyncScript
14102e8a48 Fix isMounted() for composite components
This behavior seemed incorrect for composite components.

- isComponentMounted() represents ReactComponent's lifecycle of mounting
- isMounted() represents ReactCompositeComponent's lifecycle of isMounted()

Therefore, ReactComponents no longer have isMounted(). I think this is fine since it was not supposed to be public anyway.
2013-06-24 16:15:49 -07:00
CommitSyncScript
4f2d8dfe72 Dynamic Input Component
Summary:
This is a proposal based loosely on the discussions I've had with @paulshen and @jwalke. It implements a shim for `React.DOM.input` (used as `<input>`) that supports two different use cases depending on whether `value` is provided or not.

If a `value` is //not// provided, the input will be initialized with the empty string (or `defaultValue`) and anytime the user changes the input, the `onChange` (or `onTextChange`) handler will be fired and the DOM will reflect the new changes.

  React.renderComponent(
    <input type="text" defaultValue="Untitled" onTextChange={handleChange} />,
    container
  );

If a `value` is provided, the input will be initialized to that value. Anytime the user changes the input, the `onChange` (or `onTextChange`) handler will be fired. However, the DOM will //not// reflect the new changes. If a `value` is provided, it is the responsibility of the owner to update the `value` prop passed in.

  var value = "Untitled";
  var input = React.renderComponent(
    <input type="text" value={value} onTextChange={handleChange} />,
    container
  );
  function handleChange(event) {
    // Do something cool like strip out non-numbers.
    var value = event.target.value.replace(/\D/g, '');
    input.setProps({value: value});
  }

This is just a start and we should build similar components for `textarea` and `select`. Also, this does not inject the new components because the changes are not backward compatible. Once we change all `<input>` uses to use `ReactDOMInput`, then we can inject.
2013-06-24 16:13:14 -07:00
CommitSyncScript
7c60bb3e54 Add unit test to prevent regression
The original autobinding diff made some assumptions about how methods were called on components that had to be reverted. This diff
enforces those assumptions in a test
2013-06-24 16:12:06 -07:00
CommitSyncScript
a62686622b Clean up naming
Fix a small style nit
2013-06-24 16:11:55 -07:00
CommitSyncScript
a61f4df0b9 Fix a bunch of problems with implicit autobinding 2013-06-24 16:11:24 -07:00
CommitSyncScript
3266818b42 fix bad caching in ReactID.getID 2013-06-24 16:11:00 -07:00
CommitSyncScript
c9ecbaccb3 Use React.autoBind by default.
Per our discussion - this is the general approach we'd like to take for
the public facing API.

    var MyComponent = React.createClass({
      render: function() {
        return <div onClick={this.myCallback} />;
      },
      myCallback: function() {
      }
    });
2013-06-24 16:10:33 -07:00
Ben Newman
336a0facc1 Merge pull request #99 from petehunt/invariants
Remove second argument to invariant()
2013-06-24 15:38:22 -07:00
petehunt
7053f59ad1 Remove second argument to invariant() 2013-06-23 21:58:59 -07:00
CommitSyncScript
3373572e15 Use ReactID.{get,set}ID instead of manipulating .id property directly.
Another step in the plan to centralize control of React-specific identifers.
2013-06-21 16:08:07 -07:00
CommitSyncScript
1839bcf109 Replace uses of ReactDOMNodeCache and getDOMNodeID with ReactID.
Also removed some unnecessary calls to `document.getElementById`, which
will eventually cease to work for React-specific IDs.

This clears the way for the deprecation of `ReactDOMNodeCache` and
`getDOMNodeID`.
2013-06-21 16:07:51 -07:00
CommitSyncScript
191c0dec32 Consolidate ReactDOMNodeCache and getDOMNodeID into ReactID.
When we move away from using the "id" attribute to identify
React-generated elements, we will need the cache (formerly
ReactDOMNodeCache) to be tied much more closely to the code that looks
elements up by ID (getDOMNodeID) and sets element IDs, since the magic of
document.getElementById will no longer be available.

The priming functions are going to come in handy when we create new DOM
fragments in mountComponent.

For backwards compatibility, the ReactDOMNodeCache and getDOMNodeID
modules still exist, but they are implemented entirely in terms of
functions exported from ReactID.
2013-06-21 16:07:22 -07:00
CommitSyncScript
2bc2b52eaa Allow accessing siblings by ref
This makes it possible to write a wider range of components without
depending on internal implementations.
2013-06-21 16:02:57 -07:00
CommitSyncScript
36a724feca Add reactComponentExpect#toBeComponentOfType
This adds a `toBeComponentOfType` method to `reactComponentExpect`. Now that we are injecting composite native components, `toBeDOMComponentWithTag` will not suffice and should be deprecated.
2013-06-21 16:02:55 -07:00
Paul O’Shannessy
18352090e7 Blogpost & changelog for v0.3.3 2013-06-21 10:57:41 -07:00
Paul O’Shannessy
4c97ffee34 Bring in Facebook's requestAnimationFrame module 2013-06-20 16:51:21 -07:00
Ben Alpert
ac5320e887 Remove textContent tests; they break in phantomjs 2013-06-19 17:26:29 -07:00
Ben Newman
91b10bd37c Merge pull request #109 from zpao/esprima-dep-as-tarball
Use github tarball link for esprima dependency
2013-06-19 15:59:56 -07:00
petehunt
79a2734068 Merge pull request #113 from vjeux/community_2
Community Roundup #2
2013-06-19 12:19:40 -07:00
Vjeux
32030687ba Community Roundup #2 2013-06-19 21:18:28 +02:00
Paul O’Shannessy
cb01363260 Cleanup lint warnings 2013-06-19 11:06:04 -07:00
Ben Alpert
0493b27222 Don't update value or textContent unnecessarily
_updateDOMChildren was already updating textContent so we don't need to
do it in _updateDOMProperties. Additionally, don't update .value if
it'll be a noop because it has side-effects (like moving the cursor) in
some browsers (like IE 9).

Refactor tests to be a bit more robust and a bit cleaner too.
2013-06-18 23:31:15 -07:00
Ben Alpert
44d6b94752 Merge remote-tracking branch 'origin/master' into textarea-update-value 2013-06-18 23:31:08 -07:00
petehunt
a2bc7387e4 Merge pull request #110 from vjeux/patch-1
Fix dangerouslySetInnerHTML
2013-06-18 23:13:58 -07:00
Christopher Chedeau
ea5e13893e Fix dangerouslySetInnerHTML 2013-06-19 00:09:02 -06:00
Paul O’Shannessy
bd044fc919 Use github tarball link for esprima dependency
It turns out that (at least for local development) npm has a long
standing bug where it doesn't recognize changing dependencies stored as
git urls (see https://github.com/isaacs/npm/issues/1727). Luckily npm
understand tarballs and GitHub provides tarballs for every commit, so
the workaround is easy, though unfortunate.
2013-06-18 15:29:37 -07:00
Paul O’Shannessy
870a29d9b0 Use absolute URLs for FB comments box 2013-06-18 10:20:34 -07:00
CommitSyncScript
0e91febb9c Better warnings for missing keys on arrays
We have less dynamic arrays in the code base now so let's start warning for all
the cases where we pass dynamic arrays without keys.

I use the displayName to point out which component's render method was
responsible. I only warn once per component. If the child was created in a
different component (and passed as a property) I also show the owner of the
child. Maybe it should've attached the key at a higher level.

This does give false positives for arrays that are truly static. Those should
probably be refactored to use the XML syntax if possible.
2013-06-18 09:36:24 -07:00
CommitSyncScript
37ddfa0521 Don't transfer children in transferPropsTo
06cff60bc1 made it so that `this.props.children` was no longer set when
none were provided.

  var x = <div />;

This caused an issue if the code was relying on the following not
transferring children.

  return this.transferPropsTo(<div />);
  // this now transfer children
2013-06-18 09:32:23 -07:00
Paul O’Shannessy
5bd449c157 Ignore .module-cache directories 2013-06-17 17:14:14 -07:00
Paul O’Shannessy
b69d7f0d2a Merge pull request #107 from remixz/package-json-fix
Fix package.json's reference to vendor/constants.js
2013-06-17 16:31:24 -07:00
Zach Bruggeman
a0475b3c29 Fix package.json's reference to vendor/constants.js 2013-06-17 16:27:07 -07:00
CommitSyncScript
3156458041 Fix most lint warnings/errors 2013-06-17 16:26:56 -07:00
CommitSyncScript
48333acba6 Remove reactKeys
It wasn't being used and it wasn't conforming to the @providesModule === file name rule.
2013-06-17 16:26:45 -07:00
CommitSyncScript
4a0456fb8e Fix lint warning about mismatched file & module name
@providesModule should match the file name. In this case we'll be consistent and suffix mixins with Mixin.
2013-06-17 16:26:07 -07:00
petehunt
405be0f966 Merge pull request #106 from benjamn/rename-woodchipper
Rename Woodchipper to ConstantVisitor, and simplify the vendor/constants.js interface
2013-06-17 15:55:25 -07:00
Ben Newman
000928f9dc Use recast.parse and .print for require("vendor/constants").propagate.
This removes the need to pass a callback, which is a nice improvement.
2013-06-17 16:30:32 -04:00
Ben Newman
0f87e8ee87 Rename Woodchipper-related stuff.
No functional changes introduced by this commit.

Renamed:

    woodchipper.js -> constants.js
    Woodchipper -> ConstantVisitor
    debranch -> propagate
2013-06-17 16:21:51 -04:00
Paul O’Shannessy
2195a479a8 Merge pull request #105 from benjamn/fix-options.writeback-bug
Upgrade Recast to 0.4.8 to fix options.writeback bug
2013-06-17 13:07:43 -07:00
Ben Newman
2383fd8813 Upgrade Recast to 0.4.8 to fix options.writeback bug.
Bug introduced by: https://github.com/benjamn/recast/commit/e913b22f8f
Bug fixed by: https://github.com/benjamn/recast/commit/170e18091e
2013-06-17 15:57:33 -04:00
CommitSyncScript
d8b6d260c9 Add missing license header 2013-06-17 12:50:55 -07:00
CommitSyncScript
6a41ede2d4 Fixing known keying problems
This fixes the last known parts of the flattening experiment. This has grown to
be somewhat complex and potentially fragile because of it. We may end up
reverting flattening in the future or address it slightly differently.

The purpose of this diff is to test if we've finally understood the real world
edge cases that flattening can lead to and how we have to key components to
cover those cases.

With this commit we never rekey the internal _key property. The semantics is
that once a component passes through a composite component, it's identity is
frozen.

props.key should accept numeric values and booleans which includes 0 and false.
This fixes the truthiness check.

We should never warn about missing key properties if a component is passed as a
static child. The _key acts as a flag to determine whether this component
was checked already.
2013-06-17 12:50:29 -07:00
CommitSyncScript
c04081bc56 Add missing license header. 2013-06-17 12:50:15 -07:00
CommitSyncScript
0b1ecd8872 Add Back DOMCharacterDataModified
Accidentally lost `DOMCharacterDataModified`.
2013-06-17 12:49:58 -07:00
CommitSyncScript
88e90d5601 Use Synthetic Events
Swaps out usage of `AbstractEvent` with `SyntheticEvent` (and subclasses).
2013-06-17 12:49:45 -07:00
CommitSyncScript
03464dc148 Fix EventPluginRegistry Unit Tests in GitHub
Dumping the mock cache isn't dirying the modules in the open source version, so we have to unit test a different way. If we can fix the unit test framework, we should revert this.

Also, I added strict mode to `EventPluginRegistry.js`.

See: https://github.com/facebook/react/pull/91
2013-06-17 12:49:22 -07:00
CommitSyncScript
1112f1a003 React onlyChild utility.
Small utility that extracts and validates that there is only a single
child passed to a React composite component. The benefit here is that we
abstract away *how* the children are actually stored while we iterate on
different approaches. This way we won't break callsites as we try different
ideas. When we settle on a final approach, all of these callsites will still
work.
2013-06-17 12:48:47 -07:00
Paul O’Shannessy
c1576fcf97 Remove trailing whitespace 2013-06-17 12:48:43 -07:00
CommitSyncScript
8592eacbf9 Use Node Cache in ReactComponent
There are currently two places where we lookup and cache nodes: `ReactDOMNodeCache` and `ReactComponent`. Instead, we should just consolidate caches and make `ReactComponent` use `ReactDOMNodeCache`.
2013-06-17 12:48:26 -07:00
petehunt
888cb824d7 Merge pull request #103 from benjamn/fix-maxBuffer-exceeded
Use grunt.util.spawn for jsx:* tasks instead of exec
2013-06-17 11:10:07 -07:00
petehunt
061527df6c Merge pull request #102 from zpao/fix-transformer
Improve JSXTransformer
2013-06-17 11:08:35 -07:00
Ben Newman
96b0a0253f Use grunt.util.spawn for jsx:* tasks instead of exec.
This should prevent "Warning: stdout maxBuffer exceeded" errors.

Also piping child process stdout and stderr to the parent process, so
you can see more of what's happening during the build process.
2013-06-17 13:56:58 -04:00
Paul O’Shannessy
c79a59b599 Improve JSXTransformer
The biggest improvement is that we'll now insert each parsed JSX script
back into a `<script>` tag with the body set. This allows the browser to
execute these scripts normally. Using `Function(functionBody)` or
`eval(functionBody)` both execute in window scope, but `var` assignments
don't actually get set on window (unlike everywhere else).

I also did some cleanup to make the code a little bit more readable.
In my minimal test cases this didn't break anything (scripts loaded in
the right order).
2013-06-17 10:52:16 -07:00
petehunt
fad7d58fc9 Update jsx-is-not-html.md 2013-06-17 03:11:57 -06:00
petehunt
97efa84676 Merge pull request #88 from vjeux/jsx_pitfall
Adding JSX pitfalls section in the docs
2013-06-17 02:05:55 -07:00
petehunt
22347ea54d Merge pull request #95 from groodt/patch-1
Small correction to tutorial.md
2013-06-17 01:36:51 -07:00
petehunt
46513c6d78 Merge pull request #96 from groodt/master
Very minor corrections to documentation
2013-06-17 01:26:31 -07:00
petehunt
1c7d01c2f4 Merge pull request #97 from spicyj/patch-1
Link to my own blog instead of Quora
2013-06-17 01:25:31 -07:00
ngavalas
7a0f2d71bb Add callbacks to all public-facing state/props methods
All public facing {set,replace,force}{props,state} methods now support
callbacks.
2013-06-16 22:45:36 -07:00
Ben Alpert
4104beadbb Link to my own blog 2013-06-15 18:59:45 -06:00
Greg Roodt
87f4b8be67 Minor grammar. 2013-06-15 11:08:06 +03:00
Greg Roodt
8d729d7da2 Minor typo. 2013-06-15 11:07:20 +03:00
Greg Roodt
f016479289 Update tutorial.md
The ajax call happens every 5 seconds, not every 60 seconds.
2013-06-15 10:15:42 +03:00
ngavalas
c81cc2e6d5 markdown syntax
Small problem with markdown syntax in syntax-highlighted block.
2013-06-14 16:41:02 -07:00
ngavalas
f3aac85d01 Updated docs and check for truthiness
Change api docs to reflect presence of the new argument.  In addition,
callback was change to require only a "truthy" value.
2013-06-14 16:37:20 -07:00
ngavalas
c6665e3460 Adds optional callback to setState
This commit adds an optional callback as a second argument to
`setState`, to be called after `setState` runs.

We never guarantee synchronous execution of `setState`, and as per
@phunt, we don't want to make that guarantee because we may eventually
batch calls to `setState`.  @jwalke agrees with him.
2013-06-14 16:23:06 -07:00
Timothy Yung
c7295b9e09 Merge pull request #61 from spicyj/getdomnodeid
getDOMNodeID: Don't return .id on random objects
2013-06-14 11:27:44 -07:00
Ben Newman
9fd9f712bf Merge pull request #91 from yungsters/master
Fix `EventPluginRegistry` Unit Tests
2013-06-14 06:45:57 -07:00
Ben Alpert
a9c70bcc1c getDOMNodeID: Don't return .id on random objects
If you defined a global named `id` (a horrible name, I know) then
getDOMNodeID(window) would return that object. Since only DOM nodes can
have IDs, this should be a noop change otherwise.

Test Plan:
Verified that document.documentElement and document.body both support
getAttributeNode properly in latest Chrome and in IE8.
2013-06-14 00:21:15 -07:00
Timothy Yung
80edd6ca87 Merge pull request #89 from vjeux/patch-4
Exposing ReactProps as React.Props
2013-06-13 21:08:10 -07:00
Timothy Yung
48f46b568d Merge pull request #92 from spicyj/fix-textchange
Fix textchange event enqueueing
2013-06-13 20:53:47 -07:00
yungsters
279792f891 Fix EventPluginRegistry Unit Tests
Dumping the mock cache isn't dirying the modules, so we have to unit test a different way. If we can fix our unit test framework, we should revert this.

Also, I added strict mode to `EventPluginRegistry.js`.
2013-06-13 20:38:23 -07:00
Ben Alpert
792b69ba11 Fix textchange event enqueueing
(Was broken by e1535fbd71d8c89c82cd9d9073c1ee97ee6a3b00.)
2013-06-13 20:34:14 -07:00
Paul O’Shannessy
06cff60bc1 Sync latest JSX transform - all children passed as separate arguments
This was a part of e1fe13d0cb upstream.
2013-06-13 18:18:54 -07:00
CommitSyncScript
770ec5946a Unbreaking falsy check on style values
Style values can be the number zero which is an actual value. So we check for
null instead. The empty string case falls through.
2013-06-13 17:49:04 -07:00
CommitSyncScript
b525a0c061 Unnecessary this._rootNodeID Invariant
Summary: This invariant is unnecessary because `ReactComponent.Mixin.receiveProps` already asserts that this component is mounted. (Being mounted guarantees you have a DOM ID, look at `ReactComponent` and see when `this._rootNodeID` is mutated.)
2013-06-13 17:48:09 -07:00
CommitSyncScript
34970fd785 Fix tht typos 2013-06-13 17:47:59 -07:00
Paul O’Shannessy
ceb5303581 Merge pull 75 upstream
Needed to make some small changes since we weren't synced when it was
merged.
2013-06-13 17:47:51 -07:00
CommitSyncScript
f456f8fa8d Remove isStatic
This can be replicated with a custom component that always returns false`
from `shouldComponentUpdate`. A generic implementation might look like:

```
var StaticContainer = React.createClass({
  shouldComponentUpdate: function() {
    return false;
  },

  render: function() {
    return this.transferPropsTo(this.props.children[0]);
  }
});
```

And then used in JSX as
`<StaticContainer><div>Hello!</div></StaticContainer>`, resulting in
only `<div>Hello!</div>` being inserted into the DOM.
2013-06-13 17:40:52 -07:00
CommitSyncScript
e1fe13d0cb Pass multiple children in JSX as additional arguments
This is an alternative to D809298. In normal usage you'd end up with a single
flat array in props.children.
2013-06-13 17:40:05 -07:00
CommitSyncScript
01511ea557 Remove Unnecessary DOM Mutations
This fixes an edge case that can cause unnecessary mutations in the DOM. Namely, if a prop is falsey, it will get touched on every update by reconciliation. See unit test.
2013-06-13 17:39:47 -07:00
CommitSyncScript
802241a660 Cleanup style Prop Reconciliation
This cleans up the reconcilation path when adding a `style` prop (going from a falsey or no `style` to having one) by reducing the need for an object allocation and for-loop.
2013-06-13 17:39:23 -07:00
CommitSyncScript
e1535fbd71 Create EventPluginRegistry
The `EventPluginHub` module was getting huge and scary. This pulls out all of the logic required to inject plugins and publish their event registration names into a new `EventPluginRegistry` module.

Functionally, nothing should have changed. I added many error checks to cover edge cases that we were not yet running into, but they are all in `EventPluginRegistry` and unit tested.
2013-06-13 17:38:49 -07:00
CommitSyncScript
aea8e16b4a Add ReactComponent#isMounted
There is currently no way for components to know whether or not they are mounted. This means there's no way for callbacks to figure out if they can make certain assumptions (e.g. can `getDOMNode()` or `setState()` be safely invoked).

This adds an `isMounted` protected method that lets components properly handle callback behavior when unmounted.
2013-06-13 17:38:20 -07:00
CommitSyncScript
0d6bb650cb Add HTML5 Drag/Drop events to React 2013-06-13 17:37:58 -07:00
Ben Alpert
ddc4ffffa0 Don't let textarea value change via textContent
Turns out my tests before weren't particularly useful because
receiveProps doesn't end up running componentDidUpdate since the
transaction never finishes. Now they use replaceProps instead (and I
verified that commenting out the "rootNode.value = ..." line makes the
tests fail, which wasn't true before).
2013-06-12 19:12:52 -07:00
Vjeux
d7a5f137ff Adding JSX pitfalls section in the docs 2013-06-13 03:08:50 +02:00
Christopher Chedeau
34173638d4 Exposing ReactProps as React.Props
Right now, even though ReactProps is committed, there is no way to use it as it is not exposed.
2013-06-12 18:28:25 -06:00
Timothy Yung
c9618587ef Merge pull request #67 from vjeux/fb_comments
Facebook comments integration on Docs and Blog
2013-06-12 16:13:05 -07:00
Vjeux
101bfa3112 Facebook comments integration on Docs and Blog 2013-06-13 01:08:31 +02:00
Vjeux
523bde4dc5 Community round-up blog post 2013-06-12 13:55:51 -07:00
Jordan W
483350905b Merge pull request #86 from petehunt/fixed-width-height
Fixed width/height on React logo
2013-06-12 12:35:33 -07:00
petehunt
5b72334852 Fixed width/height on React logo 2013-06-12 12:33:38 -07:00
Ben Alpert
d13a37ce22 Don't set value if it'll be a noop 2013-06-12 01:55:26 -07:00
Ben Alpert
0c6f4b3bcc Set textarea value when changing content
At http://jsfiddle.net/spicyj/W4QLq/, typing into the textbox would cause
clicking the button to do nothing; now it should work.
2013-06-12 00:14:58 -07:00
Timothy Yung
0e6fca4a38 Merge pull request #68 from vjeux/twitter
Integrate twitter in the support page
2013-06-11 22:34:44 -07:00
Timothy Yung
dfd76be568 Merge pull request #75 from spicyj/textchange
Add new textChange event: input + IE shim
2013-06-11 22:00:19 -07:00
Ben Alpert
0dc08c2115 Missing semicolon 2013-06-11 21:54:50 -07:00
Ben Alpert
6b572b3f25 Refactor based on review feedback 2013-06-11 21:51:47 -07:00
Timothy Yung
c6c40a5fb3 Merge pull request #84 from spicyj/remove-props
Correctly remove attributes when deleting props
2013-06-11 19:54:36 -07:00
Ben Alpert
fdc6beed1a Fix nit and comment 2013-06-11 19:53:24 -07:00
Ben Alpert
731aa8ead1 internalPropNames isn't necessary, so remove it
Perhaps we'll bring it back as a future perf optimization if that
appears useful.
2013-06-11 19:02:35 -07:00
Ben Alpert
8762634cf1 Remove unused require 2013-06-11 17:28:06 -07:00
Ben Alpert
735a91c9d5 Fix relative require copy pasta 2013-06-11 17:24:35 -07:00
Ben Alpert
705ce56694 Correctly remove attributes when deleting props
The most obvious manifestation of this bug is visible here:
http://jsfiddle.net/spicyj/zzGas/. In short, when props are removed from a
component, the underlying HTML element doesn't have the attribute
removed.

This change should fix it, but unfortunately it (presumably) makes
_updateDOMProperties a bit slower.
2013-06-11 16:46:10 -07:00
petehunt
94fdf2cf5d Merge pull request #81 from benjamn/issue-80-commoner-no-longer-rewrites-require
Upgrade Commoner and Recast to latest versions
2013-06-11 16:22:17 -07:00
Paul O’Shannessy
758c21fb9c Merge pull request #77 from spicyj/componentdidmount-order
Run inner componentDidMount method first
2013-06-11 13:10:03 -07:00
Ben Newman
15360056bd Upgrade Commoner and Recast to latest versions.
The Commoner upgrade is a big one because it makes bin/jsx no longer
rewrite module identifiers to be relative by default, which should
reduce confusion for people trying to use it as a standalone
transformer.

Closes #80.
2013-06-11 15:24:50 -04:00
Ben Alpert
932c45a7ab Check canUseDOM before calling isEventSupported 2013-06-10 18:27:22 -07:00
Ben Alpert
e39743f2f8 Removed unused variable 2013-06-10 17:19:45 -07:00
Paul O’Shannessy
cff4d53a9e Add missing license headers 2013-06-10 16:25:37 -07:00
CommitSyncScript
c2ce1d00cd Fix Event Normalization in IE<9
IE<9 relied on the `target` property being overriden. This adds back a hack that only applies in IE<9. I'll be able to revert this hack once I check in synthetic events.
2013-06-10 16:19:25 -07:00
CommitSyncScript
b3e0dc47a8 Rename "Delegate" to "Synthetic"
This is just a simple rename of the event classes to `SyntheticEvent`. I've also updated the constructor arguments to be more correct:

 - `dispatchConfig`: Data used by the plugin system for dispatching the event, for example: `{registrationName: 'onClick'}`
 - `dispatchMarker`: An identifying marker used to describe where the event is occuring, for example: `.reactRoot[0]`
2013-06-10 16:19:03 -07:00
CommitSyncScript
93f979ae18 Use isAncestorIDOf in ReactInstanceHandles
This is both a functional fix and performance fix for `ReactInstanceHandles`.

 - `getFirstReactDOM` uses `indexOf` but should be checking ancestry (via `isMarker()`).
 - Added `isAncestorIDOf`, checking ancestry can be way faster than getting a common ancestor: http://jsperf.com/react-ancestor-id-check
2013-06-10 16:18:40 -07:00
CommitSyncScript
ca3f871646 Reduce ReactInstanceHandles API Surface Area
Change `ReactInstanceHandles` so that `getFirstCommonAncestorID` and `nextDescendantID` are now private (and documented to be only exposed for unit testing). Also:

 - Renamed `nextDescendantID` to `getNextDescendantID`.
 - Renamed `parentID` to `getParentID`.

I also organized `ReactInstanceHandles-test` by method names.

Functionally, this diff should not change anything.
2013-06-10 16:18:13 -07:00
CommitSyncScript
1be6c592a6 Fix typechecks for isRenderedByReact() 2013-06-10 16:17:52 -07:00
CommitSyncScript
37cde3d864 Stabilize minimal server rendering API
This is a pretty killer feature and the API is simple. I know it's another API method on React, but I think it's
the only way.
2013-06-10 16:17:26 -07:00
Ben Alpert
2afd7186ae Run inner componentDidMount method first
Fixes #76.
2013-06-09 17:21:22 -07:00
Ben Alpert
c19bf9cffe Add new textChange event: input + IE shim
IE8 doesn't support oninput and IE9 supports it badly but we can do
almost a perfect shim by listening to a handful of different events
(focus, blur, propertychange, selectionchange, keyup, keydown).

This always triggers event handlers during the browser's event loop (not
later in a setTimeout) and after the value property has been updated.

The only case I know of where this doesn't fire the event immediately is
if (in IE8) you modify the input value using JS and then the user does a
key repeat, in which case we fire the event on the second keydown.

Test Plan:
Modify ballmer-peak example to add es5-shim and to use onTextChange
instead of onInput. In IE8, IE9, and latest Chrome, make sure that the
event is fired upon:

* typing normally,
* backspacing,
* forward-deleting,
* cutting,
* pasting,
* context-menu deleting,
* dragging text to reorder characters.

After modifying the example to change .value, make sure that the event
is not fired as a result of the changes from JS (even when the input box
is focused).
2013-06-09 04:18:15 -07:00
CommitSyncScript
7e7579e1ba Assign the same keys if it's a single nested array or not
If you specify a single array, we didn't prefix the keys with 0.

If you later add children, the first array won't have the same key.
2013-06-07 22:10:20 -07:00
CommitSyncScript
582359aeea Remove React.createComponentRenderer
Remove ReactMount.createComponentRenderer because it does not function
correctly.

  var f = React.createComponentRenderer(<div />);

  var container1 = document.createElement('div');
  var container2 = document.createElement('div');
  f(container1);
  f(container2); // error because mounting same instance into new root
2013-06-07 22:10:06 -07:00
CommitSyncScript
6c3c643c8e Fix typo in OrderedMap
Unique was spelled wrong. This fixes it.
2013-06-07 22:09:49 -07:00
CommitSyncScript
3eaed5a122 Delegate Event Classes
React's top-level event delegation dispatches `AbstractEvent` objects that contain:

 - `nativeEvent`, the original browser event.
 - `data`, an object with custom normalized properties.

This diff creates a set of `DelegateEvent` classes that will replace `AbstractEvent`. The goal is two-fold:

 # Provide a cross-browser implementation that conforms to the DOM Level 3 Events API so people don't have to use `nativeEvent`.
 # Generalize the event object API so that it can be shared by `DOMEventManager`, a top-level event delegation WIP.

This simply implements the classes. I will follow-up by replacing `AbstractEvent` with them.
2013-06-07 22:08:32 -07:00
CommitSyncScript
4bb966a7f0 Bugfixes to key assignment
Type coersion bug and ID breaking assumption.

Names need to be wrapped in something unique since otherwise two unique siblings
can end up having IDs that are subsets of eachother.
2013-06-07 22:08:14 -07:00
CommitSyncScript
0e9e64c550 Replace persistentCloneOf with persist
There are to reasons to prefer a `persist` method on the event rather than a static method:

 - In open source, people do not have access to `AbstractEvent`.
 - This will allow people to persist events without requiring another module.
 - This will make refactors easier and more flexible.
2013-06-07 22:07:43 -07:00
Jeffrey Lin
c5998fb483 Merge pull request #72 from benjamn/module-cache
Cache modules for jsx grunt tasks in react-tools/.module-cache
2013-06-07 18:11:05 -07:00
Ben Newman
880ada0a1c Cache modules for jsx grunt tasks in react-tools/.module-cache.
As of Commoner v0.6.11, the default is to put the cache files in
output/.module-cache, which used to be build/modules/.module-cache
before this commit. That still happens when you run bin/jsx directly,
just not for grunt tasks anymore.

The module cache needs to be cleared much less often than
build/modules, so it doesn't make sense to throw away all that work.
2013-06-07 18:02:43 -04:00
Jordan W
a5e5f53494 Merge pull request #69 from jordow/SimplifyExample
Make todo example shorter and not rely on the DOM.
2013-06-07 13:16:17 -07:00
jordow
81f3a5c6cd Make todo example shorter and not rely on the DOM. 2013-06-07 13:11:40 -07:00
Paul O’Shannessy
59bee8df21 Remove clowny diff.diff
An artifact of our sync process.
2013-06-06 15:09:11 -07:00
Paul O’Shannessy
796837b8c7 Merge pull request #66 from zpao/sync-latest
Sync latest from Facebook
2013-06-06 15:03:09 -07:00
CommitSyncScript
2dc24fc234 Add typecheck, cleanup
Followup with some additional comments for https://github.com/facebook/react/pull/58
2013-06-06 14:50:54 -07:00
CommitSyncScript
88923f61a7 Improve Browser Support for wheel Event
This improved browser support for the `wheel` event.

 - Try to use `wheel` event (DOM Level 3 Specification).
 - Fallback to `mousewheel` event.
 - Fallback to `DOMMouseWheel` (older Firefox).

Also, since `wheel` is the standard event name, let's use that in React.

NOTE: The tricky part was detecting if `wheel` is supported for IE9+ because `onwheel` does not exist.

Test Plan:
Execute the following in the console on a page with React:

  var React = require('React');
  React.renderComponent(React.DOM.div({
    style: {
      width: 10000,
      height: 10000
    },
    onWheel: function() {
      console.log('wheel');
    }
  }, null), document.body);

Verified that mousewheel events are logged to the console.
Verified in IE8-10, Firefox, Chrome, and Safari.
2013-06-06 14:48:25 -07:00
CommitSyncScript
ba6fea1bf5 Simplify Event Core
Summary:
This makes a few changes to React Core, most notably `ReactEventEmitter` and `ReactEventTopLevelCallback`.

 - Changed `ReactEventEmitter` to use `EventListener` (instead of `NormalizedEventListener`).
 - Deleted `NormalizedEventListener` (which was previously broken).
 - Created `getEventTarget` which is used to get a normalized `target` from a native event.
 - Changed `ReactEventTopLevelCallback` to use `getEventTarget`.
 - Renamed `abstractEventType` to `reactEventType` in `AbstractEvent`.
 - Reanmed `abstractTargetID` to `reactTargetID` in `AbstractEvent`.
 - Removed `originatingTopLevelEventType` from `AbstractEvent` (unused and violates encapsulation).
 - Removed `nativeEvent.target === window` check when refreshing authoritative scroll values (unnecessary).

This actually fixes React because `NormalizedEventListener` does not currently do what it promises to do (which is normalizing `target` on the native event). The `target` event is read-only on native events.

This also revises documentation and adds `@typechecks` to a few modules.

NOTE: Most importantly, this sets the stage for replacing `AbstractEvent` with `ReactEvent` and subclasses, piecemeal.
2013-06-06 14:48:12 -07:00
CommitSyncScript
36d8ce8fab [React] remove deprecated Component.update()
Summary: Since grepping for `update` and `updateAll` is pretty hard, I had these these functions call through but complain loudly. This noisy call through has been in prod for over a week and I haven't heard any complains, so let's take it out altogether.
2013-06-06 14:46:53 -07:00
CommitSyncScript
153fd9246e [React] Don't use autoMockOff 2013-06-06 14:29:45 -07:00
CommitSyncScript
fac24d462f React: Add @typechecks to CallbackRegistry 2013-06-06 14:29:45 -07:00
Paul O’Shannessy
83101b878e Add license headers to new files 2013-06-06 14:29:45 -07:00
CommitSyncScript
9d1055b3d2 Rename ReactEvent to ReactEventEmitter
ReactEvent should be reserved for the actual object created when an
event fires. The current ReactEvent is more like EventEmitter than
anything (e.g. it sets up delegation, provides methods to attach and
remove listeners).
2013-06-06 14:29:45 -07:00
CommitSyncScript
0614d30654 Move test utils internally, update for consistency 2013-06-06 14:29:44 -07:00
CommitSyncScript
9965b6b9dd Fix Listener Cleanup on Unmount
We need to make sure that deleteAllListeners() is invoked before we call
the superclass's unmountComponent() method or else we will lose
this._rootNodeID.

I also added an invariant and unit test to make sure we do not break
this in the future.
2013-06-06 14:29:44 -07:00
CommitSyncScript
a06de4bc4f Cleanup ReactCurrentOwner on Fatal
If a React component's render() fatals, it may contaminate
ReactCurrentOwner. This will cause the owner to be set improperly for
the next React.renderComponent() invocation (which causes an owner to be
set when there shouldn't be one).
2013-06-06 14:29:44 -07:00
CommitSyncScript
11a7cb5b73 Only Allow forceUpdate on Mounted Components 2013-06-06 14:29:44 -07:00
CommitSyncScript
bae6100ae8 Make ReactIdentity-test less fragile with respect to root IDs. 2013-06-06 14:29:44 -07:00
CommitSyncScript
3ffbb4d096 Re-add invariant
Bring back the invariant() that disallows setProps() and replaceProps()
on owned components.
2013-06-06 14:29:44 -07:00
CommitSyncScript
ca5d7bc683 Add getDefaultProps()
As it turns out, default values are very useful. This implements
getDefaultProps(), a hook for components to provide prop values when
a prop is not specified by the user.
2013-06-06 14:29:44 -07:00
CommitSyncScript
1457850b72 Rename domUtils to dom 2013-06-06 14:29:44 -07:00
CommitSyncScript
100af48f53 Support rendering different components into same node
var container = ...; // some DOM node
React.renderComponent(<div />, container);
React.renderComponent(<span />, container);

This should replace the rendered <div> with a <span>, effectively
reconciling at the root level.
2013-06-06 14:29:44 -07:00
CommitSyncScript
3e211bf662 [React] Removing invariant warning about updating owner state
It seems like it's possible to render a component that ends up having an
owner. Because you can end up rendering inside a render somehow.
2013-06-06 14:29:44 -07:00
CommitSyncScript
606d6b8fd4 Revert Object.create in NormalizedEventListener
It seems that the use of Object.create (to comply with strict mode) in
NormalizedEventListener is not happy in IE8.
2013-06-06 14:29:44 -07:00
CommitSyncScript
b581c8cfc7 Always reassign _key for every pass
Currently we're mutating _key. Mutation here is fine, but it needs to
be idempotent - which it's not. This is causing some issues.

Instead I reassign the _key every time it passes through a flattening.
This means that it's unique and stable for a single pass through a composite
component. When it's repassed another level, it loses it previous
identity and is rekeyed by it's new location.

For auto-generated keys by index, this actually means it has the same
semantics as before flattening.

For explicit keys, it has the effect that keys need to be unique at
every level. Regardless of how the key got there. Every component needs to ensure
that it doesn't combine keys from two different sources that may collide. This
is also inline with the old semantics but less intuitive in the new model.
2013-06-06 14:29:44 -07:00
CommitSyncScript
54d3134da2 Add ReactProps.func
This adds ReactProps.func so people don't need to write the
slightly-more-cryptic ReactProps.instanceOf(Function). We should have
had this all along.
2013-06-06 14:29:44 -07:00
CommitSyncScript
259392035d mapChildren
mapChilden() is similar to Array.map() and objMap() but handles deep
nested structures and follows similar rules to flattenChildren()
2013-06-06 14:29:44 -07:00
CommitSyncScript
4b81de93d3 use key="foo" for all components
flattenChildren was only using key when child.mountInContainerNode
exists, which is defined on ReactCompositeComponent, and not
ReactNativeComponent.

This uses the isValidComponent() fn to see if we should use this key.
2013-06-06 14:29:44 -07:00
CommitSyncScript
93fc188afb style prop improvements
Some improvements to how style={{x:y}} is handled in React:
* ignores null styles, rather than setting them.

Codez:

    var highlighted = false;
    <div style={{color: highlighted ? 'red' : null}} />

Before:

    <div style="color:;"></div>

After:

    <div></div>

Respects that 0 has no units.
2013-06-06 14:29:44 -07:00
CommitSyncScript
007b75f78a Flatten Children A Single Level
This expects static children as additional arguments to the constructor
and flattens any array arguments one level deep.

Component(props, child1, child2, arrayOfChildren, child3) ->
.props.children = [child1, child2, ...arrayOfChildren, child3]

This can avoid an additional heap allocation for the unflat array.

It allows you to pass nested arrays and objects like you used to. Those
aren't immediately flattened. That makes this a fairly safe change.

Passing a dynamic array without key properties will yield a warning
(once). Might consider throwing later.

Once we change the transpiler to use the new syntax, you'll end up with
a single flat array in normal usage.

This doesn't actually update the JSX transform.
2013-06-06 14:29:43 -07:00
Vjeux
0435216eb6 Using markdown instead of html 2013-06-06 08:40:24 +02:00
Vjeux
7061d2b25b Integrate twitter in the support page 2013-06-06 08:38:09 +02:00
Paul O’Shannessy
31cdb4c8a7 Merge pull request #58 from spicyj/unmount-nothrow
Make unmountAndReleaseReactRootNode not throw
2013-06-05 15:00:00 -07:00
Paul O’Shannessy
1e76d84569 Merge pull request #32 from spicyj/input
Add new onInput event
2013-06-05 14:57:25 -07:00
Ben Alpert
6012e94e50 Make unmountAndReleaseReactRootNode not throw
When there isn't any React node in the DOM, unmountAndReleaseReactRootNode
threw an exception because component was undefined. Instead, return whether we
were able to unmount the component.
2013-06-04 14:36:16 -07:00
Ben Alpert
35306fa7f5 Revert "Simulate input event" for now
This reverts commit 580e8f0dbb.
2013-06-04 01:29:12 -07:00
Ben Alpert
580e8f0dbb Simulate input event instead of relying on native
Test Plan:
With the ballmer-peak example (modified to use input), tested that the
percentage updates when adding or deleting text in the field on Chrome
and IE9. After adding es5-shim and es5-sham to the ballmer-peak page,
IE8 works properly too.
2013-06-01 16:55:19 -07:00
Ben Alpert
2467c0e651 Update examples to use onInput instead of onKeyUp
onInput has the advantage that it responds to repeated key events before
onKeyUp and is called when modifying the input without the keyboard
(such as pasting with the mouse).

Test Plan:
Opened the ballmer-peak example and docs homepage in Chrome and checked
that both examples update whenever the text is changed.
2013-05-30 18:20:34 -07:00
Ben Alpert
292dd238e7 Add new onInput event
'input' is supported in IE9+ and all other browsers according to
https://developer.mozilla.org/en-US/docs/Web/API/window.oninput

Test Plan:
Modified ballmer-peak example to use onInput instead of onKeyUp and
tested that it works properly on latest Chrome.
2013-05-30 18:20:34 -07:00
348 changed files with 21122 additions and 8240 deletions

3
.gitignore vendored
View File

@@ -5,12 +5,15 @@ node_modules
static
.grunt
_SpecRunner.html
__benchmarks__
build/
.module-cache
*.gem
docs/code
docs/_site
docs/.sass-cache
docs/css/react.css
docs/js/.module-cache
docs/js/JSXTransformer.js
docs/js/react.min.js
docs/js/docs.js

21
.mailmap Normal file
View File

@@ -0,0 +1,21 @@
Ben Newman <bn@cs.stanford.edu> <benjamn@fb.com>
Dan Schafer <dschafer@fb.com>
Harry Hull <harry.hull1@gmail.com>
Jeff Morrison <jeff@anafx.com> <Jeff@anafx.com>
Jeff Morrison <jeff@anafx.com> JeffMo <jeffmo@fb.com>
Jeffrey Lin <lin.jeffrey@gmail.com> <jeffreylin@fb.com>
Jordan Walke <jordojw@gmail.com>
Jordan Walke <jordojw@gmail.com> <jordanjcw@fb.com>
Laurence Rowe <l@lrowe.co.uk> <laurence@lrowe.co.uk>
Nick Gavalas <njg57@cornell.edu>
Paul OShannessy <paul@oshannessy.com> <poshannessy@fb.com>
Paul Shen <paul@mnml0.com> <paulshen@fb.com>
Pete Hunt <floydophone@gmail.com>
Pete Hunt <floydophone@gmail.com> <pete.hunt@fb.com>
Pete Hunt <floydophone@gmail.com> <pete@instagram.com>
Sander Spies <sandermail@gmail.com>
Sebastian Markbåge <sebastian@calyptus.eu> <sema@fb.com>
Stoyan Stefanov <ssttoo@ymail.com>
Timothy Yung <yungsters@gmail.com> <yungsters@fb.com>
Vjeux <vjeuxx@gmail.com>
Vjeux <vjeuxx@gmail.com> <vjeux@fb.com>

View File

@@ -1,3 +1,15 @@
---
language: node_js
node_js:
- "0.10"
- '0.10'
after_script:
- curl -F "react=@build/react.js" -F "react.min=@build/react.min.js" -F "transformer=@build/JSXTransformer.js"
-F "react-with-addons=@build/react-with-addons.js" -F "react-with-addons.min=@build/react-with-addons.min.js"
-F "commit=$TRAVIS_COMMIT" -F "date=`git log --format='%ct' -1`" -F "pull_request=$TRAVIS_PULL_REQUEST"
-F "token=$SECRET_TOKEN" -F "branch=$TRAVIS_BRANCH" $SERVER
env:
global:
# SERVER
- secure: qPvsJ46XzGrdIuPA70b55xQNGF8jcK7N1LN5CCQYYocXLa+fBrl+fTE77QvehOPhqwJXcj6kOxI+sY0KrVwV7gmq2XY2HZGWUSCxTN0SZlNIzqPA80Y7G/yOjA4PUt8LKgP+8tptyhTAY56qf+hgW8BoLiKOdztYF2p+3zXOLuA=
# SECRET_TOKEN
- secure: dkpPW+VnoqC/okhRdV90m36NcyBFhcwEKL3bNFExAwi0dXnFao8RoFlvnwiPlA23h2faROkMIetXlti6Aju08BgUFV+f9aL6vLyU7gUent4Nd3413zf2fwDtXIWIETg6uLnOpSykGKgCAT/hY3Q2oPLqOoY0OxfgnbqwxkxljrE=

48
AUTHORS Normal file
View File

@@ -0,0 +1,48 @@
Alexander Solovyov <alexander@solovyov.net>
Andrew Zich <azich@fb.com>
Andrey Popp <8mayday@gmail.com>
Ben Alpert <spicyjalapeno@gmail.com>
Ben Newman <bn@cs.stanford.edu>
Brian Rue <brian@rollbar.com>
Cam Spiers <camspiers@gmail.com>
Cheng Lou <chenglou92@gmail.com>
Christian Roman <chroman16@gmail.com>
Clay Allsopp <clay.allsopp@gmail.com>
Connor McSheffrey <connor.mcsheffrey@gmail.com>
Dan Schafer <dschafer@fb.com>
Daniel Gasienica <dgasienica@zynga.com>
Daniel Miladinov <dmiladinov@wingspan.com>
Danny Ben-David <dannybd@fb.com>
David Hu <davidhu91@gmail.com>
Eric Clemmons <eric@smarterspam.com>
Greg Roodt <groodt@gmail.com>
Harry Hull <harry.hull1@gmail.com>
Hugo Jobling <me@thisishugo.com>
Isaac Salier-Hellendag <isaac@fb.com>
Jakub Malinowski <jakubmal@gmail.com>
James Ide <ide@fb.com>
Jamie Wong <jamie.lf.wong@gmail.com>
Jan Kassens <jkassens@fb.com>
Jeff Morrison <jeff@anafx.com>
Jeffrey Lin <lin.jeffrey@gmail.com>
Jordan Walke <jordojw@gmail.com>
Josh Duck <josh@fb.com>
Keito Uchiyama <keito@fb.com>
Kunal Mehta <k.mehta@berkeley.edu>
Laurence Rowe <l@lrowe.co.uk>
Marshall Roch <mroch@fb.com>
Martin Konicek <mkonicek@fb.com>
Mathieu M-Gosselin <mathieumg@gmail.com>
Nick Gavalas <njg57@cornell.edu>
Owen Coutts <owenc@fb.com>
Paul OShannessy <paul@oshannessy.com>
Paul Seiffert <paul.seiffert@gmail.com>
Paul Shen <paul@mnml0.com>
Pete Hunt <floydophone@gmail.com>
Peter Cottle <pcottle@fb.com>
Sander Spies <sandermail@gmail.com>
Sebastian Markbåge <sebastian@calyptus.eu>
Stoyan Stefanov <ssttoo@ymail.com>
Timothy Yung <yungsters@gmail.com>
Vjeux <vjeuxx@gmail.com>
Zach Bruggeman <zbruggeman@me.com>

117
CHANGELOG.md Normal file
View File

@@ -0,0 +1,117 @@
## 0.5.0 (October 16, 2013)
### React
* Memory usage improvements - reduced allocations in core which will help with GC pauses
* Performance improvements - in addition to speeding things up, we made some tweaks to stay out of slow path code in V8 and Nitro.
* Standardized prop -> DOM attribute process. This previously resulting in additional type checking and overhead as well as confusing cases for users. Now we will always convert your value to a string before inserting it into the DOM.
* Support for Selection events.
* Support for [Composition events](https://developer.mozilla.org/en-US/docs/Web/API/CompositionEvent).
* Support for additional DOM properties (`charSet`, `content`, `form`, `httpEquiv`, `rowSpan`, `autoCapitalize`).
* Support for additional SVG properties (`rx`, `ry`).
* Support for using `getInitialState` and `getDefaultProps` in mixins.
* Support mounting into iframes.
* Bug fixes for controlled form components.
* Bug fixes for SVG element creation.
* Added `React.version`.
* Added `React.isValidClass` - Used to determine if a value is a valid component constructor.
* Removed `React.autoBind` - This was deprecated in v0.4 and now properly removed.
* Renamed `React.unmountAndReleaseReactRootNode` to `React.unmountComponentAtNode`.
* Began laying down work for refined performance analysis.
* Better support for server-side rendering - [react-page](https://github.com/facebook/react-page) has helped improve the stability for server-side rendering.
* Made it possible to use React in environments enforcing a strict [Content Security Policy](https://developer.mozilla.org/en-US/docs/Security/CSP/Introducing_Content_Security_Policy). This also makes it possible to use React to build Chrome extensions.
### React with Addons (New!)
* Introduced a separate build with several "addons" which we think can help improve the React experience. We plan to deprecate this in the long-term, instead shipping each as standalone pieces. [Read more in the docs](http://facebook.github.io/react/docs/addons.html).
### JSX
* No longer transform `class` to `className` as part of the transform! This is a breaking change - if you were using `class`, you *must* change this to `className` or your components will be visually broken.
* Added warnings to the in-browser transformer to make it clear it is not intended for production use.
* Improved compatibility for Windows
* Improved support for maintaining line numbers when transforming.
## 0.4.1 (July 26, 2013)
### React
* `setState` callbacks are now executed in the scope of your component.
* `click` events now work on Mobile Safari.
* Prevent a potential error in event handling if `Object.prototype` is extended.
* Don't set DOM attributes to the string `"undefined"` on update when previously defined.
* Improved support for `<iframe>` attributes.
* Added checksums to detect and correct cases where server-side rendering markup mismatches what React expects client-side.
### JSXTransformer
* Improved environment detection so it can be run in a non-browser environment.
## 0.4.0 (July 17, 2013)
### React
* Switch from using `id` attribute to `data-reactid` to track DOM nodes. This allows you to integrate with other JS and CSS libraries more easily.
* Support for more DOM elements and attributes (e.g., `<canvas>`)
* Improved server-side rendering APIs. `React.renderComponentToString(<component>, callback)` allows you to use React on the server and generate markup which can be sent down to the browser.
* `prop` improvements: validation and default values. [Read our blog post for details...](http://facebook.github.io/react/blog/2013/07/11/react-v0-4-prop-validation-and-default-values.html)
* Support for the `key` prop, which allows for finer control over reconciliation. [Read the docs for details...](http://facebook.github.io/react/docs/multiple-components.html)
* Removed `React.autoBind`. [Read our blog post for details...](http://facebook.github.io/react/blog/2013/07/02/react-v0-4-autobind-by-default.html)
* Improvements to forms. We've written wrappers around `<input>`, `<textarea>`, `<option>`, and `<select>` in order to standardize many inconsistencies in browser implementations. This includes support for `defaultValue`, and improved implementation of the `onChange` event, and circuit completion. [Read the docs for details...](http://facebook.github.io/react/docs/forms.html)
* We've implemented an improved synthetic event system that conforms to the W3C spec.
* Updates to your component are batched now, which may result in a significantly faster re-render of components. `this.setState` now takes an optional callback as it's second parameter. If you were using `onClick={this.setState.bind(this, state)}` previously, you'll want to make sure you add a third parameter so that the event is not treated as the callback.
### JSX
* Support for comment nodes `<div>{/* this is a comment and won't be rendered */}</div>`
* Children are now transformed directly into arguments instead of being wrapped in an array
E.g. `<div><Component1/><Component2/></div>` is transformed into `React.DOM.div(null, Component1(null), Component2(null))`.
Previously this would be transformed into `React.DOM.div(null, [Component1(null), Component2(null)])`.
If you were using React without JSX previously, your code should still work.
### react-tools
* Fixed a number of bugs when transforming directories
* No longer re-write `require()`s to be relative unless specified
## 0.3.3 (June 20, 2013)
### React
* Allow reusing the same DOM node to render different components. e.g. `React.renderComponent(<div/>, domNode); React.renderComponent(<span/>, domNode);` will work now.
### JSX
* Improved the in-browser transformer so that transformed scripts will execute in the expected scope. The allows components to be defined and used from separate files.
### react-tools
* Upgrade Commoner so `require` statements are no longer relativized when passing through the transformer. This was a feature needed when building React, but doesn't translate well for other consumers of `bin/jsx`.
* Upgraded our dependencies on Commoner and Recast so they use a different directory for their cache.
* Freeze our esprima dependency.
## 0.3.2 (May 31, 2013)
### JSX
* Improved compatability with other coding styles (specifically, multiple assignments with a single `var`).
### react-tools
* Switch from using the browserified build to shipping individual modules. This allows react-tools to be used with [browserify](https://github.com/substack/node-browserify).
## 0.3.1 (May 30, 2013)
### react-tools
* Fix bug in packaging resulting in broken module.
## 0.3.0 (May 29, 2013)
* Initial public release

View File

@@ -4,6 +4,7 @@ var exec = require('child_process').exec;
var jsxTask = require('./grunt/tasks/jsx');
var browserifyTask = require('./grunt/tasks/browserify');
var wrapupTask = require('./grunt/tasks/wrapup');
var populistTask = require('./grunt/tasks/populist');
var phantomTask = require('./grunt/tasks/phantom');
var npmTask = require('./grunt/tasks/npm');
var releaseTasks = require('./grunt/tasks/release');
@@ -16,6 +17,7 @@ module.exports = function(grunt) {
jsx: require('./grunt/config/jsx/jsx'),
browserify: require('./grunt/config/browserify'),
wrapup: require('./grunt/config/wrapup'),
populist: require('./grunt/config/populist'),
phantom: require('./grunt/config/phantom'),
npm: require('./grunt/config/npm'),
clean: ['./build', './*.gem', './docs/_site', './examples/shared/*.js'],
@@ -44,32 +46,54 @@ module.exports = function(grunt) {
// defines global variables instead of using require.
grunt.registerMultiTask('wrapup', wrapupTask);
grunt.registerMultiTask('populist', populistTask);
grunt.registerMultiTask('phantom', phantomTask);
grunt.registerMultiTask('npm', npmTask);
grunt.registerTask('build:basic', ['jsx:debug', 'browserify:basic']);
// Check that the version we're exporting is the same one we expect in the
// package. This is not an ideal way to do this, but makes sure that we keep
// them in sync.
var reactVersionExp = /\bReact\.version\s*=\s*['"]([^'"]+)['"];/;
grunt.registerTask('version-check', function() {
var version = reactVersionExp.exec(
grunt.file.read('./build/modules/React.js')
)[1];
var expectedVersion = grunt.config.data.pkg.version;
if (version !== expectedVersion) {
grunt.log.error('Versions do not match. Expected %s, saw %s', expectedVersion, version);
return false;
}
});
grunt.registerTask('build:basic', ['jsx:debug', 'version-check', 'browserify:basic']);
grunt.registerTask('build:addons', ['jsx:debug', 'browserify:addons']);
grunt.registerTask('build:transformer', ['jsx:debug', 'browserify:transformer']);
grunt.registerTask('build:min', ['jsx:release', 'browserify:min']);
grunt.registerTask('build:min', ['jsx:release', 'version-check', 'browserify:min']);
grunt.registerTask('build:addons-min', ['jsx:debug', 'browserify:addonsMin']);
grunt.registerTask('build:test', [
'jsx:debug',
'jsx:jasmine',
'jsx:test',
'browserify:jasmine',
'browserify:test'
'version-check',
'populist:jasmine',
'populist:test'
]);
grunt.registerTask('test', ['build:test', 'phantom:run']);
grunt.registerTask('test', ['build:test', 'build:basic', 'phantom:run']);
grunt.registerTask('npm:test', ['build', 'npm:pack']);
// Optimized build task that does all of our builds. The subtasks will be run
// in order so we can take advantage of that and only run jsx:debug once.
grunt.registerTask('build', [
'jsx:debug',
'version-check',
'browserify:basic',
'browserify:transformer',
'browserify:addons',
'jsx:release',
'browserify:min',
'browserify:addonsMin',
'copy:react_docs',
'compare_size'
]);

View File

@@ -28,20 +28,20 @@ React.renderComponent(
This example will render "Hello John" into a container on the page.
You'll notice that we used an XML-like syntax; [we call it JSX](http://facebook.github.io/react/docs/syntax.html). JSX is not required to use React, but it makes code more readable, and writing it feels like writing HTML. A simple transform is included with React that allows converting JSX into native JavaScript for browsers to digest.
You'll notice that we used an XML-like syntax; [we call it JSX](http://facebook.github.io/react/docs/jsx-in-depth.html). JSX is not required to use React, but it makes code more readable, and writing it feels like writing HTML. A simple transform is included with React that allows converting JSX into native JavaScript for browsers to digest.
## Installation
The fastest way to get started is to serve JavaScript from the CDN:
The fastest way to get started is to serve JavaScript from the CDN (also available on [CDNJS](http://cdnjs.com/#react)):
```html
<!-- The core React library -->
<script src="http://fb.me/react-0.3.2.min.js"></script>
<script src="http://fb.me/react-0.5.0.js"></script>
<!-- In-browser JSX transformer, remove when pre-compiling JSX. -->
<script src="http://fb.me/JSXTransformer-0.3.2.js"></script>
<script src="http://fb.me/JSXTransformer-0.5.0.js"></script>
```
We've also built a [starter kit](http://facebook.github.io/react/downloads/react-0.3.2.zip) which might be useful if this is your first time using React. It includes a webpage with an example of using React with live code.
We've also built a [starter kit](http://facebook.github.io/react/downloads/react-0.5.0.zip) which might be useful if this is your first time using React. It includes a webpage with an example of using React with live code.
If you'd like to use [bower](http://bower.io), it's as easy as:

36
bin/jsx
View File

@@ -2,41 +2,11 @@
"use strict";
var visitors = require('../vendor/fbtransform/visitors').transformVisitors;
var transform = require('../vendor/fbtransform/lib/transform').transform;
var debranch = require("../vendor/woodchipper").debranch;
var transform = require('jstransform').transform;
require("commoner").resolve(function(id) {
var context = this;
// Note that the result of context.getProvidedP() is cached for the
// duration of the build, so it is both consistent and cheap to
// evaluate multiple times.
return context.getProvidedP().then(function(idToPath) {
// If a module declares its own identifier using @providesModule
// then that identifier will be a key in the idToPath object.
if (idToPath.hasOwnProperty(id)) {
return context.readFileP(idToPath[id]);
}
// Otherwise assume the identifier maps directly to a path in the
// filesystem.
return context.readModuleP(id);
});
return this.readModuleP(id);
}).process(function(id, source) {
var context = this;
// This is where JSX, ES6, etc. desugaring happens.
source = transform(visitors.react, source).code;
return context.makePromise(function(callback) {
var constants = context.config.constants || {};
// Debranching means removing any obviously dead code after
// replacing constant conditional expressions with literal
// (boolean) values.
debranch(constants, source, function(source) {
callback(null, source);
});
});
return transform(visitors.react, source).code;
});

55
bin/jsx-internal Executable file
View File

@@ -0,0 +1,55 @@
#!/usr/bin/env node
"use strict";
var visitors = require('../vendor/fbtransform/visitors').transformVisitors;
var transform = require('jstransform').transform;
var propagate = require("../vendor/constants").propagate;
require("commoner").resolve(function(id) {
var context = this;
// Note that the result of context.getProvidedP() is cached for the
// duration of the build, so it is both consistent and cheap to
// evaluate multiple times.
return context.getProvidedP().then(function(idToPath) {
// If a module declares its own identifier using @providesModule
// then that identifier will be a key in the idToPath object.
if (idToPath.hasOwnProperty(id)) {
return context.readFileP(idToPath[id]);
}
// Otherwise assume the identifier maps directly to a path in the
// filesystem.
return context.readModuleP(id);
});
}).process(function(id, source) {
var context = this;
var constants = context.config.constants || {};
// This is where JSX, ES6, etc. desugaring happens.
source = transform(visitors.react, source).code;
// Constant propagation means removing any obviously dead code after
// replacing constant expressions with literal (boolean) values.
source = propagate(constants, source);
if (context.config.mocking) {
// Make sure there is exactly one newline at the end of the module.
source = source.replace(/\s+$/m, "\n");
return context.getProvidedP().then(function(idToPath) {
if (id !== "mock-modules" &&
id !== "mocks" &&
id !== "test/all" &&
idToPath.hasOwnProperty("mock-modules")) {
return source + '\nrequire("mock-modules").register(' +
JSON.stringify(id) + ', module);\n';
}
return source;
});
}
return source;
});

View File

@@ -1,5 +1,7 @@
source 'https://rubygems.org'
gem 'rake'
# jekyll, which builds it all
gem 'jekyll', '~>1.0'
@@ -14,3 +16,6 @@ gem 'rb-fsevent'
# Redcarpet for Markdown
gem 'redcarpet'
# For markdown header cleanup
gem 'sanitize'

View File

@@ -24,13 +24,19 @@ GEM
liquid (2.5.0)
maruku (0.6.1)
syntax (>= 1.0.0)
mini_portile (0.5.1)
nokogiri (1.6.0)
mini_portile (~> 0.5.0)
posix-spawn (0.3.6)
pygments.rb (0.5.0)
posix-spawn (~> 0.3.6)
yajl-ruby (~> 1.1.0)
rake (10.0.4)
rb-fsevent (0.9.3)
redcarpet (2.2.2)
safe_yaml (0.7.1)
sanitize (2.0.6)
nokogiri (>= 1.4.4)
sass (3.2.9)
syntax (1.0.0)
yajl-ruby (1.1.0)
@@ -41,6 +47,8 @@ PLATFORMS
DEPENDENCIES
jekyll (~> 1.0)
json
rake
rb-fsevent
redcarpet
sanitize
sass

View File

@@ -13,7 +13,7 @@ task :js do
end
desc "watch css & js"
task :watch => [:update_version] do
task :watch do
Process.spawn "sass --style=compressed --watch _css/react.scss:css/react.css"
Process.spawn "../bin/jsx --watch _js js"
Process.waitall
@@ -30,8 +30,8 @@ task :update_version do
end
desc "build into ../../react-gh-pages"
task :release => [:default] do
task :release => [:update_version, :default] do
system "jekyll build -d ../../react-gh-pages"
end
task :default => [:update_version, :css, :js]
task :default => [:css, :js]

View File

@@ -1,17 +1,71 @@
---
markdown: redcarpet
name: React
description: A JavaScript library for building user interfaces
redcarpet:
extensions:
- fenced_code_blocks
react_version: 0.3.2
pygments: true
baseurl: /react
url: http://facebook.github.io
permalink: /blog/:year/:month/:day/:title.html
exclude:
- Gemfile
- Gemfile.lock
- README.md
- Rakefile
url: http://facebook.github.io
baseurl: /react
permalink: /blog/:year/:month/:day/:title.html
redcarpet:
extensions:
- fenced_code_blocks
pygments: true
name: React
markdown: redcarpet
react_version: 0.5.0
description: A JavaScript library for building user interfaces
relative_permalinks: true
paginate: 5
paginate_path: /blog/page:num
nav_docs_sections:
- title: Quick Start
items:
- id: getting-started
title: Getting Started
- id: tutorial
title: Tutorial
- title: Guides
items:
- id: why-react
title: Why React?
- id: displaying-data
title: Displaying Data
subitems:
- id: jsx-in-depth
title: JSX in Depth
- id: jsx-gotchas
title: JSX Gotchas
- id: interactivity-and-dynamic-uis
title: Interactivity and Dynamic UIs
- id: multiple-components
title: Multiple Components
- id: reusable-components
title: Reusable Components
- id: forms
title: Forms
- id: working-with-the-browser
title: Working With the Browser
subitems:
- id: more-about-refs
title: More About Refs
- id: tooling-integration
title: Tooling Integration
- id: addons
title: Add-ons
- id: examples
title: Examples
- title: Reference
items:
- id: top-level-api
title: Top-Level API
- id: component-api
title: Component API
- id: component-specs
title: Component Specs and Lifecycle
- id: tags-and-attributes
title: Supported Tags and Attributes
- id: events
title: Event System
- id: dom-differences
title: DOM Differences

View File

@@ -199,13 +199,15 @@ li {
font-size: 14px;
// position: fixed;
float: left;
top: 100px;
width: 180px;
width: 210px;
ul {
list-style: none;
margin: 0;
}
ul ul {
margin-left: 20px;
}
li {
margin: 0;
}
@@ -245,6 +247,12 @@ li {
}
.nav-blog {
li {
margin-bottom: 5px;
}
}
// Home Page specifics
.home-section {
@@ -282,14 +290,14 @@ li {
margin-right: 0;
}
#examples {
h3 {
color: $darkColor;
font-size: 24px;
font-weight: normal;
margin-bottom: 5px;
}
#examples h3, .home-presentation h3 {
color: $darkColor;
font-size: 24px;
font-weight: normal;
margin-bottom: 5px;
}
#examples {
p {
margin: 0 0 25px 0;
max-width: $twoColumnWidth;
@@ -356,6 +364,22 @@ section.black content {
padding-bottom: 18px;
}
/**
* Blog
*/
.blogContent {
padding-top: 20px;
blockquote {
padding: 5px 15px;
margin: 20px 0;
background-color: #f8f5ec;
border-left: 5px solid #f7ebc6;
}
}
/**
* Docs
*/
@@ -495,6 +519,10 @@ p {
margin-bottom: 20px;
}
figure {
text-align: center;
}
.inner-content {
float: right;
width: $skinnyContentWidth;
@@ -658,3 +686,19 @@ p code {
padding-top: 0;
}
}
.post {
margin-bottom: 30px;
}
.pagination {
margin-bottom: 30px;
/* Trick to get the wrapper to expand to fit floating elements */
width: 100%;
overflow: hidden;
.next {
float: right;
}
}

View File

@@ -1,10 +1,11 @@
<div class="nav-docs">
<div class="nav-docs nav-blog">
<div class="nav-docs-section">
<h3>Recent posts</h3>
<ul>
{% for post in site.posts %}
<li><a href="/react{{ post.url }}"{% if page.title == post.title %} class="active"{% endif %}>{{ post.title }}</a></li>
{% endfor %}
{% for post in site.posts limit:10 %}
<li><a href="/react{{ post.url }}"{% if page.title == post.title %} class="active"{% endif %}>{{ post.title }}</a></li>
{% endfor %}
<li><a href="/react/blog/all.html">All posts ...</a></li>
</ul>
</div>
</div>

View File

@@ -1,24 +1,27 @@
<div class="nav-docs">
<div class="nav-docs-section">
<h3>Getting started</h3>
<ul>
<li><a href="/react/docs/getting-started.html"{% if page.id == 'docs-getting-started' %} class="active"{% endif %}>Getting Started</a></li>
<li><a href="/react/docs/tutorial.html"{% if page.id == 'docs-tutorial' %} class="active"{% endif %}>Tutorial</a></li>
<li><a href="/react/docs/common-questions.html"{% if page.id == 'docs-common-questions' %} class="active"{% endif %}>Common Questions</a></li>
</ul>
</div>
<div class="nav-docs-section">
<h3>Reference</h3>
<ul>
<li><a href="/react/docs/syntax.html"{% if page.id == 'docs-syntax' %} class="active"{% endif %}>JSX Syntax</a></li>
<li><a href="/react/docs/component-basics.html"{% if page.id == 'docs-component-basics' %} class="active"{% endif %}>Component Basics</a></li>
<li><a href="/react/docs/component-data.html"{% if page.id == 'docs-component-data' %} class="active"{% endif %}>Component Data</a></li>
<li><a href="/react/docs/component-lifecycle.html"{% if page.id == 'docs-component-lifecycle' %} class="active"{% endif %}>Component Lifecycle</a></li>
<li><a href="/react/docs/event-handling.html"{% if page.id == 'docs-event-handling' %} class="active"{% endif %}>Event Handling</a></li>
<li><a href="/react/docs/advanced-components.html"{% if page.id == 'docs-advanced-components' %} class="active"{% endif %}>Advanced Components</a></li>
<li><a href="/react/docs/mixins.html"{% if page.id == 'docs-mixins' %} class="active"{% endif %}>Mixins</a></li>
<li><a href="/react/docs/api.html"{% if page.id == 'docs-api' %} class="active"{% endif %}>API</a></li>
</ul>
</div>
{% for section in site.nav_docs_sections %}
<div class="nav-docs-section">
<h3>{{ section.title }}</h3>
<ul>
{% for item in section.items %}
<li>
<a href="/react/docs/{{ item.id }}.html"{% if page.id == item.id %} class="active"{% endif %}>
{{ item.title }}
</a>
{% if item.subitems %}
<ul>
{% for subitem in item.subitems %}
<li>
<a href="/react/docs/{{ subitem.id }}.html"{% if page.id == subitem.id %} class="active"{% endif %}>
{{ subitem.title }}
</a>
</li>
{% endfor %}
</ul>
{% endif %}
</li>
{% endfor %}
</ul>
</div>
{% endfor %}
</div>

View File

@@ -11,16 +11,17 @@ var MarkdownEditor = React.createClass({\n\
getInitialState: function() {\n\
return {value: 'Type some *markdown* here!'};\n\
},\n\
handleKeyUp: React.autoBind(function() {\n\
handleChange: function() {\n\
this.setState({value: this.refs.textarea.getDOMNode().value});\n\
}),\n\
},\n\
render: function() {\n\
return (\n\
<div className=\"MarkdownEditor\">\n\
<h3>Input</h3>\n\
<textarea onKeyUp={this.handleKeyUp} ref=\"textarea\">\n\
{this.state.value}\n\
</textarea>\n\
<textarea\n\
onChange={this.handleChange}\n\
ref=\"textarea\"\n\
defaultValue={this.state.value} />\n\
<h3>Output</h3>\n\
<div\n\
className=\"content\"\n\

View File

@@ -7,11 +7,14 @@ var Timer = React.createClass({\n\
getInitialState: function() {\n\
return {secondsElapsed: 0};\n\
},\n\
tick: React.autoBind(function() {\n\
tick: function() {\n\
this.setState({secondsElapsed: this.state.secondsElapsed + 1});\n\
}),\n\
},\n\
componentDidMount: function() {\n\
setInterval(this.tick, 1000);\n\
this.interval = setInterval(this.tick, 1000);\n\
},\n\
componentWillUnmount: function() {\n\
clearInterval(this.interval);\n\
},\n\
render: function() {\n\
return React.DOM.div({},\n\

View File

@@ -6,48 +6,38 @@ var TODO_COMPONENT = "\
/** @jsx React.DOM */\n\
var TodoList = React.createClass({\n\
render: function() {\n\
var items = this.props.items.map(function(item) {\n\
return <li>{item}</li>;\n\
});\n\
return <ul>{items}</ul>;\n\
var createItem = function(itemText) {\n\
return <li>{itemText}</li>;\n\
};\n\
return <ul>{this.props.items.map(createItem)}</ul>;\n\
}\n\
});\n\
\n\
var TodoCreate = React.createClass({\n\
handleSubmit: React.autoBind(function() {\n\
var textInput = this.refs.textInput.getDOMNode();\n\
this.props.onCreate(textInput.value);\n\
textInput.value = '';\n\
return false;\n\
}),\n\
render: function() {\n\
return (\n\
<form onSubmit={this.handleSubmit}>\n\
<input type=\"text\" ref=\"textInput\" />\n\
<button>Add</button>\n\
</form>\n\
);\n\
}\n\
});\n\
\n\
var TodoApp = React.createClass({\n\
getInitialState: function() {\n\
return {items: []};\n\
return {items: [], text: ''};\n\
},\n\
onChange: function(e) {\n\
this.setState({text: e.target.value});\n\
},\n\
handleSubmit: function(e) {\n\
e.preventDefault();\n\
var nextItems = this.state.items.concat([this.state.text]);\n\
var nextText = '';\n\
this.setState({items: nextItems, text: nextText});\n\
},\n\
onItemCreate: React.autoBind(function(value) {\n\
this.setState({items: this.state.items.concat([value])});\n\
}),\n\
render: function() {\n\
return (\n\
<div>\n\
<h3>TODO</h3>\n\
<TodoList items={this.state.items} />\n\
<TodoCreate onCreate={this.onItemCreate} />\n\
<form onSubmit={this.handleSubmit}>\n\
<input onChange={this.onChange} value={this.state.text} />\n\
<button>{'Add #' + (this.state.items.length + 1)}</button>\n\
</form>\n\
</div>\n\
);\n\
}\n\
});\n\
\n\
React.renderComponent(<TodoApp />, mountNode);\
";

View File

@@ -24,7 +24,7 @@ var CodeMirrorEditor = React.createClass({
matchBrackets: true,
theme: 'solarized-light'
});
this.editor.on('change', this.onChange.bind(this));
this.editor.on('change', this.onChange);
this.onChange();
},
onChange: function() {
@@ -40,7 +40,7 @@ var CodeMirrorEditor = React.createClass({
if (IS_MOBILE) {
editor = <pre style={{overflow: 'scroll'}}>{this.props.codeText}</pre>;
} else {
editor = <textarea ref="editor">{this.props.codeText}</textarea>;
editor = <textarea ref="editor" defaultValue={this.props.codeText} />;
}
return (

View File

@@ -10,6 +10,7 @@
<meta property="og:url" content="http://facebook.github.io/react{{ page.url }}" />
<meta property="og:image" content="http://facebook.github.io/react/img/logo_og.png" />
<meta property="og:description" content="A JavaScript library for building user interfaces" />
<meta property="fb:app_id" content="623268441017527" />
<link rel="shortcut icon" href="/react/favicon.ico">
<link rel="alternate" type="application/rss+xml" title="{{ site.name }}" href="{{ site.url }}{{ site.baseurl }}/feed.xml">
@@ -35,7 +36,7 @@
<div class="nav-main">
<div class="wrap">
<a class="nav-home" href="/react/index.html">
<img class="nav-logo" alt="" src="/react/img/logo_small.png">
<img class="nav-logo" alt="" src="/react/img/logo_small.png" width="38" height="38">
React
</a>
<ul class="nav-site">
@@ -72,6 +73,7 @@
<div class="right">&copy; 2013 Facebook Inc.</div>
</footer>
</div>
<div id="fb-root"></div>
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
@@ -79,7 +81,16 @@
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-41298772-1', 'facebook.github.io');
ga('send', 'pageview');
!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="https://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");
(function(d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return;
js = d.createElement(s); js.id = id;
js.src = "//connect.facebook.net/en_US/all.js#xfbml=1&appId=623268441017527";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
</script>
</body>
</html>

View File

@@ -19,5 +19,7 @@ sectionid: docs
<a class="docs-next" href="/react/docs/{{ page.next }}">Next &rarr;</a>
{% endif %}
</div>
<div class="fb-comments" data-width="650" data-num-posts="10" data-href="{{ site.url }}{{ site.baseurl }}{{ page.url }}"></div>
</div>
</section>

View File

@@ -3,7 +3,7 @@ layout: default
sectionid: blog
---
<section class="content wrap documentationContent">
<section class="content wrap blogContent">
{% include nav_blog.html %}
<div class="inner-content">
<h1>{{ page.title }}</h1>
@@ -14,5 +14,8 @@ sectionid: blog
<div class="post">
{{ content }}
</div>
<div class="fb-like" data-send="true" data-width="650" data-show-faces="false"></div>
<div class="fb-comments" data-width="650" data-num-posts="10" data-href="{{ site.url }}{{ site.baseurl }}{{ page.url }}"></div>
</div>
</section>

View File

@@ -0,0 +1,6 @@
<html>
<head>
<meta http-equiv="refresh" content="0; {{ page.destination }}">
</head>
<body></body>
</html>

View File

@@ -0,0 +1,17 @@
require 'redcarpet'
require 'sanitize'
# Simple converter that is probably better than RedCarpet's built in TOC id
# generator (which ends up with things lik id="toc_1"... terrible).
class Redcarpet::Render::HTML
def header(title, level)
clean_title = Sanitize.clean(title)
.downcase
.gsub(/\s+/, "-")
.gsub(/[^A-Za-z0-9\-_.]/, "")
return "<h#{level} id=\"#{clean_title}\">#{title}</h#{level}>"
end
end

View File

@@ -20,8 +20,8 @@ These templates dictate the full set of abstractions that you are allowed to use
to build your UI.
React approaches building user interfaces differently by breaking them into
**components**. This means React uses JavaScript to generate markup, which we
see as an advantage over templates for a few reasons:
**components**. This means React uses a real, full featured programming language
to render views, which we see as an advantage over templates for a few reasons:
- **JavaScript is a flexible, powerful programming language** with the ability
to build abstractions. This is incredibly important in large applications.

View File

@@ -0,0 +1,48 @@
---
title: "Community Round-up #1"
layout: post
author: Vjeux
---
React was open sourced two weeks ago and it's time for a little round-up of what has been going on.
## Khan Academy Question Editor
It looks like [Ben Alpert](http://benalpert.com/) is the first person outside of Facebook and Instagram to push React code to production. We are very grateful for his contributions in form of pull requests, bug reports and presence on IRC ([#reactjs on Freenode](irc://chat.freenode.net/reactjs)). Ben wrote about his experience using React:
> I just rewrote a 2000-line project in React and have now made a handful of pull requests to React. Everything about React I've seen so far seems really well thought-out and I'm proud to be the first non-FB/IG production user of React.
>
> The project that I rewrote in React (and am continuing to improve) is the Khan Academy question editor which content creators can use to enter questions and hints that will be presented to students:
> <figure>[![](/react/img/blog/khan-academy-editor.png)](http://benalpert.com/2013/06/09/using-react-to-speed-up-khan-academy.html)</figure>
>
> [Read the full post...](http://benalpert.com/2013/06/09/using-react-to-speed-up-khan-academy.html)
## Pimp my Backbone.View (by replacing it with React)
[Paul Seiffert](https://blog.mayflower.de/) wrote a blog post that explains how to integrate React into Backbone applications.
> React has some interesting concepts for JavaScript view objects that can be used to eliminate this one big problem I have with Backbone.js.
>
> As in most MVC implementations (although React is probably just a VC implementation), a view is one portion of the screen that is managed by a controlling object. This object is responsible for deciding when to re-render the view and how to react to user input. With React, these view-controllers objects are called components. A component knows how to render its view and how to handle to the user's interaction with it.
>
> The interesting thing is that React is figuring out by itself when to re-render a view and how to do this in the most efficient way.
>
> [Read the full post...](https://blog.mayflower.de/3937-Backbone-React.html)
## Using facebook's React with require.js
[Mario Mueller](http://blog.xenji.com/) wrote a menu component in React and was able to easily integrate it with require.js, EventEmitter2 and bower.
> I recently stumbled upon facebook's React library, which is a Javascript library for building reusable frontend components. Even if this lib is only at version 0.3.x it behaves very stable, it is fast and is fun to code. I'm a big fan of require.js, so I tried to use React within the require.js eco system. It was not as hard as expected and here are some examples and some thoughts about it.
>
> [Read the full post...](http://blog.xenji.com/2013/06/facebooks-react-require-js.html)
## Origins of React
[Pete Hunt](http://www.petehunt.net/blog/) explained what differentiates React from other JavaScript libraries in [a previous blog post](http://facebook.github.io/react/blog/2013/06/05/why-react.html). [Lee Byron](http://leebyron.com/) gives another perspective on Quora:
> React isn't quite like any other popular Javascript libraries, and it solves a very specific problem: complex UI rendering. It's also intended to be used along side many other popular libraries. For example, React works well with Backbone.js, amongst many others.
>
> React was born out of frustrations with the common pattern of writing two-way data bindings in complex MVC apps. React is an implementation of one-way data bindings.
>
> [Read the full post...](http://www.quora.com/React-JS-Library/How-is-Facebooks-React-JavaScript-library/answer/Lee-Byron?srid=3DcX)

View File

@@ -0,0 +1,71 @@
---
title: "Community Round-up #2"
layout: post
author: Vjeux
---
Since the launch we have received a lot of feedback and are actively working on React 0.4. In the meantime, here are the highlights of this week.
## Some quick thoughts on React
[Andrew Greig](http://www.andrewgreig.com/) made a blog post that gives a high level description of what React is.
> I have been using Facebooks recently released Javascript framework called React.js for the last few days and have managed to obtain a rather high level understanding of how it works and formed a good perspective on how it fits in to the entire javascript framework ecosystem.
>
> Basically, React is not an MVC framework. It is not a replacement for Backbone or Knockout or Angular, instead it is designed to work with existing frameworks and help extend their functionality.
>
> It is designed for building big UIs. The type where you have lots of reusable components that are handling events and presenting and changing some backend data. In a traditional MVC app, React fulfils the role of the View. So you would still need to handle the Model and Controller on your own.
>
> I found the best way to utilise React was to pair it with Backbone, with React replacing the Backbone View, or to write your own Model/Data object and have React communicate with that.
>
> [Read the full post...](http://www.andrewgreig.com/637/)
## React and Socket.IO Chat Application
[Danial Khosravi](http://danialk.github.io/) made a real-time chat application that interacts with the back-end using Socket.IO.
> A week ago I was playing with AngularJS and [this little chat application](https://github.com/btford/angular-socket-io-im) which uses socket.io and nodejs for realtime communication. Yesterday I saw a post about ReactJS in [EchoJS](http://www.echojs.com/) and started playing with this UI library. After playing a bit with React, I decided to write and chat application using React and I used Bran Ford's Backend for server side of this little app.
> <figure>[![](/react/img/blog/chatapp.png)](http://danialk.github.io/blog/2013/06/16/reactjs-and-socket-dot-io-chat-application/)</figure>
>
> [Read the full post...](http://danialk.github.io/blog/2013/06/16/reactjs-and-socket-dot-io-chat-application/)
## React and Other Frameworks
[Pete Hunt](http://www.petehunt.net/blog/) wrote an answer on Quora comparing React and Angular directives. At the end, he explains how you can make an Angular directive that is in fact being rendered with React.
> To set the record straight: React components are far more powerful than Angular templates; they should be compared with Angular's directives instead. So I took the first Google hit for "AngularJS directive tutorial" (AngularJS Directives Tutorial - Fundoo Solutions), rewrote it in React and compared them. [...]
>
> We've designed React from the beginning to work well with other libraries. Angular is no exception. Let's take the original Angular example and use React to implement the fundoo-rating directive.
>
> [Read the full post...](http://www.quora.com/Pete-Hunt/Posts/Facebooks-React-vs-AngularJS-A-Closer-Look)
In the same vein, [Markov Twain](https://twitter.com/markov_twain/status/345702941845499906) re-implemented the examples on the front-page [with Ember](http://jsbin.com/azihiw/2/edit) and [Vlad Yazhbin](https://twitter.com/vla) re-implemented the tutorial [with Angular](http://jsfiddle.net/vla/Cdrse/).
## Web Components: React & x-tags
Mozilla and Google are actively working on Web Components. [Vjeux](http://blog.vjeux.com/) wrote a proof of concept that shows how to implement them using React.
> Using [x-tags](http://www.x-tags.org/) from Mozilla, we can write custom tags within the DOM. This is a great opportunity to be able to write reusable components without being tied to a particular library. I wrote [x-react](https://github.com/vjeux/react-xtags/) to have them being rendered in React.
> <figure>[![](/react/img/blog/xreact.png)](http://blog.vjeux.com/2013/javascript/custom-components-react-x-tags.html)</figure>
>
> [Read the full post...](http://blog.vjeux.com/2013/javascript/custom-components-react-x-tags.html)
## React TodoMVC Example
[TodoMVC.com](http://todomvc.com/) is a website that collects various implementations of the same basic Todo app. [Pete Hunt](http://www.petehunt.net/blog/) wrote an idiomatic React version.
> Developers these days are spoiled with choice when it comes to selecting an MV* framework for structuring and organizing their JavaScript web apps.
>
> To help solve this problem, we created TodoMVC - a project which offers the same Todo application implemented using MV* concepts in most of the popular JavaScript MV* frameworks of today.
> <figure>[![](/react/img/blog/todomvc.png)](http://todomvc.com/labs/architecture-examples/react/)</figure>
>
> [Read the source code...](https://github.com/tastejs/todomvc/tree/gh-pages/labs/architecture-examples/react)
## JSX is not HTML
Many of you pointed out differences between JSX and HTML. In order to clear up some confusion, we have added some documentation that covers the four main differences:
- [Whitespace removal](http://facebook.github.io/react/docs/jsx-is-not-html.html)
- [HTML Entities](http://facebook.github.io/react/docs/jsx-is-not-html.html)
- [Comments](http://facebook.github.io/react/docs/jsx-is-not-html.html)
- [Custom HTML Attributes](http://facebook.github.io/react/docs/jsx-is-not-html.html)

View File

@@ -0,0 +1,24 @@
---
title: "React v0.3.3"
layout: post
author: Paul O'Shannessy
---
We have a ton of great stuff coming in v0.4, but in the meantime we're releasing v0.3.3. This release addresses some small issues people were having and simplifies our tools to make them easier to use.
## react-tools
* Upgrade Commoner so `require` statements are no longer relativized when passing through the transformer. This was a feature needed when building React, but doesn't translate well for other consumers of `bin/jsx`.
* Upgraded our dependencies on Commoner and Recast so they use a different directory for their cache.
* Freeze our esprima dependency.
## React
* Allow reusing the same DOM node to render different components. e.g. `React.renderComponent(<div/>, domNode); React.renderComponent(<span/>, domNode);` will work now.
## JSXTransformer
* Improved the in-browser transformer so that transformed scripts will execute in the expected scope. The allows components to be defined and used from separate files.

View File

@@ -0,0 +1,91 @@
---
title: "Community Round-up #3"
layout: post
author: Vjeux
---
The highlight of this week is that an interaction-heavy app has been ported to React. React components are solving issues they had with nested views.
## Moving From Backbone To React
[Clay Allsopp](http://twitter.com/clayallsopp) successfully ported [Propeller](http://usepropeller.com/blog/posts/from-backbone-to-react/), a fairly big, interaction-heavy JavaScript app, to React.
> [<img style="float: right; margin: 0 0 10px 10px;" src="/react/img/blog/propeller-logo.png" />](http://usepropeller.com/blog/posts/from-backbone-to-react/)Subviews involve a lot of easy-to-forget boilerplate that Backbone (by design) doesn't automate. Libraries like Backbone.Marionette offer more abstractions to make view nesting easier, but they're all limited by the fact that Backbone delegates how and went view-document attachment occurs to the application code.
>
> React, on the other hand, manages the DOM and only exposes real nodes at select points in its API. The "elements" you code in React are actually objects which wrap DOM nodes, not the actual objects which get inserted into the DOM. Internally, React converts those abstractions into actual DOMElements and fills out the document accordingly. [...]
>
> We moved about 20 different Backbone view classes to React over the past few weeks, including the live-preview pane that you see in our little iOS demo. Most importantly, it's allowed us to put energy into making each component work great on its own, instead of spending extra cycles to ensure they function in unison. For that reason, we think React is a more scalable way to build view-intensive apps than Backbone alone, and it doesn't require you to drop-everything-and-refactor like a move to Ember or Angular would demand.
>
> [Read the full post...](http://usepropeller.com/blog/posts/from-backbone-to-react/)
## Grunt Task for JSX
[Eric Clemmons](http://ericclemmons.github.io/) wrote a task for [Grunt](http://gruntjs.com/) that applies the JSX transformation to your Javascript files. It also works with [Browserify](http://browserify.org/) if you want all your files to be concatenated and minified together.
> Grunt task for compiling Facebook React's .jsx templates into .js
>
> ```javascript
grunt.initConfig({
react: {
app: {
options: { extension: 'js' },
files: { 'path/to/output/dir': 'path/to/jsx/templates/dir' }
```
>
> It also works great with `grunt-browserify`!
>
> ```javascript
browserify: {
options: {
transform: [ require('grunt-react').browserify ]
},
app: {
src: 'path/to/source/main.js',
dest: 'path/to/target/output.js'
```
>
> [Check out the project ...](https://github.com/ericclemmons/grunt-react)
## Backbone/Handlebars Nested Views
[Joel Burget](http://joelburget.com/) wrote a blog post talking about the way we would write React-like components in Backbone and Handlebars.
> The problem here is that we're trying to maniplate a tree, but there's a textual layer we have to go through. Our views are represented as a tree - the subviews are children of CommentCollectionView - and they end up as part of a tree in the DOM. But there's a Handlebars layer in the middle (which deals in flat strings), so the hierarchy must be destructed and rebuilt when we render.
>
> What does it take to render a collection view? In the Backbone/Handlebars view of the world you have to render the template (with stubs), render each subview which replaces a stub, and keep a reference to each subview (or anything within the view that could change in the future).
>
> So while our view is conceptually hierarchical, due to the fact that it has to go through a flat textual representation, we need to do a lot of extra work to reassemble that structure after rendering.
>
> [Read the full post...](http://joelburget.com/react/)
## JSRomandie Meetup
[Renault John Lecoultre](https://twitter.com/renajohn/) from [BugBuster](http://www.bugbuster.com) did a React introduction talk at a JS meetup called [JS Romandie](https://twitter.com/jsromandie) last week.
<script async class="speakerdeck-embed" data-id="888a9d50c01b01300df36658d0894ac1" data-ratio="1.33333333333333" src="//speakerdeck.com/assets/embed.js"></script>
## CoffeeScript integration
[Vjeux](http://blog.vjeux.com/) used the fact that JSX is just a syntactic sugar on-top of regular JS to rewrite the React front-page examples in CoffeeScript.
> Multiple people asked what's the story about JSX and CoffeeScript. There is no JSX pre-processor for CoffeeScript and I'm not aware of anyone working on it. Fortunately, CoffeeScript is pretty expressive and we can play around the syntax to come up with something that is usable.
>
> ```javascript
{div, h3, textarea} = React.DOM
(div {className: 'MarkdownEditor'}, [
(h3 {}, 'Input'),
(textarea {onKeyUp: @handleKeyUp, ref: 'textarea'},
@state.value
)
])
```
>
> [Read the full post...](http://blog.vjeux.com/2013/javascript/react-coffeescript.html)
## Tutorial in Plain Javascript
We've seen a lot of people comparing React with various frameworks. [Ricardo Tomasi](http://ricardo.cc/) decided to re-implement the tutorial without any framework, just plain Javascript.
> Facebook & Instagram launched the React framework and an accompanying tutorial. Developer Vlad Yazhbin decided to rewrite that using AngularJS. The end result is pretty neat, but if you're like me you will not actually appreciate the HTML speaking for itself and doing all the hard work. So let's see what that looks like in plain javascript.
>
> [Read the full post...](http://ricardo.cc/2013/06/07/react-tutorial-rewritten-in-plain-javascript.html)

View File

@@ -0,0 +1,52 @@
---
title: "New in React v0.4: Autobind by Default"
layout: post
author: Paul O'Shannessy
---
React v0.4 is very close to completion. As we finish it off, we'd like to share with you some of the major changes we've made since v0.3. This is the first of several posts we'll be making over the next week.
## What is React.autoBind?
If you take a look at most of our current examples, you'll see us using `React.autoBind` for event handlers. This is used in place of `Function.prototype.bind`. Remember that in JS, [function calls are late-bound](http://bonsaiden.github.io/JavaScript-Garden/#function.this). That means that if you simply pass a function around, the `this` used inside won't necessarily be the `this` you expect. `Function.prototype.bind` creates a new, properly bound, function so that when called, `this` is exactly what you expect it to be.
Before we launched React, we would write this:
```js{4}
React.createClass({
onClick: function(event) {/* do something with this */},
render: function() {
return <button onClick={this.onClick.bind(this)} />;
}
});
```
We wrote `React.autoBind` as a way to cache the function creation and save on memory usage. Since `render` can get called multiple times, if you used `this.onClick.bind(this)` you would actually create a new function on each pass. With React v0.3 you were able to write this instead:
```js{2,4}
React.createClass({
onClick: React.autoBind(function(event) {/* do something with this */}),
render: function() {
return <button onClick={this.onClick} />;
}
});
```
## What's Changing in v0.4?
After using `React.autoBind` for a few weeks, we realized that there were very few times that we didn't want that behavior. So we made it the default! Now all methods defined within `React.createClass` will already be bound to the correct instance.
Starting with v0.4 you can just write this:
```js{2,4}
React.createClass({
onClick: function(event) {/* do something with this */},
render: function() {
return <button onClick={this.onClick} />;
}
});
```
For v0.4 we will simply be making `React.autoBind` a no-op — it will just return the function you pass to it. Most likely you won't have to change your code to account for this change, though we encourage you to update. We'll publish a migration guide documenting this and other changes that come along with React v0.4.

View File

@@ -0,0 +1,58 @@
---
title: "Community Round-up #4"
layout: post
author: Vjeux
---
React reconciliation process appears to be very well suited to implement a text editor with a live preview as people at Khan Academy show us.
## Khan Academy
[Ben Kamens](http://bjk5.com/) explains how [Ben Alpert](http://benalpert.com/) and [Joel Burget](http://joelburget.com/) are promoting React inside of [Khan Academy](https://www.khanacademy.org/). They now have three projects in the works using React.
> Recently two Khan Academy devs dropped into our team chat and said they were gonna use React to write a new feature. They even hinted that we may want to adopt it product-wide.
>
> "The library is only a week old. It's a brand new way of thinking about things. We're the first to use it outside of Facebook. Heck, even the React devs were surprised to hear we're using this in production!!!"
>
> [Read the full post...](http://bjk5.com/post/53742233351/getting-your-team-to-adopt-new-technology)
The best part is the demo of how React reconciliation process makes live editing more user-friendly.
> Our renderer, post-React, is on the left. A typical math editor's preview is on the right.
> <figure>[<img src="/react/img/blog/monkeys.gif" width="70%" />](http://bjk5.com/post/53742233351/getting-your-team-to-adopt-new-technology)</figure>
## React Snippets
Over the past several weeks, members of our team, [Pete Hunt](http://www.petehunt.net/) and [Paul O'Shannessy](http://zpao.com/), answered many questions that were asked in the [React group](https://groups.google.com/forum/#!forum/reactjs). They give a good overview of how to integrate React with other libraries and APIs through the use of [Mixins](/react/docs/reusable-components.html) and [Lifecycle Methods](/react/docs/working-with-the-browser.html).
> [Listening Scroll Event](https://groups.google.com/forum/#!topic/reactjs/l6PnP8qbofk)
>
> * [JSFiddle](http://jsfiddle.net/aabeL/1/): Basically I've given you two mixins. The first lets you react to global scroll events. The second is, IMO, much more useful: it gives you scroll start and scroll end events, which you can use with setState() to create components that react based on whether the user is scrolling or not.
>
> [Fade-in Transition](https://groups.google.com/forum/#!topic/reactjs/RVAY_eQmdpo)
>
> * [JSFiddle](http://jsfiddle.net/ufe8k/1/): Creating a new `<FadeInWhenAdded>` component and using jQuery `.fadeIn()` function on the DOM node.
> * [JSFiddle](http://jsfiddle.net/R8f5L/5/): Using CSS transition instead.
>
> [Socket.IO Integration](https://groups.google.com/forum/#!topic/reactjs/pyUZBRWcHB4)
>
> * [Gist](https://gist.github.com/zpao/5686416): The big thing to notice is that my component is pretty dumb (it doesn't have to be but that's how I chose to model it). All it does is render itself based on the props that are passed in. renderOrUpdate is where the "magic" happens.
> * [Gist](https://gist.github.com/petehunt/5687230): This example is doing everything -- including the IO -- inside of a single React component.
> * [Gist](https://gist.github.com/petehunt/5687276): One pattern that we use at Instagram a lot is to employ separation of concerns and consolidate I/O and state into components higher in the hierarchy to keep the rest of the components mostly stateless and purely display.
>
> [Sortable jQuery Plugin Integration](https://groups.google.com/forum/#!topic/reactjs/mHfBGI3Qwz4)
>
> * [JSFiddle](http://jsfiddle.net/LQxy7/): Your React component simply render empty divs, and then in componentDidMount() you call React.renderComponent() on each of those divs to set up a new root React tree. Be sure to explicitly unmountAndReleaseReactRootNode() for each component in componentWillUnmount().
## Introduction to React Screencast
[Pete Hunt](http://www.petehunt.net/) recorded himself implementing a simple `<Blink>` tag in React.
<figure><iframe src="http://player.vimeo.com/video/67248575" width="500" height="340" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe></figure>
## Snake in React
[Tom Occhino](http://tomocchino.com/) implemented Snake in 150 lines with React.
> [Check the source on Github](https://github.com/tomocchino/react-snake/blob/master/src/snake.js)
> <figure>[![](/react/img/blog/snake.png)](http://tomocchino.github.io/react-snake/)</figure>

View File

@@ -0,0 +1,63 @@
---
title: "New in React v0.4: Prop Validation and Default Values"
layout: post
author: Paul O'Shannessy
---
Many of the questions we got following the public launch of React revolved around `props`, specifically that people wanted to do validation and to make sure their components had sensible defaults.
## Validation
Oftentimes you want to validate your `props` before you use them. Perhaps you want to ensure they are a specific type. Or maybe you want to restrict your prop to specific values. Or maybe you want to make a specific prop required. This was always possible — you could have written validations in your `render` or `componentWillReceiveProps` functions, but that gets clunky fast.
React v0.4 will provide a nice easy way for you to use built-in validators, or to even write your own.
```js
React.createClass({
propTypes: {
// An optional string prop named "description".
description: React.PropTypes.string,
// A required enum prop named "category".
category: React.PropTypes.oneOf(['News','Photos']).isRequired,
// A prop named "dialog" that requires an instance of Dialog.
dialog: React.PropTypes.instanceOf(Dialog).isRequired
},
...
});
```
## Default Values
One common pattern we've seen with our React code is to do something like this:
```js
React.createClass({
render: function() {
var value = this.props.value || 'default value';
return <div>{value}</div>;
}
});
```
Do this for a few `props` across a few components and now you have a lot of redundant code. Starting with React v0.4, you can provide default values in a declarative way:
```js
React.createClass({
getDefaultProps: function() {
return {
value: 'default value'
};
}
...
});
```
We will use the cached result of this function before each `render`. We also perform all validations before each `render` to ensure that you have all of the data you need in the right form before you try to use it.
- - -
Both of these features are entirely optional. We've found them to be increasingly valuable at Facebook as our applications grow and evolve, and we hope others find them useful as well.

View File

@@ -0,0 +1,40 @@
---
title: "React v0.4.0"
layout: post
author: Paul O'Shannessy
---
Over the past 2 months we've been taking feedback and working hard to make React even better. We fixed some bugs, made some under-the-hood improvements, and added several features that we think will improve the experience developing with React. Today we're proud to announce the availability of React v0.4!
This release could not have happened without the support of our growing community. Since launch day, the community has contributed blog posts, questions to the [Google Group](http://groups.google.com/group/reactjs), and issues and pull requests on GitHub. We've had contributions ranging from documentation improvements to major changes to React's rendering. We've seen people integrate React into the tools they're using and the products they're building, and we're all very excited to see what our budding community builds next!
React v0.4 has some big changes. We've also restructured the documentation to better communicate how to use React. We've summarized the changes below and linked to documentation where we think it will be especially useful.
When you're ready, [go download it](/react/downloads.html)!
### React
* Switch from using `id` attribute to `data-reactid` to track DOM nodes. This allows you to integrate with other JS and CSS libraries more easily.
* Support for more DOM elements and attributes (e.g., `<canvas>`)
* Improved server-side rendering APIs. `React.renderComponentToString(<component>, callback)` allows you to use React on the server and generate markup which can be sent down to the browser.
* `prop` improvements: validation and default values. [Read our blog post for details...](http://facebook.github.io/react/blog/2013/07/11/react-v0-4-prop-validation-and-default-values.html)
* Support for the `key` prop, which allows for finer control over reconciliation. [Read the docs for details...](http://facebook.github.io/react/docs/multiple-components.html)
* Removed `React.autoBind`. [Read our blog post for details...](http://facebook.github.io/react/blog/2013/07/02/react-v0-4-autobind-by-default.html)
* Improvements to forms. We've written wrappers around `<input>`, `<textarea>`, `<option>`, and `<select>` in order to standardize many inconsistencies in browser implementations. This includes support for `defaultValue`, and improved implementation of the `onChange` event, and circuit completion. [Read the docs for details...](http://facebook.github.io/react/docs/forms.html)
* We've implemented an improved synthetic event system that conforms to the W3C spec.
* Updates to your component are batched now, which may result in a significantly faster re-render of components. `this.setState` now takes an optional callback as its second parameter. If you were using `onClick={this.setState.bind(this, state)}` previously, you'll want to make sure you add a third parameter so that the event is not treated as the callback.
### JSX
* Support for comment nodes `<div>{/* this is a comment and won't be rendered */}</div>`
* Children are now transformed directly into arguments instead of being wrapped in an array
E.g. `<div><Component1/><Component2/></div>` is transformed into `React.DOM.div(null, Component1(null), Component2(null))`.
Previously this would be transformed into `React.DOM.div(null, [Component1(null), Component2(null)])`.
If you were using React without JSX previously, your code should still work.
### react-tools
* Fixed a number of bugs when transforming directories
* No longer re-write `require()`s to be relative unless specified

View File

@@ -0,0 +1,99 @@
---
title: "Community Round-up #5"
layout: post
author: Vjeux
---
We launched the [React Facebook Page](https://www.facebook.com/react) along with the React v0.4 launch. 700 people already liked it to get updated on the project :)
## Cross-browser onChange
[Ben Alpert](http://benalpert.com/) from [Khan Academy](https://www.khanacademy.org/) worked on a cross-browser implementation of `onChange` event that landed in v0.4. He wrote a blog post explaining the various browser quirks he had to deal with.
> First off, what is the input event? If you have an `<input>` element and want to receive events whenever the value changes, the most obvious thing to do is to listen to the change event. Unfortunately, change fires only after the text field is defocused, rather than on each keystroke. The next obvious choice is the keyup event, which is triggered whenever a key is released. Unfortunately, keyup doesn't catch input that doesn't involve the keyboard (e.g., pasting from the clipboard using the mouse) and only fires once if a key is held down, rather than once per inserted character.
>
> Both keydown and keypress do fire repeatedly when a key is held down, but both fire immediately before the value changes, so to read the new value you have to defer the handler to the next event loop using `setTimeout(fn, 0)` or similar, which slows down your app. Of course, like keyup, neither keydown nor keypress fires for non-keyboard input events, and all three can fire in cases where the value doesn't change at all (such as when pressing the arrow keys).
>
> [Read the full post...](http://benalpert.com/2013/06/18/a-near-perfect-oninput-shim-for-ie-8-and-9.html)
## React Samples
Learning a new library is always easier when you have working examples you can play with. [jwh](https://github.com/jhw) put many of them on his [react-samples Github repo](https://github.com/jhw/react-samples).
> Some simple examples with Facebook's React framework
>
> * Bootstrap action bar, modal and table [#1](https://rawgithub.com/jhw/react-samples/master/html/actionbar.html),
> [#2](https://rawgithub.com/jhw/react-samples/master/html/bootstrap_actionbar.html),
> [#3](https://rawgithub.com/jhw/react-samples/master/html/bootstrap_modal.html),
> [#4](https://rawgithub.com/jhw/react-samples/master/html/bootstrap_striped_table.html)
> * Comments [#1](https://rawgithub.com/jhw/react-samples/master/html/comments1.html),
> [#2](https://rawgithub.com/jhw/react-samples/master/html/comments2.html)
> * Data Table [#1](https://rawgithub.com/jhw/react-samples/master/html/datatable.html),
> [#2](https://rawgithub.com/jhw/react-samples/master/html/datatable2.html),
> [#3](https://rawgithub.com/jhw/react-samples/master/html/datatable3.html),
> [#4](https://rawgithub.com/jhw/react-samples/master/html/datatable4.html),
> [#5](https://rawgithub.com/jhw/react-samples/master/html/datatable5.html)
> * Filter Bar [#1](https://rawgithub.com/jhw/react-samples/master/html/filterbar.html),
> [#2](https://rawgithub.com/jhw/react-samples/master/html/filterbar2.html),
> [#3](https://rawgithub.com/jhw/react-samples/master/html/filterbar3.html),
> [#4](https://rawgithub.com/jhw/react-samples/master/html/filterbar4.html),
> [#5](https://rawgithub.com/jhw/react-samples/master/html/filterbar5.html)
> * Fundoo Rating [#1](https://rawgithub.com/jhw/react-samples/master/html/fundoo.html)
> * Line Char: [#1](https://rawgithub.com/jhw/react-samples/master/html/linechart.html),
> [#2](https://rawgithub.com/jhw/react-samples/master/html/linechart2.html)
> * Multi tabs [#1](https://rawgithub.com/jhw/react-samples/master/html/multitabs.html)
> * Select [#1](https://rawgithub.com/jhw/react-samples/master/html/select.html)
> * Simple Tabs [#1](https://rawgithub.com/jhw/react-samples/master/html/simpletabs.html),
> [#2](https://rawgithub.com/jhw/react-samples/master/html/simpletabs2.html),
> [#3](https://rawgithub.com/jhw/react-samples/master/html/simpletabs3.html),
> [#4](https://rawgithub.com/jhw/react-samples/master/html/simpletabs4.html)
> * Toggle [#1](https://rawgithub.com/jhw/react-samples/master/html/toggle.html)
## React Chosen Wrapper
[Cheng Lou](https://github.com/chenglou) wrote a wrapper for the [Chosen](http://harvesthq.github.io/chosen/) input library called [react-chosen](https://github.com/chenglou/react-chosen). It took just 25 lines to be able to use jQuery component as a React one.
```javascript
React.renderComponent(
<Chosen noResultsText="No result" value="Harvest" onChange={doSomething}>
<option value="Facebook">Facebook</option>
<option value="Harvest">Harvest</option>
</Chosen>
, document.body);
```
## JSX and ES6 Template Strings
[Domenic Denicola](http://domenicdenicola.com/) wrote a slide deck about the great applications of ES6 features and one slide shows how we could use Template Strings to compile JSX at run-time without the need for a pre-processing phase.
<figure><iframe src="http://www.slideshare.net/slideshow/embed_code/24187146?rel=0&startSlide=36" width="600" height="356" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC;border-width:1px 1px 0;margin-bottom:5px" allowfullscreen webkitallowfullscreen mozallowfullscreen> </iframe></figure>
## React Presentation
[Tom Occhino](http://tomocchino.com/) and [Jordan Walke](https://github.com/jordwalke), React developers, did a presentation of React at Facebook Seattle's office. Check out the first 25 minutes for the presentation and the remaining 45 for a Q&A. I highly recommend you watching this video.
<figure><iframe width="650" height="400" src="//www.youtube.com/embed/XxVg_s8xAms" frameborder="0" allowfullscreen></iframe></figure>
## Docs
[Pete Hunt](http://www.petehunt.net/) rewrote the entirety of the docs for v0.4. The goal was to add more explanation about why we built React and what the best practices are.
> Guides
>
> * [Why React?](/react/docs/why-react.html)
> * [Displaying Data](/react/docs/displaying-data.html)
> * [JSX in Depth](/react/docs/jsx-in-depth.html)
> * [JSX Gotchas](/react/docs/jsx-gotchas.html)
> * [Interactivity and Dynamic UIs](/react/docs/interactivity-and-dynamic-uis.html)
> * [Multiple Components](/react/docs/multiple-components.html)
> * [Reusable Components](/react/docs/reusable-components.html)
> * [Forms](/react/docs/forms.html)
> * [Working With the Browser](/react/docs/working-with-the-browser.html)
> * [More About Refs](/react/docs/more-about-refs.html)
> * [Tooling integration](/react/docs/tooling-integration.html)
> * [Reference](/react/docs/top-level-api.html)

View File

@@ -0,0 +1,25 @@
---
title: "React v0.4.1"
layout: post
author: Paul O'Shannessy
---
React v0.4.1 is a small update, mostly containing correctness fixes. Some code has been restructured internally but those changes do not impact any of our public APIs.
## React
* `setState` callbacks are now executed in the scope of your component.
* `click` events now work on Mobile Safari.
* Prevent a potential error in event handling if `Object.prototype` is extended.
* Don't set DOM attributes to the string `"undefined"` on update when previously defined.
* Improved support for `<iframe>` attributes.
* Added checksums to detect and correct cases where server-side rendering markup mismatches what React expects client-side.
## JSXTransformer
* Improved environment detection so it can be run in a non-browser environment.
[Download it now!](/react/downloads.html)

View File

@@ -0,0 +1,54 @@
---
title: "Use React and JSX in Ruby on Rails"
layout: post
author: Paul O'Shannessy
---
Today we're releasing a gem to make it easier to use React and JSX in Ruby on Rails applications: [react-rails](https://github.com/facebook/react-rails).
This gem has 2 primary purposes:
1. To package `react.js` in a way that's easy to use and easy to update.
2. To allow you to write JSX without an external build step to transform that into JS.
## Packaging react.js
To make `react.js` available for use client-side, simply add `react` to your manifest, and declare the variant you'd like to use in your environment. When you use `:production`, the minified and optimized `react.min.js` will be used instead of the development version. For example:
```ruby
# config/environments/development.rb
MyApp::Application.configure do
config.react.variant = :development
# use :production in production.rb
end
```
```js
// app/assets/javascript/application.js
//= require react
```
## Writing JSX
When you name your file with `myfile.js.jsx`, `react-rails` will automatically try to transform that file. For the time being, we still require that you include the docblock at the beginning of the file. For example, this file will get transformed on request.
```js
/** @jsx React.DOM */
React.renderComponent(<MyComponent/>, document.body)
```
## Asset Pipeline
`react-rails` takes advantage of the [asset pipeline](http://guides.rubyonrails.org/asset_pipeline.html) that was introduced in Rails 3.1. A very important part of that pipeline is the `assets:precompile` Rake task. `react-rails` will ensure that your JSX files will be transformed into regular JS before all of your assets are minified and packaged.
## Installation
Installation follows the same process you're familiar with. You can install it globally with `gem install react-rails`, though we suggest you add the dependency to your `Gemfile` directly.

View File

@@ -0,0 +1,80 @@
---
title: "Community Round-up #6"
layout: post
author: Vjeux
---
This is the first Community Round-up where none of the items are from Facebook/Instagram employees. It's great to see the adoption of React growing.
## React Game Tutorial
[Caleb Cassel](https://twitter.com/CalebCassel) wrote a [step-by-step tutorial](https://rawgithub.com/calebcassel/react-demo/master/part1.html) about making a small game. It covers JSX, State and Events, Embedded Components and Integration with Backbone.
<figure>[![](/react/img/blog/dog-tutorial.png)](https://rawgithub.com/calebcassel/react-demo/master/part1.html)</figure>
## Reactify
[Andrey Popp](http://andreypopp.com/) created a [Browserify](http://browserify.org/) helper to compile JSX files.
> Browserify v2 transform for `text/jsx`. Basic usage is:
>
> ```
% browserify -t reactify main.jsx
```
>
> `reactify` transform activates for files with either `.jsx` extension or `/** @jsx React.DOM */` pragma as a first line for any `.js` file.
>
> [Check it out on Github...](https://github.com/andreypopp/reactify)
## React Integration with Este
[Daniel Steigerwald](http://daniel.steigerwald.cz/) is now using React within [Este](https://github.com/steida/este), which is a development stack for web apps in CoffeeScript that are statically typed using the Closure Library.
```coffeescript
este.demos.react.todoApp = este.react.create (`/** @lends {React.ReactComponent.prototype} */`)
render: ->
@div [
este.demos.react.todoList 'items': @state['items']
if @state['items'].length
@p "#{@state['items'].length} items."
@form 'onSubmit': @onFormSubmit, [
@input
'onChange': @onChange
'value': @state['text']
'autoFocus': true
'ref': 'textInput'
@button "Add ##{@state['items'].length + 1}"
]
]
```
[Check it out on Github...](https://github.com/steida/este-library/blob/master/este/demos/thirdparty/react/start.coffee)
## React Stylus Boilerplate
[Zaim Bakar](http://zaim.github.io/) shared his boilerplate to get started with Stylus CSS processor.
> This is my boilerplate React project using Grunt as the build tool, and Stylus as my CSS preprocessor.
>
> - Very minimal HTML boilerplate
> - Uses Stylus, with nib included
> - Uses two build targets:
> - `grunt build` to compile JSX and Stylus into a development build
> - `grunt dist` to minify and optimize the development build for production
>
> [Check it out on Github...](https://github.com/zaim/react-stylus-boilerplate)
## WebFUI
[Conrad Barski](http://lisperati.com/), author of the popular book [Land of Lisp](http://landoflisp.com/), wants to use React for his ClojureScript library called [WebFUI](https://github.com/drcode/webfui).
> I'm the author of "[Land of Lisp](http://landoflisp.com/)" and I love your framework. I built a somewhat similar framework a year ago [WebFUI](https://github.com/drcode/webfui) aimed at ClojureScript. My framework also uses global event delegates, a global "render" function, DOM reconciliation, etc just like react.js. (Of course these ideas all have been floating around the ether for ages, always great to see more people building on them.)
>
> Your implementation is more robust, and so I think the next point release of webfui will simply delegate all the "hard work" to react.js and will only focus on the areas where it adds value (enabling purely functional UI programming in clojurescript, and some other stuff related to streamlining event handling)
<figure>[![](/react/img/blog/landoflisp.png)](https://groups.google.com/forum/#!msg/reactjs/e3bYersyd64/qODfcuBR9LwJ)</figure>
>
> [Read the full post...](https://groups.google.com/forum/#!msg/reactjs/e3bYersyd64/qODfcuBR9LwJ)

View File

@@ -0,0 +1,56 @@
---
title: "Use React and JSX in Python Applications"
layout: post
author: Kunal Mehta
---
Today we're happy to announce the initial release of [PyReact](https://github.com/facebook/react-python), which makes it easier to use React and JSX in your Python applications. It's designed to provide an API to transform your JSX files into JavaScript, as well as provide access to the latest React source files.
## Usage
Transform your JSX files via the provided `jsx` module:
```python
from react import jsx
# For multiple paths, use the JSXTransformer class.
transformer = jsx.JSXTransformer()
for jsx_path, js_path in my_paths:
transformer.transform(jsx_path, js_path)
# For a single file, you can use a shortcut method.
jsx.transform('path/to/input/file.jsx', 'path/to/output/file.js')
```
For full paths to React files, use the `source` module:
```python
from react import source
# path_for raises IOError if the file doesn't exist.
react_js = source.path_for('react.min.js')
```
## Django
PyReact includes a JSX compiler for [django-pipeline](https://github.com/cyberdelia/django-pipeline). Add it to your project's pipeline settings like this:
```python
PIPELINE_COMPILERS = (
'react.utils.pipeline.JSXCompiler',
)
```
## Installation
PyReact is hosted on PyPI, and can be installed with `pip`:
$ pip install PyReact
Alternatively, add it into your `requirements` file:
PyReact==0.1.1
**Dependencies**: PyReact uses [PyExecJS](https://github.com/doloopwhile/PyExecJS) to execute the bundled React code, which requires that a JS runtime environment is installed on your machine. We don't explicitly set a dependency on a runtime environment; Mac OS X comes bundled with one. If you're on a different platform, we recommend [PyV8](https://code.google.com/p/pyv8/).
For the initial release, we've only tested on Python 2.7. Look out for support for Python 3 in the future, and if you see anything that can be improved, we welcome your [contributions](https://github.com/facebook/react-python/blob/master/CONTRIBUTING.md)!

View File

@@ -0,0 +1,74 @@
---
title: "Community Round-up #7"
layout: post
author: Vjeux
---
It's been three months since we open sourced React and it is going well. Some stats so far:
* 114 285 unique visitors on this website
* [1933 stars](https://github.com/facebook/react/stargazers) and [210 forks](https://github.com/facebook/react/network/members)
* [226 posts on Google Group](https://groups.google.com/forum/#!forum/reactjs)
* [76 Github projects using React](https://gist.github.com/vjeux/6335762)
* [30 contributors](https://github.com/facebook/react/graphs/contributors)
* [15 blog posts](http://facebook.github.io/react/blog/)
* 2 early adopters: [Khan Academy](http://benalpert.com/2013/06/09/using-react-to-speed-up-khan-academy.html) and [Propeller](http://usepropeller.com/blog/posts/from-backbone-to-react/)
## Wolfenstein Rendering Engine Ported to React
[Pete Hunt](http://www.petehunt.net/) ported the render code of the web version of Wolfenstein 3D to React. Check out [the demo](http://www.petehunt.net/wolfenstein3D-react/wolf3d.html) and [render.js](https://github.com/petehunt/wolfenstein3D-react/blob/master/js/renderer.js#L183) file for the implementation.
<figure>[![](/react/img/blog/wolfenstein_react.png)](http://www.petehunt.net/wolfenstein3D-react/wolf3d.html)</figure>
## React & Meteor
[Ben Newman](https://twitter.com/benjamn) made a [13-lines wrapper](https://github.com/benjamn/meteor-react/blob/master/lib/mixin.js) to use React and Meteor together. [Meteor](http://www.meteor.com/) handles the real-time data synchronization between client and server. React provides the declarative way to write the interface and only updates the parts of the UI that changed.
> This repository defines a Meteor package that automatically integrates the React rendering framework on both the client and the server, to complement or replace the default Handlebars templating system.
>
> The React core is officially agnostic about how you fetch and update your data, so it is far from obvious which approach is the best. This package provides one answer to that question (use Meteor!), and I hope you will find it a compelling combination.
>
>```javascript
>var MyComponent = React.createClass({
> mixins: [MeteorMixin],
>
> getMeteorState: function() {
> return { foo: Session.get('foo') };
> },
>
> render: function() {
> return <div>{this.state.foo}</div>;
> }
>});
>```
>
> Dependencies will be registered for any data accesses performed by getMeteorState so that the component can be automatically re-rendered whenever the data changes.
>
> [Read more ...](https://github.com/benjamn/meteor-react)
## React Page
[Jordan Walke](https://github.com/jordwalke) implemented a complete React project creator called [react-page](https://github.com/facebook/react-page/). It supports both server-side and client-side rendering, source transform and packaging JSX files using CommonJS modules, and instant reload.
> Easy Application Development with React JavaScript
> <figure>[![](/react/img/blog/react-page.png)](https://github.com/facebook/react-page/)</figure>
>
> **Why Server Rendering?**
>
> * Faster initial page speed:
> * Markup displayed before downloading large JavaScript.
> * Markup can be generated more quickly on a fast server than low power client devices.
> * Faster Development and Prototyping:
> * Instantly refresh your app without waiting for any watch scripts or bundlers.
> * Easy deployment of static content pages/blogs: just archive using recursive wget.
> * SEO benefits of indexability and perf.
>
> **How Does Server Rendering Work?**
>
> * `react-page` computes page markup on the server, sends it to the client so the user can see it quickly.
> * The corresponding JavaScript is then packaged and sent.
> * The browser runs that JavaScript, so that all of the event handlers, interactions and update code will run seamlessly on top of the server generated markup.
> * From the developer's (and the user's) perspective, it's just as if the rendering occurred on the client, only faster.
>
> [Try it out ...](https://github.com/facebook/react-page/)

View File

@@ -0,0 +1,70 @@
---
title: "Community Round-up #8"
layout: post
author: Vjeux
---
A lot has happened in the month since our last update. Here are some of the more interesting things we've found. But first, we have a couple updates before we share links.
First, we are organizing a [React Hackathon](http://reactjshack-a-thon.splashthat.com/) in Facebook's Seattle office on Saturday September 28. If you want to hack on React, meet some of the team or win some prizes, feel free to join us!
We've also reached a point where there are too many questions for us to handle directly. We're encouraging people to ask questions on [StackOverflow](http://stackoverflow.com/questions/tagged/reactjs) using the tag [[reactjs]](http://stackoverflow.com/questions/tagged/reactjs). Many members of the team and community have subscribed to the tag, so feel free to ask questions there. We think these will be more discoverable than Google Groups archives or IRC logs.
## Javascript Jabber
[Pete Hunt](http://www.petehunt.net/) and [Jordan Walke](https://github.com/jordwalke) were interviewed on [Javascript Jabber](http://javascriptjabber.com/073-jsj-react-with-pete-hunt-and-jordan-walke/) for an hour. They go over many aspects of React such as 60 FPS, Data binding, Performance, Diffing Algorithm, DOM Manipulation, Node.js support, server-side rendering, JSX, requestAnimationFrame and the community. This is a gold mine of information about React.
> **PETE:** So React was designed all around that. Conceptually, how you build a React app is that every time your data changes, it's like hitting the refresh button in a server-rendered app. What we do is we conceptually throw out all of the markup and event handlers that you've registered and we reset the whole page and then we redraw the entire page. If you're writing a server-rendered app, handling updates is really easy because you hit the refresh button and you're pretty much guaranteed to get what you expect.
>
> **MERRICK:** That's true. You don't get into these odd states.
>
> **PETE:** Exactly, exactly. In order to implement that, we communicate it as a fake DOM. What we'll do is rather than throw out the actual browser html and event handlers, we have an internal representation of what the page looks like and then we generate a brand new representation of what we want the page to look like. Then we perform this really, really fast diffing algorithm between those two page representations, DOM representations. Then React will compute the minimum set of DOM mutations it needs to make to bring the page up to date.
>
> Then to finally get to answer your question, that set of DOM mutations then goes into a queue and we can plug in arbitrary flushing strategies for that. For example, when we originally launched React in open source, every setState would immediately trigger a flush to the DOM. That wasn't part of the contract of setState, but that was just our strategy and it worked pretty well. Then this totally awesome open source contributor Ben Alpert at Khan Academy built a new batching strategy which would basically queue up every single DOM update and state change that happened within an event tick and would execute them in bulk at the end of the event tick.
>
> [Read the full conversation ...](http://javascriptjabber.com/073-jsj-react-with-pete-hunt-and-jordan-walke/)
## JSXTransformer Trick
While this is not going to work for all the attributes since they are camelCased in React, this is a pretty cool trick.
<div style="margin-left: 74px;"><blockquote class="twitter-tweet"><p>Turn any DOM element into a React.js function: JSXTransformer.transform(&quot;/** <a href="https://twitter.com/jsx">@jsx</a> React.DOM */&quot; + element.innerHTML).code</p>&mdash; Ross Allen (@ssorallen) <a href="https://twitter.com/ssorallen/statuses/377105575441489920">September 9, 2013</a></blockquote></div>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
## Remarkable React
[Stoyan Stefanov](http://www.phpied.com/) gave a talk at [BrazilJS](http://braziljs.com.br/) about React and wrote an article with the content of the presentation. He goes through the difficulties of writting _active apps_ using the DOM API and shows how React handles it.
> So how does exactly React deal with it internally? Two crazy ideas - virtual DOM and synthetic events.
>
> You define you components in React. It builds a virtual DOM in JavaScript land which is way more efficient. Then it updates the DOM. (And "virtual DOM" is a very big name for what is simply a JavaScript object with nested key-value pairs)
>
> Data changes. React computes a diff (in JavaScript land, which is, of course, much more efficient) and updates the single table cell that needs to change. React replicates the state of the virtual DOM into the actual DOM only when and where it's necessary. And does it all at once, in most cases in a single tick of the `requestAnimationFrame()`.
>
> What about event handlers? They are synthetic. React uses event delegation to listen way at the top of the React tree. So removing a node in the virtual DOM has no effect on the event handling.
>
> The events are automatically cross-browser (they are React events). They are also much closer to W3C than any browser. That means that for example `e.target` works, no need to look for the event object or checking whether it's `e.target` or `e.srcElement` (IE). Bubbling and capturing phases also work cross browser. React also takes the liberty of making some small fixes, e.g. the event `<input onChange>` fires when you type, not when blur away from the input. And of course, event delegation is used as the most efficient way to handle events. You know that "thou shall use event delegation" is also commonly given advice for making web apps snappy.
>
> The good thing about the virtual DOM is that it's all in JavaScript land. You build all your UI in JavaScript. Which means it can be rendered on the server side, so you initial view is fast (and any SEO concerns are addressed). Also, if there are especially heavy operations they can be threaded into WebWorkers, which otherwise have no DOM access.
>
> [Read More ...](http://www.phpied.com/remarkable-react/)
## Markdown in React
[Ben Alpert](http://benalpert.com/) converted [marked](https://github.com/chjj/marked), a Markdown Javascript implementation, in React: [marked-react](https://github.com/spicyj/marked-react). Even without using JSX, the HTML generation is now a lot cleaner. It is also safer as forgetting a call to `escape` will not introduce an XSS vulnerability.
<figure>[![](/react/img/blog/markdown_refactor.png)](https://github.com/spicyj/marked-react/commit/cb70c9df6542c7c34ede9efe16f9b6580692a457)</figure>
## Unite from BugBusters
[Renault John Lecoultre](https://twitter.com/renajohn) wrote [Unite](https://www.bugbuster.com/), an interactive tool for analyzing code dynamically using React. It integrates with CodeMirror.
<figure>[![](/react/img/blog/unite.png)](https://unite.bugbuster.com/)</figure>
## #reactjs IRC Logs
[Vjeux](http://blog.vjeux.com/) re-implemented the display part of the IRC logger in React. Just 130 lines are needed for a performant infinite scroll with timestamps and color-coded author names.
<iframe width="100%" height="300" src="http://jsfiddle.net/vjeux/QL9tz/embedded/" allowfullscreen="allowfullscreen" frameborder="0"></iframe>

View File

@@ -0,0 +1,52 @@
---
title: "React v0.5"
layout: post
author: Paul O'Shannessy
---
This release is the result of several months of hard work from members of the team and the community. While there are no groundbreaking changes in core, we've worked hard to improve performance and memory usage. We've also worked hard to make sure we are being consistent in our usage of DOM properties.
The biggest change you'll notice as a developer is that we no longer support `class` in JSX as a way to provide CSS classes. Since this prop was being converted to `className` at the transform step, it caused some confusion when trying to access it in composite components. As a result we decided to make our DOM properties mirror their counterparts in the JS DOM API. There are [a few exceptions](https://github.com/facebook/react/blob/master/src/dom/DefaultDOMPropertyConfig.js#L156) where we deviate slightly in an attempt to be consistent internally.
The other major change in v0.5 is that we've added an additional build - `react-with-addons` - which adds support for some extras that we've been working on including animations and two-way binding. [Read more about these addons in the docs](/react/docs/addons.html).
## Thanks to Our Community
We added *22 new people* to the list of authors since we launched React v0.4.1 nearly 3 months ago. With a total of 48 names in our `AUTHORS` file, that means we've nearly doubled the number of contributors in that time period. We've seen the number of people contributing to discussion on IRC, mailing lists, Stack Overflow, and GitHub continue rising. We've also had people tell us about talks they've given in their local community about React.
It's been awesome to see the things that people are building with React, and we can't wait to see what you come up with next!
## Changelog
### React
* Memory usage improvements - reduced allocations in core which will help with GC pauses
* Performance improvements - in addition to speeding things up, we made some tweaks to stay out of slow path code in V8 and Nitro.
* Standardized prop -> DOM attribute process. This previously resulting in additional type checking and overhead as well as confusing cases for users. Now we will always convert your value to a string before inserting it into the DOM.
* Support for Selection events.
* Support for [Composition events](https://developer.mozilla.org/en-US/docs/Web/API/CompositionEvent).
* Support for additional DOM properties (`charSet`, `content`, `form`, `httpEquiv`, `rowSpan`, `autoCapitalize`).
* Support for additional SVG properties (`rx`, `ry`).
* Support for using `getInitialState` and `getDefaultProps` in mixins.
* Support mounting into iframes.
* Bug fixes for controlled form components.
* Bug fixes for SVG element creation.
* Added `React.version`.
* Added `React.isValidClass` - Used to determine if a value is a valid component constructor.
* Removed `React.autoBind` - This was deprecated in v0.4 and now properly removed.
* Renamed `React.unmountAndReleaseReactRootNode` to `React.unmountComponentAtNode`.
* Began laying down work for refined performance analysis.
* Better support for server-side rendering - [react-page](https://github.com/facebook/react-page) has helped improve the stability for server-side rendering.
* Made it possible to use React in environments enforcing a strict [Content Security Policy](https://developer.mozilla.org/en-US/docs/Security/CSP/Introducing_Content_Security_Policy). This also makes it possible to use React to build Chrome extensions.
### React with Addons (New!)
* Introduced a separate build with several "addons" which we think can help improve the React experience. We plan to deprecate this in the long-term, instead shipping each as standalone pieces. [Read more in the docs](/react/docs/addons.html).
### JSX
* No longer transform `class` to `className` as part of the transform! This is a breaking change - if you were using `class`, you *must* change this to `className` or your components will be visually broken.
* Added warnings to the in-browser transformer to make it clear it is not intended for production use.
* Improved compatibility for Windows
* Improved support for maintaining line numbers when transforming.

View File

@@ -0,0 +1,100 @@
---
title: "Community Round-up #9"
layout: post
author: Vjeux
---
We organized a React hackathon last week-end in the Facebook Seattle office. 50 people, grouped into 15 teams, came to hack for a day on React. It was a lot of fun and we'll probably organize more in the future.
![](/react/img/blog/react-hackathon.jpg)
## React Hackathon Winner
[Alex Swan](http://bold-it.com/) implemented [Qu.izti.me](http://qu.izti.me/), a multi-player quiz game. It is real-time via Web Socket and mobile friendly.
> The game itself is pretty simple. People join the "room" by going to [http://qu.izti.me](http://qu.izti.me/) on their device. Large displays will show a leaderboard along with the game, and small displays (such as phones) will act as personal gamepads. Users will see questions and a choice of answers. The faster you answer, the more points you earn.
>
> In my opinion, Socket.io and React go together like chocolate and peanut butter. The page was always an accurate representation of the game object.
><figure>[![](/react/img/blog/quiztime.png)](http://bold-it.com/javascript/facebook-react-example/)</figure>
>
> [Read More...](http://bold-it.com/javascript/facebook-react-example/)
## JSConf EU Talk: Rethinking Best Practices
[Pete Hunt](http://www.petehunt.net/) presented React at JSConf EU. He covers three controversial design decisions of React:
1. Build **components**, not templates
2. Re-render the whole app on every update
3. Virtual DOM
The video will be available soon on the [JSConf EU website](http://2013.jsconf.eu/speakers/pete-hunt-react-rethinking-best-practices.html), but in the meantime, here are Pete's slides:
<figure><iframe src="http://www.slideshare.net/slideshow/embed_code/26589373" width="550" height="450" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" allowfullscreen></iframe></figure>
## Pump - Clojure bindings for React
[Alexander Solovyov](http://solovyov.net/) has been working on React bindings for ClojureScript. This is really exciting as it is using "native" ClojureScript data structures.
```ruby
(ns your.app
(:require-macros [pump.def-macros :refer [defr]])
(:require [pump.core]))
(defr Component
:get-initial-state #(identity {:some-value ""})
[component props state]
[:div {:class-name "test"} "hello"])
```
[Check it out on GitHub...](https://github.com/piranha/pump)
## JSXHint
[Todd Kennedy](http://blog.selfassembled.org/) working at [Cond&eacute; Nast](http://www.condenast.com/) implemented a wrapper on-top of [JSHint](http://www.jshint.com/) that first converts JSX files to JS.
> A wrapper around JSHint to allow linting of files containg JSX syntax. Accepts glob patterns. Respects your local .jshintrc file and .gitignore to filter your glob patterns.
>
> ```
npm install -g jsxhint
```
>
> [Check it out on GitHub...](https://github.com/CondeNast/JSXHint)
## Turbo React
[Ross Allen](https://twitter.com/ssorallen) working at [Mesosphere](http://mesosphere.io/) combined [Turbolinks](https://github.com/rails/turbolinks/), a library used by Ruby on Rails to speed up page transition, and React.
> "Re-request this page" is just a link to the current page. When you click it, Turbolinks intercepts the GET request and fetchs the full page via XHR.
>
> The panel is rendered with a random panel- class on each request, and the progress bar gets a random widthX class.
>
> With Turbolinks alone, the entire <body> would be replaced, and transitions would not happen. In this little demo though, React adds and removes classes and text, and the attribute changes are animated with CSS transitions. The DOM is otherwise left intact.
><figure>[![](/react/img/blog/turboreact.png)](https://turbo-react.herokuapp.com/)</figure>
>
> [Check out the demo...](https://turbo-react.herokuapp.com/)
## Reactive Table
[Stoyan Stefanov](http://www.phpied.com/) continues his series of blog posts about React. This one is an introduction tutorial on rendering a simple table with React.
> React is all about components. So let's build one.
>
> Let's call it Table (to avoid any confusion what the component is about).
>
> ```javascript
var Table = React.createClass({
/*stuff goeth here*/
});
```
>
> You see that React components are defined using a regular JS object. Some properties and methods of the object such as render() have special meanings, the rest is upforgrabs.
>
> [Read the full article...](http://www.phpied.com/reactive-table/)

15
docs/blog/all.html Normal file
View File

@@ -0,0 +1,15 @@
---
title: Blog
layout: default
sectionid: blog
id: all-posts
---
<section class="content wrap documentationContent nosidebar">
<div class="inner-content">
<h1>All Posts</h1>
{% for page in site.posts %}
<p><strong><a href="/react{{ page.url }}">{{ page.title }}</a></strong> on {{ page.date | date: "%B %e, %Y" }} by {{ page.author }}</p>
{% endfor %}
</div>
</section>

View File

@@ -4,25 +4,31 @@ layout: default
sectionid: blog
---
<section class="content wrap documentationContent">
<section class="content wrap blogContent">
{% include nav_blog.html %}
<div class="inner-content">
{% for page in site.posts %}
{% for page in paginator.posts %}
<div class="post-list-item">
<h1><a href="/react{{ page.url }}">{{ page.title }}</a></h1>
<p class="meta">{{ page.date | date: "%B %e, %Y" }} by {{ page.author }}</p>
<hr>
<hr />
<div class="post">
{{ page.excerpt }}
{% if page.excerpt != page.content %}
<p>
<a href="/react{{ page.url }}">Continue Reading &rarr;</a>
</p>
{% endif %}
{{ page.content }}
</div>
</div>
{% endfor %}
<div class="pagination">
{% if paginator.previous_page %}
<a href="/react/blog/{{ paginator.previous_page_path }}" class="previous">
&laquo; Previous Page
</a>
{% endif %}
{% if paginator.next_page %}
<a href="/react/blog/{{ paginator.next_page_path }}" class="next">
Next Page &raquo;
</a>
{% endif %}
</div>
</div>
</section>

30
docs/docs/01-why-react.md Normal file
View File

@@ -0,0 +1,30 @@
---
id: why-react
title: Why React?
layout: docs
permalink: why-react.html
next: displaying-data.html
---
React is a JavaScript library for creating user interfaces by Facebook and Instagram. Many people choose to think of React as the **V** in **[MVC](http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller)**.
We built React to solve one problem: **building large applications with data that changes over time**. To do this, React uses two main ideas.
### Simple
Simply express how your app should look at any given point in time, and React will automatically manage all UI updates when your underlying data changes.
### Declarative
When the data changes, React conceptually hits the "refresh" button, and knows to only update the changed parts.
## Build Composable Components
React is all about building reusable components. In fact, with React the *only* thing you do is build components. Since they're so encapsulated, components make code reuse, testing, and separation of concerns easy.
## Give It Five Minutes
React challenges a lot of conventional wisdom, and at first glance some of the ideas may seem crazy. [Give it five minutes](http://37signals.com/svn/posts/3124-give-it-five-minutes) while reading this guide; those crazy ideas have worked for building thousands of components both inside and outside of Facebook and Instagram.
## Learn More
You can learn more about our motivations behind building React in [this blog post](http://facebook.github.io/react/blog/2013/06/05/why-react.html).

View File

@@ -0,0 +1,91 @@
---
id: displaying-data
title: Displaying Data
layout: docs
permalink: displaying-data.html
prev: why-react.html
next: jsx-in-depth.html
---
The most basic thing you can do with a UI is display some data. React makes it easy to display data and automatically keeps the interface up-to-date when the data changes.
## Getting Started
Let's look at a really simple example. Create a `hello-react.html` file with the following code:
```html
<!DOCTYPE html>
<html>
<head>
<title>Hello React</title>
<script src="http://fb.me/react-{{site.react_version}}.min.js"></script>
<script src="http://fb.me/JSXTransformer-{{site.react_version}}.js"></script>
</head>
<body>
<div id="example"></div>
<script type="text/jsx">
// ** Your code goes here! **
</script>
</body>
</html>
```
For the rest of the documentation, we'll just focus on the JavaScript code and assume it's inserted into a template like the one above. Replace the placeholder comment above with the following JS:
```javascript
/** @jsx React.DOM */
var HelloWorld = React.createClass({
render: function() {
return (
<p>
Hello, <input type="text" placeholder="Your name here" />!
It is {this.props.date.toTimeString()}
</p>
);
}
});
setInterval(function() {
React.renderComponent(
<HelloWorld date={new Date()} />,
document.getElementById('example')
);
}, 500);
```
## Reactive Updates
Open `hello-react.html` in a web browser and type your name into the text field. Notice that React is only changing the time string in the UI — any input you put in the text field remains, even though you haven't written any code to manage this behavior. React figures it out for you and does the right thing.
The way we are able to figure this out is that React does not manipulate the DOM unless it needs to. **It uses a fast, internal mock DOM to perform diffs and computes the most efficient DOM mutation for you.**
The inputs to this component are called `props` — short for "properties". They're passed as attributes in JSX syntax. You should think of these as immutable within the component, that is, **never write to `this.props`**.
## Components are Just Like Functions
React components are very simple. You can think of them as simple function that take in `props` and `state` (discussed later) and render HTML. Because they're so simple, it makes them very easy to reason about.
> Note:
>
> **One limitation**: React components can only render a single root node. If you want to return multiple nodes they *must* be wrapped in a single root.
## JSX Syntax
We strongly believe that components are the right way to separate concerns rather than "templates" and "display logic." We think that markup and the code that generates it are intimately tied together. Additionally, display logic is often very complex and using template languages to express it becomes cumbersome.
We've found that the best solution for this problem is to generate markup directly from the JavaScript code such that you can use all of the expressive power of a real programming language to build UIs. In order to make this easier, we've added a very simple, **optional** HTML-like syntax for the function calls that generate markup called JSX.
**JSX lets you write JavaScript function calls with HTML syntax.** To generate a link in React using pure JavaScript you'd write: `React.DOM.a({href: 'http://facebook.github.io/react/'}, 'Hello React!')`. With JSX this becomes `<a href="http://facebook.github.io/react/">Hello React!</a>`. We've found this has made building React apps easier and designers tend to prefer the syntax, but everyone has their own workflow, so **JSX is not required to use React.**
JSX is very small; the "hello, world" example above uses every feature of JSX. To learn more about it, see [JSX in depth](./jsx-in-depth.html). Or see the transform in action in [our live JSX compiler](/react/jsx-compiler.html).
JSX is similar to HTML, but not exactly the same. See [JSX gotchas](./jsx-gotchas.html) for some key differences.
The easiest way to get started with JSX is to use the in-browser `JSXTransformer`. We strongly recommend that you don't use this in production. You can precompile your code using our command-line [react-tools](http://npmjs.org/package/react-tools) package.

View File

@@ -1,18 +1,17 @@
---
id: docs-syntax
title: JSX Syntax
description: Writing JavaScript with XML syntax.
id: jsx-in-depth
title: JSX in Depth
layout: docs
prev: common-questions.html
next: component-basics.html
permalink: jsx-in-depth.html
prev: displaying-data.html
next: jsx-gotchas.html
---
JSX is a JavaScript XML syntax transform recommended (but not required) for use
JSX is a JavaScript XML syntax transform recommended for use
with React.
## Why JSX?
First of all, **don't use JSX if you don't like it!**
## Why JSX?
React works out of the box without JSX. Simply construct your markup using the
functions on `React.DOM`. For example, here's how to construct a simple link:
@@ -23,21 +22,22 @@ var link = React.DOM.a({href: 'http://facebook.github.io/react'}, 'React');
We recommend using JSX for many reasons:
- It's easier to visualize the structure of the DOM.
- Designers are more comfortable making changes.
- It's familiar for those who have used MXML or XAML.
* It's easier to visualize the structure of the DOM.
* Designers are more comfortable making changes.
* It's familiar for those who have used MXML or XAML.
## The Transform
JSX transforms XML-like syntax into native JavaScript. It turns XML elements and
attributes into function calls and objects, respectively.
JSX transforms from an XML-like syntax into native JavaScript. XML elements and
attributes are transformed into function calls and objects, respectively.
```javascript
var Nav;
// Input (JSX):
var app = <Nav color="blue" />;
// Output (JS):
var app = Nav({color:'blue'});
var app = Nav({color:"blue"});
```
Notice that in order to use `<Nav />`, the `Nav` variable must be in scope.
@@ -49,11 +49,11 @@ var Nav, Profile;
// Input (JSX):
var app = <Nav color="blue"><Profile>click</Profile></Nav>;
// Output (JS):
var app = Nav({color:'blue'}, Profile({}, 'click'));
var app = Nav({color:"blue"}, Profile(null, "click"));
```
Use the [JSX Compiler](/react/jsx-compiler.html) to try out JSX and see how it
desguars into native JavaScript.
desugars into native JavaScript.
If you want to use JSX, the [Getting Started](getting-started.html) guide shows
how to setup compilation.
@@ -63,16 +63,17 @@ how to setup compilation.
> Details about the code transform are given here to increase understanding, but
> your code should not rely on these implementation details.
## React and JSX
React and JSX are independent technologies, but JSX was primarily built with
React in mind. The two valid uses of JSX are:
- To construct instances of React DOM components (`React.DOM.*`).
- To construct instances of composite components created with
* To construct instances of React DOM components (`React.DOM.*`).
* To construct instances of composite components created with
`React.createClass()`.
**React DOM Components**
### React DOM Components
To construct a `<div>` is to create a variable that refers to `React.DOM.div`.
@@ -81,7 +82,7 @@ var div = React.DOM.div;
var app = <div className="appClass">Hello, React!</div>;
```
**React Component Components**
### React Composite Components
To construct an instance of a composite component, create a variable that
references the class.
@@ -91,7 +92,7 @@ var MyComponent = React.createClass({/*...*/});
var app = <MyComponent someProperty={true} />;
```
See [Component Basics](component-basics.html) to learn more about components.
See [Multiple Components](multiple-components.html) to learn more about using composite components.
> Note:
>
@@ -114,7 +115,7 @@ var Nav;
// Input (JSX):
var tree = <Nav><span /></Nav>;
// Output (JS):
var tree = Nav({}, React.DOM.span({}));
var tree = Nav(null, React.DOM.span(null));
```
> Remember:
@@ -125,7 +126,7 @@ var tree = Nav({}, React.DOM.span({}));
## JavaScript Expressions
#### Attribute Expressions
### Attribute Expressions
To use a JavaScript expression as an attribute value, wrap the expression in a
pair of curly braces (`{}`) instead of quotes (`""`).
@@ -137,7 +138,7 @@ var person = <Person name={window.isLoggedIn ? window.name : ''} />;
var person = Person({name: window.isLoggedIn ? window.name : ''});
```
#### Child Expressions
### Child Expressions
Likewise, JavaScript expressions may be used to express children:
@@ -145,24 +146,39 @@ Likewise, JavaScript expressions may be used to express children:
// Input (JSX):
var content = <Container>{window.isLoggedIn ? <Nav /> : <Login />}</Container>;
// Output (JS):
var content = Container({}, window.isLoggedIn ? <Nav /> : <Login />);
var content = Container(null, window.isLoggedIn ? Nav(null) : Login(null));
```
### Comments
It's easy to add comments within your JSX; they're just JS expressions:
```javascript
var content = <Container>{/* this is a comment */}<Nav /></Container>;
```
## Tooling
Beyond the compilation step, JSX does not require any special tools.
- Many editors already include reasonable support for JSX (Vim, Emacs js2-mode).
- Linting provides accurate line numbers after compiling without sourcemaps.
- Elements use standard scoping so linters can find usage of out-of-scope
* Many editors already include reasonable support for JSX (Vim, Emacs js2-mode).
* JSX syntax highlighting is available for Sublime Text and other editors
that support `*.tmLanguage` using the third-party
[`JavaScript (JSX).tmLanguage`][1].
* Linting provides accurate line numbers after compiling without sourcemaps.
* Elements use standard scoping so linters can find usage of out-of-scope
components.
[1]: https://github.com/yungsters/sublime/blob/master/tmLanguage/JavaScript%20(JSX).tmLanguage
## Prior Work
JSX is similar to several other JavaScript embedded XML language
proposals/projects. Some of the features of JSX that distinguish it from similar
efforts include:
- JSX is a simple syntactic transform.
- JSX neither provides nor requires a runtime library.
- JSX does not alter or add to the semantics of JavaScript.
* JSX is a simple syntactic transform.
* JSX neither provides nor requires a runtime library.
* JSX does not alter or add to the semantics of JavaScript.
JSX is similar to HTML, but not exactly the same. See [JSX gotchas](./jsx-gotchas.html) for some key differences.

View File

@@ -0,0 +1,80 @@
---
id: jsx-gotchas
title: JSX Gotchas
layout: docs
permalink: jsx-gotchas.html
prev: jsx-in-depth.html
next: interactivity-and-dynamic-uis.html
---
JSX looks like HTML but there are some important differences you may run into.
> Note:
>
> For DOM differences, such as the inline `style` attribute, check [here](dom-differences.html).
## Whitespace Removal
JSX doesn't follow the same whitespace elimination rules as HTML. JSX removes all whitespace between two curly braces expressions. If you want to have whitespace, simply add `{' '}`.
```javascript
<div>{this.props.name} {' '} {this.props.surname}</div>
```
Follow [Issue #65](https://github.com/facebook/react/issues/65) for discussion on this behavior.
## HTML Entities
You can insert HTML entities within literal text in JSX:
```javascript
<div>First &middot; Second</div>
```
If you want to display an HTML entity within dynamic content, you will run into double escaping issues as React escapes all the strings you are displaying in order to prevent a wide range of XSS attacks by default.
```javascript
// Bad: It displays "First &middot; Second"
<div>{'First &middot; Second'}</div>
```
There are various ways to work-around this issue. The easiest one is to write unicode character directly in Javascript. You need to make sure that the file is saved as UTF-8 and that the proper UTF-8 directives are set so the browser will display it correctly.
```javascript
<div>{'First · Second'}</div>
```
A safer alternative is to find the [unicode number corresponding to the entity](http://www.fileformat.info/info/unicode/char/b7/index.htm) and use it inside of a JavaScript string.
```javascript
<div>{'First \u00b7 Second'}</div>
<div>{'First ' + String.fromCharCode(183) + ' Second'}</div>
```
You can use mixed arrays with strings and JSX elements.
```javascript
<div>{['First ', <span>&middot;</span>, ' Second']}</div>
```
As a last resort, you always have the ability to insert raw HTML.
```javascript
<div dangerouslySetInnerHTML={{'{{'}}__html: 'First &middot; Second'}} />
```
## Custom HTML Attributes
If you pass properties to native HTML elements that do not exist in the HTML specification, React will not render them. If you want to use a custom attribute, you should prefix it with `data-`.
```javascript
<div data-custom-attribute="foo" />
```
[Web Accessibility](http://www.w3.org/WAI/intro/aria) attributes starting with `aria-` will be rendered properly.
```javascript
<div aria-hidden={true} />
```

View File

@@ -0,0 +1,89 @@
---
id: interactivity-and-dynamic-uis
title: Interactivity and Dynamic UIs
layout: docs
permalink: interactivity-and-dynamic-uis.html
prev: jsx-gotchas.html
next: multiple-components.html
---
You've already [learned how to display data](./displaying-data.html) with React. Now let's look at how to make our UIs interactive.
## A Simple Example
```javascript
/** @jsx React.DOM */
var LikeButton = React.createClass({
getInitialState: function() {
return {liked: false};
},
handleClick: function(event) {
this.setState({liked: !this.state.liked});
},
render: function() {
var text = this.state.liked ? 'like' : 'unlike';
return (
<p onClick={this.handleClick}>
You {text} this. Click to toggle.
</p>
);
}
});
React.renderComponent(
<LikeButton />,
document.getElementById('example')
);
```
## Event Handling and Synthetic Events
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](http://www.w3.org/TR/DOM-Level-3-Events/), regardless of which browser you're using.
If you'd like to use React on a touch device (i.e. a phone or tablet), simply call `React.initializeTouchEvents(true);` to turn them on.
## Under the Hood: autoBind and Event Delegation
Under the hood React does a few things to keep your code performant and easy to understand.
**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!
**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).
## Components are Just State Machines
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.
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.
## How State Works
A common way to inform React of a data change is by calling `setState(data, callback)`. This method merges `data` into `this.state` and re-renders the component. When the component finishes re-rendering, the optional `callback` is called. Most of the time you'll never need to provide a `callback` since React will take care of keeping your UI up-to-date for you.
## What Components Should Have State?
Most of your components should simply take some data from `props` and render it. However, sometimes you need to respond to user input, a server request or the passage of time. For this you use state.
**Try to keep as many of your components as possible stateless.** By doing this you'll isolate the state to its most logical place and minimize redundancy, making it easier to reason about your application.
A common pattern is to create several stateless components that just render data, and have a stateful component above them in the hierarchy that passes its state to its children via `props`. The stateful component encapsulates all of the interaction logic, while the stateless components take care of rendering data in a declarative way.
## What *Should* Go in State?
**State should contain data that a component's event handlers may change to trigger a UI update.** In real apps this data tends to be very small and JSON-serializable. When building a stateful component, think about the minimal possible representation of its state, and only store those properties in `this.state`. Inside of `render()` simply compute any other information you need based on this state. You'll find that thinking about and writing applications in this way tends to lead to the most correct application, since adding redundant or computed values to state means that you need to explicitly keep them in sync rather than rely on React computing them for you.
## What *Shouldn't* Go in State?
`this.state` should only contain the minimal amount of data needed to represent your UI's state. As such, it should not contain:
* **Computed data:** Don't worry about precomputing values based on state — it's easier to ensure that your UI is consistent if you do all computation within `render()`. For example, if you have an array of list items in state and you want to render the count as a string, simply render `this.state.listItems.length + ' list items'` in your `render()` method rather than storing it on state.
* **React components:** Build them in `render()` based on underlying props and state.
* **Duplicated data from props:** Try to use props as the source of truth where possible. Because props can change over time, it's appropriate to store props in state to be able to know its previous values.

View File

@@ -0,0 +1,151 @@
---
id: multiple-components
title: Multiple Components
layout: docs
permalink: multiple-components.html
prev: interactivity-and-dynamic-uis.html
next: reusable-components.html
---
So far, we've looked at how to write a single component to display data and handle user input. Next let's examine one of React's finest features: composability.
## Motivation: Separation of Concerns
By building modular components that reuse other components with well-defined interfaces, you get much of the same benefits that you get by using functions or classes. Specifically you can *separate the different concerns* of your app however you please simply by building new components. By building a custom component library for your application, you are expressing your UI in a way that best fits your domain.
## Composition Example
Let's create a simple Avatar component which shows a profile picture and username using the Facebook Graph API.
```javascript
/** @jsx React.DOM */
var Avatar = React.createClass({
render: function() {
return (
<div>
<ProfilePic username={this.props.username} />
<ProfileLink username={this.props.username} />
</div>
);
}
});
var ProfilePic = React.createClass({
render: function() {
return (
<img src={'http://graph.facebook.com/' + this.props.username + '/picture'} />
);
}
});
var ProfileLink = React.createClass({
render: function() {
return (
<a href={'http://www.facebook.com/' + this.props.username}>
{this.props.username}
</a>
);
}
});
React.renderComponent(
<Avatar username="pwh" />,
document.getElementById('example')
);
```
## Ownership
In the above example, instances of `Avatar` *own* instances of `ProfilePic` and `ProfileLink`. In React, **an owner is the component that sets the `props` of other components**. More formally, if a component `X` is created in component `Y`'s `render()` method, it is said that `X` is *owned by* `Y`. As discussed earlier, a component cannot mutate its `props` — they are always consistent with what its owner sets them to. This key property leads to UIs that are guaranteed to be consistent.
It's important to draw a distinction between the owner-ownee relationship and the parent-child relationship. The owner-ownee relationship is specific to React, while the parent-child relationship is simply the one you know and love from the DOM. In the example above, `Avatar` owns the `div`, `ProfilePic` and `ProfileLink` instances, and `div` is the **parent** (but not owner) of the `ProfilePic` and `ProfileLink` instances.
## Children
When you create a React component instance, you can include additional React components or JavaScript expressions between the opening and closing tags like this:
```javascript
<Parent><Child /></Parent>
```
`Parent` can read its children by accessing the special `this.props.children` prop.
### Child Reconciliation
**Reconciliation is the process by which React updates the DOM with each new render pass.** In general, children are reconciled according to the order in which they are rendered. For example, suppose two render passes generate the following respective markup:
```html
// Render Pass 1
<Card>
<p>Paragraph 1</p>
<p>Paragraph 2</p>
</Card>
// Render Pass 2
<Card>
<p>Paragraph 2</p>
</Card>
```
Intuitively, `<p>Paragraph 1</p>` was removed. Instead, React will reconcile the DOM by changing the text content of the first child and destroying the last child. React reconciles according to the *order* of the children.
### Stateful Children
For most components, this is not a big deal. However, for stateful components that maintain data in `this.state` across render passes, this can be very problematic.
In most cases, this can be sidestepped by hiding elements instead of destroying them:
```html
// Render Pass 1
<Card>
<p>Paragraph 1</p>
<p>Paragraph 2</p>
</Card>
// Render Pass 2
<Card>
<p style={{'{{'}}display: 'none'}}>Paragraph 1</p>
<p>Paragraph 2</p>
</Card>
```
### Dynamic Children
The situation gets more complicated when the children are shuffled around (as in search results) or if new components are added onto the front of the list (as in streams). In these cases where the identity and state of each child must be maintained across render passes, you can uniquely identify each child by assigning it a `key`:
```javascript
render: function() {
var results = this.props.results;
return (
<ol>
{this.results.map(function(result) {
return <li key={result.id}>{result.text}</li>;
})}
</ol>
);
}
```
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).
## Data Flow
In React, data flows from owner to owned component through `props` as discussed above. This is effectively one-way data binding: owners bind their owned component's props to some value the owner has computed based on its `props` or `state`. Since this process happens recursively, data changes are automatically reflected everywhere they are used.
## A Note on Performance
You may be thinking that it's expensive to react to changing data if there are a large number of nodes under an owner. The good news is that JavaScript is fast and `render()` methods tend to be quite simple, so in most applications this is extremely fast. Additionally, the bottleneck is almost always the DOM mutation and not JS execution and React will optimize this for you using batching and change detection.
However, sometimes you really want to have fine-grained control over your performance. In that case, simply override `shouldComponentUpdate()` to return false when you want React to skip processing of a subtree. See [the React reference docs](component-specs.html) for more information.
> Note:
>
> If `shouldComponentUpdate()` returns false when data has actually changed, React can't keep your UI in sync. Be sure you know what you're doing while using it, and only use this function when you have a noticeable performance problem. Don't underestimate how fast JavaScript is relative to the DOM.

View File

@@ -0,0 +1,143 @@
---
id: reusable-components
title: Reusable Components
layout: docs
permalink: reusable-components.html
prev: multiple-components.html
next: forms.html
---
When designing interfaces, break down the common design elements (buttons, form fields, layout components, etc) into reusable components with well-defined interfaces. That way, the next time you need to build some UI you can write much less code, which means faster development time, less bugs, and less bytes down the wire.
## Prop Validation
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, an error will be thrown. Here is an example documenting the different validators provided:
```javascript
React.createClass({
propTypes: {
// You can declare that a prop is a specific JS primitive. By default, these
// are all optional.
optionalArray: React.PropTypes.array,
optionalBool: React.PropTypes.bool,
optionalFunc: React.PropTypes.func,
optionalNumber: React.PropTypes.number,
optionalObject: React.PropTypes.object,
optionalString: React.PropTypes.string,
// You can ensure that your prop is limited to specific values by treating
// it as an enum.
optionalEnum: React.PropTypes.oneOf(['News','Photos']),
// You can also declare that a prop is an instance of a class. This uses
// JS's instanceof operator.
someClass: React.PropTypes.instanceOf(SomeClass),
// You can chain any of the above with isRequired to make sure an error is
// thrown if the prop isn't provided.
requiredFunc: React.PropTypes.func.isRequired
// You can also specify a custom validator.
customProp: function(props, propName, componentName) {
if (!/matchme/.test(props[propName])) {
throw new Error('Validation failed!')
}
}
},
/* ... */
});
```
## Default Prop Values
React lets you define default values for your `props` in a very declarative way:
```javascript
var ComponentWithDefaultProps = React.createClass({
getDefaultProps: function() {
return {
value: 'default value'
};
}
/* ... */
});
```
The result of `getDefaultProps()` will be cached and used to ensure that `this.props.value` will have a value if it was not specified by the parent component. This allows you to safely just use your props without having to write repetitive and fragile code to handle that yourself.
## Transferring Props: A Shortcut
A common type of React component is one that extends a basic HTML in a simple way. Often you'll want to copy any HTML attributes passed to your component to the underlying HTML element to save typing. React provides `transferPropsTo()` to do just this.
```javascript
/** @jsx React.DOM */
var CheckLink = React.createClass({
render: function() {
// transferPropsTo() will take any props passed to CheckLink
// and copy them to <a>
return this.transferPropsTo(<a>{'√ '}{this.props.children}</a>);
}
});
React.renderComponent(
<CheckLink href="javascript:alert('Hello, world!');">
Click here!
</CheckLink>,
document.getElementById('example')
);
```
## 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](http://en.wikipedia.org/wiki/Cross-cutting_concern). React provides `mixins` to solve this problem.
One common use case is a component wanting to update itself on a time interval. It's easy to use `setInterval()`, but it's important to cancel your interval when you don't need it anymore to save memory. React provides [lifecycle methods](./working-with-the-browser.html) that let you know when a component is about to be created or destroyed. Let's create a simple mixin that uses these methods to provide an easy `setInterval()` function that will automatically get cleaned up when your component is destroyed.
```javascript
/** @jsx React.DOM */
var SetIntervalMixin = {
componentWillMount: function() {
this.intervals = [];
},
setInterval: function() {
this.intervals.push(setInterval.apply(null, arguments));
},
componentWillUnmount: function() {
this.intervals.map(clearInterval);
}
};
var TickTock = React.createClass({
mixins: [SetIntervalMixin], // Use the mixin
getInitialState: function() {
return {seconds: 0};
},
componentDidMount: function() {
this.setInterval(this.tick, 1000); // Call a method on the mixin
},
tick: function() {
this.setState({seconds: this.state.seconds + 1});
},
render: function() {
return (
<p>
React has been running for {this.state.seconds} seconds.
</p>
);
}
});
React.renderComponent(
<TickTock />,
document.getElementById('example')
);
```
A nice feature of mixins is that if a component is using multiple mixins and several mixins define the same lifecycle method (i.e. several mixins want to do some cleanup when the component is destroyed), all of the lifecycle methods are guaranteed to be called.

132
docs/docs/06-forms.md Normal file
View File

@@ -0,0 +1,132 @@
---
id: forms
title: Forms
layout: docs
permalink: forms.html
prev: reusable-components.html
next: working-with-the-browser.html
---
Form components such as `<input>`, `<textarea>`, and `<option>` differ from other native components because they can be mutated via user interactions. These components provide interfaces that make it easier to manage forms in response to user interactions.
## Interactive Props
Form components support a few props that are affected via user interactions:
* `value`, supported by `<input>` and `<textarea>` components.
* `checked`, supported by `<input>` components of type `checkbox` or `radio`.
* `selected`, supported by `<option>` components.
In HTML, the value of `<textarea>` is set via children. In React, you should use `value` instead.
Form components allow listening for changes by setting a callback to the `onChange` prop. The `onChange` prop works across browsers to fire in response to user interactions when:
* The `value` of `<input>` or `<textarea>` changes.
* The `checked` state of `<input>` changes.
* The `selected` state of `<option>` changes.
Like all DOM events, the `onChange` prop is supported on all native components and can be used to listen to bubbled change events.
## Controlled Components
An `<input>` with `value` set is a *controlled* component. In a controlled `<input>`, the value of the rendered element will always reflect the `value` prop. For example:
```javascript
render: function() {
return <input type="text" value="Hello!" />;
}
```
This will render an input that always has a value of `Hello!`. Any user input will have no effect on the rendered element because React has declared the value to be `Hello!`. If you wanted to update the value in response to user input, you could use the `onChange` event:
```javascript
getInitialState: function() {
return {value: 'Hello!'};
},
handleChange: function(event) {
this.setState({value: event.target.value});
},
render: function() {
var value = this.state.value;
return <input type="text" value={value} onChange={this.handleChange} />;
}
```
In this example, we are simply accepting the newest value provided by the user and updating the `value` prop of the `<input>` component. This pattern makes it easy to implement interfaces that respond to or validate user interactions. For example:
```javascript
handleChange: function(event) {
this.setState({value: event.target.value.substr(0, 140)});
}
```
This would accept user input but truncate the value to the first 140 characters.
## Uncontrolled Components
An `<input>` that does not supply a `value` (or sets it to `null`) is an *uncontrolled* component. In an uncontrolled `<input>`, the value of the rendered element will reflect the user's input. For example:
```javascript
render: function() {
return <input type="text" />;
}
```
This will render an input that starts off with an empty value. Any user input will be immediately reflected by the rendered element. If you wanted to listen to updates to the value, you could use the `onChange` event just like you can with controlled components.
If you want to initialize the component with a non-empty value, you can supply a `defaultValue` prop. For example:
```javascript
render: function() {
return <input type="text" defaultValue="Hello!" />;
}
```
This example will function much like the **Controlled Components** example above.
Likewise, `<input>` supports `defaultChecked` and `<option>` supports `defaultSelected`.
## Advanced Topics
### Why Controlled Components?
Using form components such as `<input>` in React presents a challenge that is absent when writing traditional form HTML. For example, in HTML:
```html
<input type="text" name="title" value="Untitled" />
```
This renders an input *initialized* with the value, `Untitled`. When the user updates the input, the node's value *property* will change. However, `node.getAttribute('value')` will still return the value used at initialization time, `Untitled`.
Unlike HTML, React components must represent the state of the view at any point in time and not only at initialization time. For example, in React:
```javascript
render: function() {
return <input type="text" name="title" value="Untitled" />;
}
```
Since this method describes the view at any point in time, the value of the text input should *always* be `Untitled`.
### Why Textarea Value?
In HTML, the value of `<textarea>` is usually set using its children:
```html
<!-- counterexample: DO NOT DO THIS! -->
<textarea name="description">This is the description.</textarea>
```
For HTML, this easily allows developers to supply multiline values. However, since React is JavaScript, we do not have string limitations and can use `\n` if we want newlines. In a world where we have `value` and `defaultValue`, it is ambiguous what role children play. For this reason, you should not use children when setting `<textarea>` values:
```javascript
<textarea name="description" value="This is a description." />
```
If you *do* decide to use children, they will behave like `defaultValue`.

View File

@@ -0,0 +1,134 @@
---
id: working-with-the-browser
title: Working With the Browser
layout: docs
permalink: working-with-the-browser.html
prev: forms.html
next: more-about-refs.html
---
React provides powerful abstractions that free you from touching the DOM directly in most cases, but sometimes you simply need to access the underlying API, perhaps to work with a third-party library or existing code.
## The Mock DOM
React is so fast because it never talks to the DOM directly. React maintains a fast in-memory representation of the DOM. `render()` methods return a *description* of the DOM, and React can diff this description with the in-memory representation to compute the fastest way to update the browser.
Additionally, React implements a full synthetic event system such that all event objects are guaranteed to conform to the W3C spec despite browser quirks, and everything bubbles consistently and in a performant way cross-browser. You can even use some HTML5 events in IE8!
Most of the time you should stay within React's "faked browser" world since it's more performant and easier to reason about. However, sometimes you simply need to access the underlying API, perhaps to work with a third-party library like a jQuery plugin. React provides escape hatches for you to use the underlying DOM API directly.
## Refs and getDOMNode()
To interact with the browser, you'll need a reference to a DOM node. Every mounted React component has a `getDOMNode()` function which you can call to get a reference to it.
> Note:
>
> `getDOMNode()` only works on mounted components (that is, components that have been placed in the DOM). If you try to call this on a component that has not been mounted yet (like calling `getDOMNode()` in `render()` on a component that has yet to be created) an exception will be thrown.
In order to get a reference to a React component, you can either use `this` to get the current React component, or you can use refs to refer to a component you own. They work like this:
```javascript
/** @jsx React.DOM */
var MyComponent = React.createClass({
handleClick: function() {
// Explicitly focus the text input using the raw DOM API.
this.refs.myTextInput.getDOMNode().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="myTextInput" />
<input
type="button"
value="Focus the text input"
onClick={this.handleClick}
/>
</div>
);
}
});
React.renderComponent(
<MyComponent />,
document.getElementById('example')
);
```
## More About Refs
To learn more about refs, including ways to use them effectively, see our [more about refs](./more-about-refs.html) documentation.
## Component Lifecycle
Components have three main parts of their lifecycle:
* **Mounting:** A component is being inserted into the DOM.
* **Updating:** A component is being re-rendered to determine if the DOM should be updated.
* **Unmounting:** A component is being removed from the DOM.
React provides lifecycle methods that you can specify to hook into this process. We provide **will** methods, which are called right before something happens, and **did** methods which are called right after something happens.
### Mounting
* `getInitialState(): object` is invoked before a component is mounted. Stateful components should implement this and return the initial state data.
* `componentWillMount()` is invoked immediately before mounting occurs.
* `componentDidMount(DOMElement rootNode)` is invoked immediately after mounting occurs. Initialization that requires DOM nodes should go here.
### Updating
* `componentWillReceiveProps(object nextProps)` is invoked when a mounted component receives new props. This method should be used to compare `this.props` and `nextProps` to perform state transitions using `this.setState()`.
* `shouldComponentUpdate(object nextProps, object nextState): boolean` is invoked when a component decides whether any changes warrant an update to the DOM. Implement this as an optimization to compare `this.props` with `nextProps` and `this.state` with `nextState` and return false if React should skip updating.
* `componentWillUpdate(object nextProps, object nextState)` is invoked immediately before updating occurs. You cannot call `this.setState()` here.
* `componentDidUpdate(object prevProps, object prevState, DOMElement rootNode)` is invoked immediately after updating occurs.
### Unmounting
* `componentWillUnmount()` is invoked immediately before a component is unmounted and destroyed. Cleanup should go here.
### Mounted Methods
_Mounted_ composite components also support the following methods:
* `getDOMNode(): DOMElement` can be invoked on any mounted component in order to obtain a reference to its rendered DOM node.
* `forceUpdate()` can be invoked on any mounted component when you know that some deeper aspect of the component's state has changed without using `this.setState()`.
> Note:
>
> The `DOMElement rootNode` argument of `componentDidMount()` and
> `componentDidUpdate()` is a convenience. The same node can be obtained by
> calling `this.getDOMNode()`.
## Browser Support and Polyfills
At Facebook, we support older browsers, including IE8. We've had polyfills in place for a long time to allow us to write forward-thinking JS. This means we don't have a bunch of hacks scattered throughout our codebase and we can still expect our code to "just work". For example, instead of seeing `+new Date()`, we can just write `Date.now()`. Since the open source React is the same as what we use internally, we've carried over this philosophy of using forward thinking JS.
In addition to that philosophy, we've also taken the stance that we, as authors of a JS library, should not be shipping polyfills as a part of our library. If every library did this, there's a good chance you'd be sending down the same polyfill multiple times, which could be a sizable chunk of dead code. If your product needs to support older browsers, chances are you're already using something like [es5-shim](https://github.com/kriskowal/es5-shim).
### Polyfills Needed to Support Older Browsers
These six functions can be polyfilled using `es5-shim.js` from [kriskowal's es5-shim](https://github.com/kriskowal/es5-shim):
* `Array.isArray`
* `Array.prototype.forEach`
* `Array.prototype.indexOf`
* `Array.prototype.some`
* `Date.now`
* `Function.prototype.bind`
Other required polyfills:
* `Object.create` Provided by `es5-sham.js` from [kriskowal's es5-shim](https://github.com/kriskowal/es5-shim).
* `console.*` Only needed when using the unminified build. If you need to polyfill this, try [paulmillr's console-polyfill](https://github.com/paulmillr/console-polyfill).

View File

@@ -0,0 +1,135 @@
---
id: more-about-refs
title: More About Refs
layout: docs
permalink: more-about-refs.html
prev: working-with-the-browser.html
next: tooling-integration.html
---
After returning the structure of your UI from the render method, you may find yourself wanting to "reach out" and invoke methods on component instances returned from render. Often, doing something like this isn't necessary for making data flow through your application, 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.
Consider the case when you wish to tell an `<input />` element (that exists within your instances sub-hierarchy) to focus after you update its value to be the empty string, `''`.
```javascript
var App = React.createClass({
getInitialState: function() {
return {userInput: ''};
},
handleKeyUp: 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}
onKeyUp={this.handleKeyUp}
/>
</div>
);
}
});
```
Notice how, in this example, we want to "tell" the input something - something that it cannot infer from its props over time. In this case we want to "tell" it that it should now become focused. However, there are some challenges. What is returned from `render()` is not your actual composition of "child" components, it is merely a *description* of the children at a particular instance in time - a snapshot, if you will.
> Note:
>
> Remember, what you return from `render()` is not your *actual* rendered children instances. What you return from `render()` is merely a *description* of the children instances in your component's sub-hierarchy at a particular moment in time.
This means that you should never "hold onto" something that you return from `render()` and then expect it to be anything meaningful.
```javascript
// counterexample: DO NOT DO THIS!
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>
);
}
```
In this counterexample, the `<input />` is merely a *description* of an `<input />`. This description is used to create a *real* **backing instance** for the `<input />`.
So how do we talk to the *real* backing instance of the input?
## The ref Attribute
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.
It's as simple as:
**1.** Assign a `ref` attribute to anything returned from `render` such as:
```html
<input ref="myInput" />
```
**2.** In some other code (typically event handler code), access the **backing instance** via `this.refs` as in:
```javascript
this.refs.myInput
```
## Completing the Example
```javascript
var App = React.createClass({
getInitialState: function() {
return {userInput: ''};
},
handleKeyUp: function(e) {
this.setState({userInput: e.target.value});
},
clearAndFocusInput: function() {
this.setState({userInput: ''}); // Clear the input
this.refs.theInput.getDOMNode().focus(); // Boom! Focused!
},
render: function() {
return (
<div>
<div onClick={this.clearAndFocusInput}>
Click To Focus and Reset
</div>
<input
ref="theInput"
value={this.state.userInput}
onKeyUp={this.handleKeyUp}
/>
</div>
);
}
});
```
In this example, our render function returns a description of an `<input />` instance. But the true instance is accessed via `this.refs.theInput`. As long as a child component with `ref="theInput"` is returned from render, `this.refs.theInput` will access the proper instance. This even works on higher level (non-DOM) components such as `<Typeahead ref="myTypeahead" />`.
## Summary
Refs are a great way to send a message to a particular child instance in a way that would be inconvenient to do via streaming Reactive `props` and `state`. They should, however, not be your go-to abstraction for flowing data through your application. By default, use the Reactive data flow and save `ref`s for use cases that are inherently non-reactive.
### Benefits:
- You can define any public method on your component classes (such as a reset method on a Typeahead) and call those public methods through refs (such as `this.refs.myTypeahead.reset()`).
- Performing DOM measurements almost always requires reaching out to a "native" component such as `<input />` and accessing its underlying DOM node via `this.refs.myInput.getDOMNode()`. Refs are one of the only practical ways of doing this reliably.
- Refs are automatically book-kept for you! If that child is destroyed, its ref is also destroyed for you. No worrying about memory here (unless you do something crazy to retain a reference yourself).
### Cautions:
- *Never* access refs inside of any component's render method - or while any component's render method is even running anywhere in the call stack.
- If you want to preserve Google Closure Compiler Crushing resilience, make sure to never access as a property what was specified as a string. This means you must access using `this.refs['myRefString']` if your ref was defined as `ref="myRefString"`.
- If you have not programmed several apps with React, your first inclination is usually going to be to try to use refs to "make things happen" in your app. If this is the case, take a moment and think more critically about where `state` should be owned in the component hierarchy. Often, it becomes clear that the proper place to "own" that state is at a higher level in the hierarchy. Placing the state there often eliminates any desire to use `ref`s to "make things happen" - instead, the data flow will usually accomplish your goal.

View File

@@ -0,0 +1,52 @@
---
id: tooling-integration
title: Tooling Integration
layout: docs
permalink: tooling-integration.html
prev: more-about-refs.html
next: addons.html
---
Every project uses a different system for building and deploying JavaScript. We've tried to make React as environment-agnostic as possible.
## React
### CDN-hosted React
We provide CDN-hosted versions of React [on our download page](/react/downloads.html). These prebuilt files use the UMD module format. Dropping them in with a simple `<script>` tag will inject a `React` global into your environment. It should also work out-of-the-box in CommonJS and AMD environments.
### Using master
We have instructions for building from `master` [in our GitHub repository](https://github.com/facebook/react). We build a tree of CommonJS modules under `build/modules` which you can drop into any environment or packaging tool that supports CommonJS.
## JSX
### In-browser JSX Transform
If you like using JSX, we provide an in-browser JSX transformer for development [on our download page](/react/downloads.html). Simply include a `<script type="text/jsx">` tag to engage the JSX transformer. Be sure to include the `/** @jsx React.DOM */` comment as well, otherwise the transformer will not run the transforms.
> Note:
>
> The in-browser JSX transformer is fairly large and results in extraneous computation client-side that can be avoided. Do not use it in production — see the next section.
### Productionizing: Precompiled JSX
If you have [npm](http://npmjs.org/), you can simply run `npm install -g react-tools` to install our command-line `jsx` tool. 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: `jsx --watch src/ build/`. Run `jsx --help` for more information on how to use this tool.
### Helpful Open-Source Projects
The open-source community has built tools that integrate JSX with several build systems.
* [reactify](https://github.com/andreypopp/reactify) - use JSX with [browserify](http://browserify.org/)
* [grunt-react](https://github.com/ericclemmons/grunt-react) - [grunt](http://gruntjs.com/) task for JSX
* [require-jsx](https://github.com/seiffert/require-jsx) - use JSX with [require.js](http://requirejs.org/)
* [pyReact](https://github.com/facebook/react-python) - use JSX with [Python](http://www.python.org/)
* [react-rails](https://github.com/facebook/react-rails) - use JSX with [Ruby on Rails](http://rubyonrails.org/)
## React Page
To get started on a new project, you can use [react-page](https://github.com/facebook/react-page/), a complete React project creator. It supports both server-side and client-side rendering, source transform and packaging JSX files using CommonJS modules, and instant reload.

210
docs/docs/09-addons.md Normal file
View File

@@ -0,0 +1,210 @@
---
id: addons
title: Add-ons
layout: docs
permalink: addons.html
prev: tooling-integration.html
next: examples.html
---
`React.addons` is where we park some useful utilities for building React apps. **These should be considered experimental** but will eventually be rolled into core or a blessed utilities library.
## CSS Animation and Transitions
`ReactTransitions` is an easy way to perform CSS transitions and animations when a React component enters or leaves the DOM. `ReactTransitions` is inspired by the excellent [ng-animate](http://www.nganimate.org/) library.
### Getting Started
`ReactTransitionGroup` is the interface to `ReactTransitions`. This is a simple element that wraps all of the components you are interested in animating. Here's an example where we fade list items in and out.
```javascript{22-24}
/** @jsx React.DOM */
var ReactTransitionGroup = React.addons.TransitionGroup;
var TodoList = React.createClass({
getInitialState: function() {
return {items: ['hello', 'world', 'click', 'me']};
},
handleAdd: function() {
var newItems =
this.state.items.concat([prompt('Enter some text')]);
this.setState({items: newItems});
},
handleRemove: function(i) {
var newItems = this.state.items;
newItems.splice(i, 0)
this.setState({items: newItems});
},
render: function() {
var items = this.state.items.map(function(item, i) {
return (
<div key={i} onClick={this.handleRemove.bind(this, i)}>
{item}}
</div>
);
}.bind(this));
return (
<div>
<div><button onClick={this.handleAdd} /></div>
<ReactTransitionGroup transitionName="example">
{items}
</ReactTransitionGroup>
</div>
);
}
});
```
In this component, when a new item is added `ReactTransitionGroup` it will get the `example-enter` CSS class and the `example-enter-active` CSS class added in the next tick. This is a convention based on the `transitionName` prop.
You can use these classes to trigger a CSS animation or transition. For example, try adding this CSS and adding a new list item:
```css
.example-enter {
opacity: 0.01;
transition: opacity .5s ease-in;
}
.example-enter.example-enter-active {
opacity: 0.99;
}
```
You'll notice that when you try to remove an item `ReactTransitionGroup` keeps it in the DOM. If you're using an unminified build of React you'll see a warning that React was expecting an animation or transition to occur. That's because `ReactTransitionGroup` keeps your DOM elements on the page until the animation completes. Try adding this CSS:
```css
.example-leave {
opacity: 0.99;
transition: opacity .5s ease-in;
}
.example-leave.example-leave-active {
opacity: 0.01;
}
```
### Disabling Animations
You can disable animating `enter` or `leave` animations if you want. For example, sometimes you may want an `enter` animation and no `leave` animation, but `ReactTransitionGroup` waits for an animation to complete before removing your DOM node. You can add `transitionEnter={false}` or `transitionLeave={false}` props to `ReactTransitionGroup` to disable these animations.
### Rendering a Different Component
By default `ReactTransitionGroup` renders as a `span`. You can change this behavior by providing a `component` prop. For example, here's how you would render a `<ul>`:
```javascript{3}
<ReactTransitionGroup
transitionName="example"
component={React.DOM.ul}>
...
</ReactTransitionGroup>
```
`component` does not need to be a DOM component. It can be any component you want; even one you've written yourself!
## ReactLink
`ReactLink` is an easy way to express two-way binding with React.
In React, data flows one way: from owner to child. This is because data only flows one direction in [the Von Neumann model of computing](http://en.wikipedia.org/wiki/Von_Neumann_architecture). You can think of it as "one-way data binding."
However, there are lots of applications that require you to read some data and flow it back into your program. For example, when developing forms, you'll often want to update some React `state` when you receive user input. Or perhaps you want to perform layout in JavaScript and react to changes in some DOM element size.
In React, you would implement this by listening to a "change" event, read from your data source (usually the DOM) and call `setState()` on one of your components. "Closing the data flow loop" explicitly leads to more understandable and easier-to-maintain programs. See [our forms documentation](./forms.html) for more information.
Two-way binding -- implicitly enforcing that some value in the DOM is always consistent with some React `state` -- is concise and supports a wide variety of applications. We've provided `ReactLink`: syntactic sugar for setting up the common data flow loop pattern described above, or "linking" some data source to React `state`.
> Note:
>
> ReactLink is just a thin wrapper and convention around the `onChange`/`setState()` pattern. It doesn't fundamentally change how data flows in your React application.
### ReactLink: Before and After
Here's a simple form example without using `ReactLink`:
```javascript
/** @jsx React.DOM */
var NoLink = React.createClass({
getInitialState: function() {
return {value: 'Hello!'};
},
handleChange: function(event) {
this.setState({value: event.target.value});
},
render: function() {
var value = this.state.value;
return <input type="text" value={value} onChange={this.handleChange} />;
}
});
```
This works really well and it's very clear how data is flowing, however with a lot of form fields it could get a bit verbose. Let's use `ReactLink` to save us some typing:
```javascript{4,9}
/** @jsx React.DOM */
var WithLink = React.createClass({
mixins: [React.addons.LinkedStateMixin],
getInitialState: function() {
return {value: 'Hello!'};
},
render: function() {
return <input type="text" valueLink={this.linkState('value')} />;
}
});
```
`LinkedStateMixin` adds a method ot your React component called `linkState()`. `linkState()` returns a `ReactLink` object which contains the current value of the React state and a callback to change it.
`ReactLink` objects can be passed up and down the tree as props, so it's easy (and explicit) to set up two-way binding between a component deep in the hierarchy and state that lives higher in the hierarchy.
### Under the Hood
There are two sides to `ReactLink`: the place where you create the `ReactLink` instance and the place where you use it. To prove how simple `ReactLink` is, let's rewrite each side separately to be more explicit.
#### ReactLink Without LinkedStateMixin
```javascript{7-9,11-14}
/** @jsx React.DOM */
var WithoutMixin = React.createClass({
getInitialState: function() {
return {value: 'Hello!'};
},
handleChange: function(newValue) {
this.setState({value: newValue});
},
render: function() {
var valueLink = {
value: this.state.value,
requestChange: this.handleChange
};
return <input type="text" valueLink={valueLink} />;
}
});
```
As you can see, `ReactLink` objects are very simple objects that just have a `value` and `requestChange` prop. And `LinkedStateMixin` is similarly simple: it just populates those fields with a value from `this.state` and a callback that calls `this.setState()`.
#### ReactLink Without valueLink
```javascript
/** @jsx React.DOM */
var WithoutLink = React.createClass({
mixins: [React.addons.LinkedStateMixin],
getInitialState: function() {
return {value: 'Hello!'};
},
render: function() {
var valueLink = this.linkState('value');
var handleChange = function(e) {
valueLink.requestChange(e.target.value);
};
return <input type="text" value={valueLink.value} onChange={handleChange} />;
}
});
```
The `valueLink` prop is also quite simple. It simply handles the `onChange` event and calls `this.props.valueLink.requestChange()` and also uses `this.props.valueLink.value` instead of `this.props.value`. That's it!

22
docs/docs/10-examples.md Normal file
View File

@@ -0,0 +1,22 @@
---
id: examples
title: Examples
layout: docs
permalink: examples.html
prev: addons.html
---
### Production Apps
* All of [Instagram.com](http://instagram.com/) is built on React.
* Many components on [Facebook.com](http://www.facebook.com/), including the commenting interface, ads creation flows, and page insights.
* [Khan Academy](http://khanacademy.org/) is using React for most new JS development.
### Sample Code
* We've included [a step-by-step comment box tutorial](./tutorial.html).
* [The React starter kit](/react/downloads.html) includes several examples which you can [view online in our GitHub repository](https://github.com/facebook/react/tree/master/examples/).
* [React Page](https://github.com/facebook/react-page) is a simple React project creator to get you up-and-running quickly with React. It supports both server-side and client-side rendering, source transform and packaging JSX files using CommonJS modules, and instant reload.
* [React one-hour email](https://github.com/petehunt/react-one-hour-email/commits/master) goes step-by-step from a static HTML mock to an interactive email reader (written in just one hour!)
* [Rendr + React app template](https://github.com/petehunt/rendr-react-template/) demonstrates how to use React's server rendering capabilities.

96
docs/docs/OUTLINE.md Normal file
View File

@@ -0,0 +1,96 @@
---
id: OUTLINE
title: Goals of the documentation
layout: docs
prev: 09.1-tutorial.html
---
- Flow of docs should mimic progression of questions a new user would ask
- High information density -- assume the reader is adept at JS
- Talk about best practices
- JSFiddles for all code samples
- Provide background for some of the design decisions
- Less words less words less words!
## Outline
Motivation / Why React?
- Declarative (simple)
- Components (separation of concerns)
- Give it 5 minutes
Displaying data
- Hello world example
- Reactive updates
- Components are just functions
- JSX syntax (link to separate doc?)
- JSX gotchas
Interactivity and dynamic UIs
- Click handler example
- Event handlers / synthetic events (link to w3c docs)
- Under the hood: autoBind and event delegation (IE8 notes)
- React is a state machine
- How state works
- What components should have state?
- What should go in state?
- What shouldn't go in state?
Scaling up: using multiple components
- Motivation: separate concerns
- Composition example
- Ownership (and owner vs. parent)
- Children
- Data flow (one-way data binding)
- A note on performance
Building effective reusable components
- You should build a reusable component library (CSS, testing etc)
- Prop validation
- Transferring props: a shortcut
- Mixins
- Testing
Forms
Working with the browser
- The mock DOM
- Refs / getDOMNode()
- More about refs
- Component lifecycle
- Browser support and polyfills
Working with your environment
- CDN-hosted React
- Using master
- In-browser JSX transform
- Productionizing: precompiled JSX
- Helpful open-source projects
Integrating with other UI libraries
- Using jQuery plugins
- Letting jQuery manage React components
- Using with Backbone.View
- CoffeeScript
- Moving from Handlebars to React: an example
Server / static rendering
- Motivation
- Simple example
- How does it work? (No DOM)
- Rendr + React
Big ideas
- Animation
- Bootstrap bindings (responsive grids)
- Reactive CSS
- Web workers
- Native views
Case studies
- Comment box tutorial from scratch
- From HTML mock to application: React one-hour email
- Jordan's LikeToggler example
Reference
- API
- DOM differences

View File

@@ -1,119 +0,0 @@
---
id: docs-advanced-components
title: Advanced Components
description: How to build advanced composite components.
layout: docs
prev: event-handling.html
next: mixins.html
---
Composite components extend a `ReactCompositeComponent` base class that provides
a very powerful API that makes React flexible and able to easily work with other
libraries and frameworks.
## Lifecycle Methods
Composite components can optionally implement lifecycle methods that are invoked
at various stages in the [component lifecycle](component-lifecycle.html) that
each have unique guarantees.
### Mounting
- `getInitialState(): object` is invoked before a component is mounted.
Stateful components should implement this and return the initial state data.
- `componentWillMount()` is invoked immediately before mounting occurs.
- `componentDidMount(DOMElement rootNode)` is invoked immediately after
mounting occurs. Initialization that requires DOM nodes should go here.
### Updating
- `componentWillReceiveProps(object nextProps)` is invoked when a mounted
component receives new props. This method should be used to compare
`this.props` and `nextProps` to perform state transitions using
`this.setState()`.
- `shouldComponentUpdate(object nextProps, object nextState): boolean` is
invoked when a component decides whether any changes warrant an update to the
DOM. Implement this as an optimization to compare `this.props` with
`nextProps` and `this.state` with `nextState` and return false if React
should skip updating.
- `componentWillUpdate(object nextProps, object nextState)` is invoked
immediately before updating occurs. You cannot call `this.setState()` here.
- `componentDidUpdate(object prevProps, object prevState, DOMElement rootNode)`
is invoked immediately after updating occurs.
### Unmounting
- `componentWillUnmount()` is invoked immediately before a component is
unmounted and destroyed. Cleanup should go here.
## Mounted Methods
_Mounted_ composite components also support the following methods:
- `getDOMNode(): DOMElement` can be invoked on any mounted component in order
to obtain a reference to its rendered DOM node.
- `forceUpdate()` can be invoked on any mounted component when you know that
some deeper aspect of the component's state has changed without using
`this.setState()`.
> Note:
>
> The `DOMElement rootNode` argument of `componentDidMount()` and
> `componentDidUpdate()` is a convenience. The same node can be obtained by
> calling `this.getDOMNode()`.
## Component Refs
A common use case of event callbacks or the lifecycle methods is to operate on a
component returned by `render()`. For example, consider a search component that
should auto-focus the input once mounted:
```javascript
var SearchForm = React.createClass({
render: function() {
return (
<form action={this.props.action}>
<input type="search" placeholder="Search..." />
</form>
);
},
componentDidMount: function(rootNode) {
var searchInput = rootNode.firstChild;
searchInput.focus();
}
});
```
Although this implementation works, it is fragile because `componentDidMount()`
now relies on `render()` returning a particular DOM structure.
React provides a better way for composite components to reference components
that it constructs in its `render()` method through the use of refs. A component
can assign a `ref` to any component it constructs. This will create a reference
to those components on `this.refs`. For example:
```javascript{5,10}
var SearchForm = React.createClass({
render: function() {
return (
<form action={this.props.action}>
<input type="search" placeholder="Search..." ref="searchInput" />
</form>
);
},
componentDidMount: function(rootNode) {
var searchInput = this.refs.searchInput.getDOMNode();
searchInput.focus();
}
});
```
In this example, `this.refs.searchInput` will reference the `<input>` component
and is available in most lifecycle methods and event callbacks. We obtain a
reference to the `<input>`'s DOM node using `getDOMNode()`.
> Note:
>
> If you want to preserve compatibility with Google Closure Compiler's
> property crushing in `ADVANCED_OPTIMIZATIONS` mode, make sure to use string
> literals with `this.refs`.

View File

@@ -1,150 +0,0 @@
---
id: docs-api
title: React API
layout: docs
prev: mixins.html
---
## React
`React` is the entry point to the React framework. If you're using one of the prebuilt packages it's available as a global; if you're using CommonJS modules you can `require()` it.
#### React.DOM
`React.DOM` provides all of the standard HTML tags needed to build a React app. You generally don't use it directly; instead, just include it as part of the `/** @jsx React.DOM */` docblock.
#### React.initializeTouchEvents
```javascript
initializeTouchEvents(boolean shouldUseTouch)
```
Configure React's event system to handle touch events on mobile devices.
#### React.autoBind
```javascript
function autoBind(function method)
```
Marks the provided function to be automatically bound to each React component instance created. This allows React components to define automatically bound methods and ensure that when called they will always reference their current instance.
Example:
```javascript
React.createClass({
click: React.autoBind(function(evt) {
this.setState({jumping: true});
}),
render: function() {
// Look: no bind!
return <a onClick={this.click}>Jump</a>;
}
});
```
#### React.createClass
```javascript
function createClass(object specification)
```
Creates a component given a specification. A component implements a `render` method which returns a single child. That child may have an arbitrarily deep child structure. One thing that makes components different than a standard prototypal classes is that you don't need to call new on them. They are convenience wrappers that construct backing instances (via new) for you.
#### React.renderComponent
```javascript
ReactComponent renderComponent(ReactComponent container, DOMElement mountPoint)
```
Renders a React component into the DOM in the supplied `container`.
If the React component was previously rendered into `container`, this will perform an update on it and only mutate the DOM as necessary to reflect the latest React component.
## AbstractEvent
Your event handlers will be passed instances of `AbstractEvent`, a cross-browser wrapper around the browser's native event. It has the same interface as the browser's native event (such as `stopPropagation()` and `preventDefault()`) except they work exactly the same across all browsers.
If you find that you need the underlying browser event for some reason, simply use the `nativeEvent` attribute to get it.
## ReactComponent
Component classses created by `createClass()` return instances of `ReactComponent` when called. Most of the time when you're using React you're either creating or consuming `ReactComponent`s.
#### getDOMNode
```javascript
DOMElement getDOMNode()
```
If this component has been mounted into the DOM, this returns the corresponding native browser DOM element. This method is useful for reading values out of the DOM, such as form field values and performing DOM measurements.
#### setProps
```javascript
setProps(object nextProps)
```
When you're integrating with an external JavaScript application you may want to signal a change to a React component rendered with `renderComponent()`. Simply call `setProps()` to change its properties and trigger a re-render.
**Note:** This method can only be called on a root-level component. That is, it's only available on the component passed directly to `renderComponent()` 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()`.
#### replaceProps
```javascript
replaceProps(object nextProps)
```
Like `setProps()` but deletes any pre-existing props that are not in nextProps.
#### transferPropsTo
```javascript
ReactComponent transferPropsTo(ReactComponent targetComponent)
```
Transfer properties from this component to a target component that have not already been set on the target component. This is usually used to pass down properties to the returned root component. `targetComponent`, now updated with some new props is returned as a convenience.
#### setState
```javascript
setState(object nextState)
```
Merges nextState with the current state. This is the primary method you use to trigger UI updates from event handlers and server request callbacks.
**Note:** *NEVER* mutate `this.state` directly. As calling `setState()` afterwards may replace the mutation you made. Treat `this.state` as if it were immutable.
**Note:** `setState()` does not immediately mutate `this.state` but creates a pending state transition. Accessing `this.state` after calling this method can potentially return the existing value.
#### replaceState
```javascript
replaceState(object nextState)
```
Like `setState()` but deletes any pre-existing state keys that are not in nextState.
#### forceUpdate()
```javascript
forceUpdate()
```
If your `render()` method reads from something other than `this.props` or `this.state` you'll need to tell React when it needs to re-run `render()`. Use `forceUpdate()` to cause React to automatically re-render. This will cause `render()` to be called on the component and all of its children but React will only update the DOM if the markup changes.
Normally you should try to avoid all uses of `forceUpdate()` and only read from `this.props` and `this.state` in `render()`. This makes your application much simpler and more efficient.
```javascript
object getInitialState()
componentWillMount()
componentDidMount(DOMElement domNode)
componentWillReceiveProps(object nextProps)
boolean shouldComponentUpdate(object nextProps, object nextState)
componentWillUpdate(object nextProps, object nextState)
ReactComponent render()
componentDidUpdate(object prevProps, object prevState, DOMElement domNode)
componentWillUnmount()
```
See the [advanced components](advanced-components.html) documentation for more details on these lifecycle methods.

View File

@@ -1,28 +0,0 @@
---
id: docs-common-questions
title: Common Questions
layout: docs
prev: tutorial.html
next: syntax.html
---
### What browsers does React support?
React supports the latest two Chrome, Firefox, Safari, and Internet Explorer versions. React can work with Internet Explorer 8 with polyfills.
### How do I get React to support Internet Explorer 8?
React requires ES5 JavaScript shims to run in Internet Explorer 8. Include the [ES5 Shims](https://github.com/kriskowal/es5-shim) to implement these shims.
### Who uses React?
The [Instagram](http://instagram.com/) website is built entirely in React. The [Facebook](https://www.facebook.com/) website is also increasingly using React, including the common commenting plugin across the site.
### I don't get it. React is confusing!
[This blog post by a member of the React team](http://www.quora.com/Pete-Hunt/Posts/React-Under-the-Hood) talks about some of the reasons
why React is designed the way that it is.
### Can I integrate with other JavaScript libraries?
Absolutely! In fact, we encourage it! See [our GitHub repo](http://github.com/facebook/react/) for a [TodoMVC example using Backbone](https://github.com/facebook/react/tree/master/examples/todomvc-backbone) and a [jQuery + Bootstrap modal demo](https://github.com/facebook/react/tree/master/examples/jquery-bootstrap).

View File

@@ -1,73 +0,0 @@
---
id: docs-component-basics
title: Component Basics
description: What are components?
layout: docs
next: component-data.html
prev: syntax.html
---
_Components_ are the basic units of composition in React. Components encapsulate
the logic necessary to take input parameters and render markup. Components can
be rendered into an existing DOM element on the page by using
`React.renderComponent`:
```javascript
// Replaces everything in `document.body` with <div>Hello, world!</div>;
React.renderComponent(<div>Hello, world!</div>, document.body);
```
Keep in mind that `<div>` is **not** a DOM element! Keep reading...
## Types of Components
There are two types of components:
- **Composite Components**
- **DOM Components**
### Composite Components <small>such as `TodoApp` and `Typeahead`.</small>
The majority of your React code will be implementing composite components.
Composite components are higher-level components with custom rendering logic
that may compose other composite components or DOM components.
```javascript
/** @jsx React.DOM */
var LinkButton = React.createClass({
render: function() {
return <a className="btn" />;
}
});
var myButton = <LinkButton />;
```
This example defines a `LinkButton` component class using `React.createClass()`,
and its `render()` method composes the `<a>` DOM component.
### DOM Components <small>such as `div` and `span`.</small>
DOM components are the set of classes that correspond to browser DOM elements.
They are defined in `React.DOM` and can be brought "into scope" by setting
`@jsx React.DOM` in the docblock. See [JSX Syntax](syntax.html) for more
details.
Although `React.DOM` components look like browser DOM elements, they differ in a
few ways:
- All property names, including event handlers, are camelCased.
- JavaScript identifiers should be used, namely `className` and `htmlFor`.
- The `style` prop expects an object instead of a string. The object should map
camelCased style properties to values, e.g. `{backgroundColor: '#fff'}`.
Here is an example of a React link styled as a button with a click handler:
```javascript
/** @jsx React.DOM */
var handleClick = function() {alert('Clicked!');};
var inlineStyle = {textDecoration: 'none'};
var myLink = <a className="btn" onClick={handleClick} style={inlineStyle} />;
```

View File

@@ -1,145 +0,0 @@
---
id: docs-component-data
title: Component Data
description: How is data passed into a component?
layout: docs
prev: component-basics.html
next: component-lifecycle.html
---
## Props
Components use data to determine what should be rendered. For example:
```javascript
var LikeLink = React.createClass({
render: function() {
var text = this.props.liked ? 'Liked' : 'Like';
return <a>{text}</a>;
}
});
var myLikeLink = <LikeLink liked={false} />;
```
In this example, `LikeLink` takes `liked` as boolean data. This type of data
that is passed in is called a "prop". Examples of props on DOM components
include `className` and `onClick`.
Whenever a component's props change, its `render()` function will be
re-evaluated and the DOM will be updated. React will ensure that the DOM is
always kept up-to-date.
## State
Let's build a small `LikeApp` application that makes use of the `<LikeLink>`
component from above. It should start off unliked and we should be able to like
it by clicking the link:
```javascript
var LikeApp = React.createClass({
render: function() {
var isClicked = false;
return <LikeLink liked={isClicked} onClick={this.handleClick.bind(this)} />;
},
handleClick: function() {
// Somehow update `isClicked`.
}
});
```
This renders a `<LikeLink>` with a click listener. However, it is not clear how
`handleClick` should update `isClicked` to true. `LikeApp` needs a way to store
**state** about whether or not it has been clicked.
### State vs. Props
State is data that is managed _internally_ by a composite component. Like props,
the `render()` function will be re-evaluated whenever state changes. Props and
state differ in that:
- Props are passed in from the creator.
- State is private to and managed by the component.
### Managing State
Let's update our `LikeApp` component using state:
```javascript{2-4,6,10}
var LikeApp = React.createClass({
getInitialState: function() {
return {isClicked: false};
},
render: function() {
var isClicked = this.state.isClicked;
return <LikeLink liked={isClicked} onClick={this.handleClick.bind(this)} />;
},
handleClick: function() {
this.setState({isClicked: true});
}
});
```
There's a lot going on here, so let's work our way from top to bottom:
- `getInitialState()` describes what state data looks like when the component
is created.
- In `render()`, state data can be accessed via `this.state`.
- When the link is clicked, we update state using `setState()`.
Now when we click the link, the `<LikeLink>` will get updated, right? Wrong.
## Transferring Props
If you have been following carefully, you may have noticed that although we pass
a click handler into `<LikeLink>` as a prop, `LikeLink` does not do anything
with `this.props.onClick`! Let's fix that.
```javascript{4}
var LikeLink = React.createClass({
render: function() {
var text = this.props.liked ? 'Liked' : 'Like';
return <a onClick={this.props.onClick}>{text}</a>;
}
});
```
Although this works, realize that this would quickly become tedious if we wanted
to also transfer `href`, `title`, `target`, and other events from `this` to the
rendered `<a>`. React provides a convenience method, `transferPropsTo()`, for
transferring props:
```javascript{4}
var LikeLink = React.createClass({
render: function() {
var text = this.props.liked ? 'Liked' : 'Like';
return this.transferPropsTo(<a>{text}</a>);
}
});
```
This will transfer all props from `this` to the specified component (including
`onClick`).
## Summary
Now we are done. `LikeApp` renders an unliked link which, when clicked, will:
1. Update the internal state of `LikeApp`.
2. Change the props passed into `LikeLink`.
3. Change the return value of `render()`.
4. Trigger an update to the DOM.
It's worth noting that React will handle new return values of `render()` by
making the minimal set of mutations necessary to bring the DOM up-to-date. In
this case, only the `textContent` of the rendered link will be mutated.
In summary:
- Props are passed in whereas state is managed internally by a component.
- Never mutate `this.props` or `this.state`. You should pass props into other
components and mutate state using `setState()`.
- State is private. Never read `state` or call `setState()` on
anything but `this`.
- Whenever props or state changes, `render()` will be re-evaluated and the DOM
updated. Also, `render()` should not depend on anything besides `this.props`
and `this.state`.

View File

@@ -1,85 +0,0 @@
---
id: docs-component-lifecycle
title: Component Lifecycle
description: What happens when I render a React component?
layout: docs
prev: component-data.html
next: event-handling.html
---
## Mounting
[We have previously seen](component-basics.html) how to render components into
existing DOM elements on the page:
```javascript
React.renderComponent(<div>Hello, world!</div>, document.body);
```
In this one simple line, we have accomplished the following:
- A `<div>` (defined by `React.DOM.div`) component is instantiated.
- The component is **mounted** into `document.body`.
**Mounting** is the process of initializing a React component by creating its
DOM nodes and inserting the them into a supplied container node.
At this point, the entire page consists of a single `<div>` with "Hello,
world!".
## Updating
Let's add a second call to `React.renderComponent()` after three
seconds:
```javascript{2-4}
React.renderComponent(<div>Hello, world!</div>, document.body);
setTimeout(function() {
React.renderComponent(<div>Goodbye, world.</div>, document.body);
}, 3000);
```
The second call to `React.renderComponent()` will trigger the following:
- The `<div>` component will check the new props to see if anything changed.
- The set of changes are used to **update** the DOM node as necessary.
**Updating** is the process of mutating the rendered DOM nodes and occurs
whenever either props or state has changed. This ensures that the rendered DOM
is consistent with the data.
## Unmounting
Let's add one final call to `React.renderComponent()` after another three
seconds:
```javascript{5-7}
React.renderComponent(<div>Hello, world!</div>, document.body);
setTimeout(function() {
React.renderComponent(<div>Goodbye, world.</div>, document.body);
}, 3000);
setTimeout(function() {
React.renderComponent(<img src="/images/fin.png" />, document.body);
}, 6000);
```
The third call to `React.renderComponent()` will trigger the following:
- An `<img>` (defined by `React.DOM.img`) component is instantiated.
- React will compare the `<div>` component with the `<img>` component.
- Since the component class is different, the `<div>` component will be
**unmounted**.
- The `<img>` component will then be mounted into `document.body`.
**Unmounting** is the process of releasing resources that have been allocated by
a component. This allows user interfaces built with React to live long without
memory leaks.
Components can also be unmounted using
`React.unmountAndReleaseReactRootNode()`:
```javascript
React.unmountAndReleaseReactRootNode(document.body);
```
This will unmount any components mounted immediately within `document.body`.

View File

@@ -1,224 +0,0 @@
---
id: docs-event-handling
title: Event Handling
description: How do events work with React components?
layout: docs
prev: component-lifecycle.html
next: advanced-components.html
---
Events in React work the way they do with HTML, except the event names are
camelCased.
```javascript
var Clicker = React.createClass({
render: function() {
return <span onClick={this.handleClick}>Click me!</span>;
},
handleClick: function(event) {
alert('You clicked me!');
}
});
```
When `<Clicker>` is clicked, the `handleClick()` function will get fired. Under
the hood, React uses top-level event delegation to achieve high performance.
## Automatically Binding Callbacks
Just like any callback in JavaScript, if you want to refer to the component as
`this` from the callback, you need to bind the callback to the component:
```javascript{3}
var Clicker = React.createClass({
render: function() {
var handleClick = this.handleClick.bind(this);
return <span onClick={handleClick}>Click me!</span>;
},
handleClick: function(event) {
alert(this.ALERT_MESSAGE);
},
ALERT_MESSAGE: 'You clicked me!'
});
```
React provides a convenient and _efficient_ way to bind methods using
`React.autoBind()`:
```javascript{3,5-7}
var Clicker = React.createClass({
render: function() {
return <span onClick={this.handleClick}>Click me!</span>;
},
handleClick: React.autoBind(function(event) {
alert(this.ALERT_MESSAGE);
}),
ALERT_MESSAGE: 'You clicked me!'
});
```
> Note:
>
> Binding a function allocates memory to create a new bound function. Since
> `render()` may be invoked many times, it is a bad place to bind functions.
> `React.autoBind()` sidesteps this issue by only binding once at instantiation
> time.
## DOM Events
React uses [top-level event delegation](http://davidwalsh.name/event-delegate)
to achieve high performance when implementing DOM events. For each type of DOM
event, React adds a single top-level listener and determines which event
handlers to execute by simulating event capturing and bubbling.
DOM event handlers are called with a normalized `AbstractEvent` object that has
cross-browser compatible implementations of `stopPropagation` and
`preventDefault()`. If you need access to the raw browser event, you can use the
`nativeEvent` property.
> Note:
>
> The `AbstractEvent` object is JSON serializable so that React applications can
> be executed inside web workers.
### Touch Events
If you want to use touch events, you must configure React's event system to
initialize them:
```javascript
// Invoke before calling `React.renderComponent()`.
React.initializeTouchEvents(true);
```
## Custom Events
Notice that event listeners are attached by simply passing them into components
as props. For DOM components, events are handled using top-level event
delegation. For composite components, event handling is up to the component's
implementation.
Here is an example of a toggle link that fires a custom `onToggle` event:
```javascript
var ToggleLink = React.createClass({
getInitialState: function() {
return {isEnabled: false};
},
render: function() {
return <a onClick={this.handleClick}>Toggle</a>;
},
handleClick: React.autoBind(function() {
var willEnable = !this.state.isEnabled;
if (this.props.onToggle) {
this.props.onToggle(willEnable)
}
this.setState({isEnabled: willEnable});
})
});
var handleToggle = function(enabled) {
alert(enabled ? 'Enabled.' : 'Disabled.');
};
var myToggleLink = <ToggleLink onToggle={handleToggle} />;
```
### Common Patterns
With React your event handlers should be quite small. Large event handlers may
be symptomatic of code that should be moved into helpers or into `render()`.
Here are some common usage patterns for event handlers.
#### Updating State
The most common thing to do in response to a user action is to call
`this.setState()` to update the component's state, which will in turn trigger
an update to the rendered component.
#### Server Requests
Many event handlers will issue a server request to read or write some data in
response to an event. The response handler for the request will often call
`this.setState()`.
#### Invoke a Callback
Your component will often be a small, reusable building block that does not know
how to respond to a user action. In these situations, we delegate the
responsibility to the owner by exposing a handler on `this.props`. This is what
the `ToggleLink` example above is doing.
#### Inter-component Communication
A common scenario involves communicating to **Component A** that a user action
has occurred on **Component B**. To solve this problem, a common parent to
both components should listen for the event on **Component B**, update its
internal state, and pass that data into **Component A**.
For example, say we have two components: **Clicker**, a component that fires an
`onCountChange` custom event, and **ClickCountLabel**, a component that displays
the number of clicks that have happened:
```javascript
var Clicker = React.createClass({
getInitialState: function() {
return {count: 0};
},
render: function() {
return <span onClick={this.handleClick}>Click me!</span>;
},
handleClick: React.autoBind(function() {
this.setState({count: this.state.count + 1});
if (this.props.onCountChange) {
this.props.onCountChange(this.state.count);
}
})
});
var ClickCountLabel = React.createClass({
render: function() {
return <p>You have clicked <strong>{this.props.count}</strong> times.</p>;
}
});
var ClickApp = React.createClass({
render: function() {
var count = 0;
return (
<div>
<Clicker onCountChange={this.handleCountChange} />
<ClickCountLabel count={count} />
</div>
);
},
handleCountChange: React.autoBind(function(count) {
// Somehow update `count`.
})
});
```
In order to communicate the click count from `Clicker` to `ClickCountLabel`, we
modify `ClickApp` to maintain state that will be passed into `ClickCountLabel`:
```javascript{2-4,6,15}
var ClickApp = React.createClass({
getInitialState: function() {
return {count: 0};
},
render: function() {
var count = this.state.count;
return (
<div>
<Clicker onCountChange={this.handleCountChange} />
<ClickCountLabel count={count} />
</div>
);
},
handleCountChange: React.autoBind(function(count) {
this.setState({count: count});
})
});
```
Now when `Clicker` fires the `onCountChange` event, the `ClickCountLabel` will
get updated!

View File

@@ -1,5 +1,5 @@
---
id: docs-getting-started
id: getting-started
title: Getting Started
layout: docs
next: tutorial.html
@@ -44,7 +44,7 @@ In the root directory of the starter kit, create a `helloworld.html` with the fo
</html>
```
The XML syntax inside of JavaScript is called JSX; check out the [JSX syntax](syntax.html) to learn more about it. In order to translate it to vanilla JavaScript we use `<script type="text/jsx">` and include `JSXTransformer.js` to actually perform the transformation in the browser.
The XML syntax inside of JavaScript is called JSX; check out the [JSX syntax](jsx-in-depth.html) to learn more about it. In order to translate it to vanilla JavaScript we use `<script type="text/jsx">` and include `JSXTransformer.js` to actually perform the transformation in the browser.
### Separate File
@@ -84,10 +84,14 @@ The file `build/helloworld.js` is autogenerated whenever you make a change.
/** @jsx React.DOM */
React.renderComponent(
React.DOM.h1(null, 'Hello, world!'),
document.getElementyById('example')
document.getElementById('example')
);
```
> Note:
>
> The comment parser is very strict right now, in order for it to pick up the `@jsx` modifier, two conditions are required. The `@jsx` comment block must be the first comment on the file. The comment must start with `/**` (`/*` and `//` will not work). If the parser can't find the `@jsx` comment, it will output the file without transforming it.
Update your HTML file as below:
```html{6,10}

4
docs/docs/index.html Normal file
View File

@@ -0,0 +1,4 @@
---
layout: redirect
destination: getting-started.html
---

View File

@@ -1,65 +0,0 @@
---
id: docs-mixins
title: Mixins
layout: docs
prev: advanced-components.html
next: api.html
---
Mixins allow code to be shared between multiple React components. They are pretty similar to mixins
in Python or traits in PHP. Let's look at a simple example:
```javascript
var MyMixin = {
getMessage: function() {
return 'hello world';
}
};
var MyComponent = React.createClass({
mixins: [MyMixin],
render: function() {
return <div>{this.getMessage()}</div>;
}
});
```
A class can use multiple mixins, but no two mixins can define the same method. Two mixins can, however,
implement the same [lifecycle method](component-lifecycle.html). In this case, each implementation will be invoked one after another.
The only exception is the `shouldComponentUpdate` lifecycle method. This method may only be implemented once
(either by a mixin or by the component).
```javascript
var Mixin1 = {
componentDidMount: function() {
console.log('Mixin1.componentDidMount()');
}
};
var Mixin2 = {
componentDidMount: function() {
console.log('Mixin2.componentDidMount()');
}
};
var MyComponent = React.createClass({
mixins: [Mixin1, Mixin2],
render: function() {
return <div>hello world</div>;
}
});
```
When `MyComponent` is mounted into the page, the following text will print to the console:
```
Mixin1.componentDidMount()
Mixin2.componentDidMount()
```
## When should you use mixins?
In general, add a mixin whenever you want a component to share some utility methods, public interface,
or lifecycle behavior. Often it's appropriate to use them as you would use a superclass in another OOP language.

View File

@@ -0,0 +1,73 @@
---
id: top-level-api
title: Top-Level API
layout: docs
permalink: top-level-api.html
next: component-api.html
---
## React
`React` is the entry point to the React framework. If you're using one of the prebuilt packages it's available as a global; if you're using CommonJS modules you can `require()` it.
### React.DOM
`React.DOM` provides all of the standard HTML tags needed to build a React app. You generally don't use it directly; instead, just include it as part of the `/** @jsx React.DOM */` docblock.
### React.initializeTouchEvents
```javascript
initializeTouchEvents(boolean shouldUseTouch)
```
Configure React's event system to handle touch events on mobile devices.
### React.createClass
```javascript
function createClass(object specification)
```
Creates a component given a specification. A component implements a `render` method which returns **one single** child. That child may have an arbitrarily deep child structure. One thing that makes components different than standard prototypal classes is that you don't need to call new on them. They are convenience wrappers that construct backing instances (via new) for you.
For more information about the specification object, see [Component Specs and Lifecycle](component-specs.html).
### React.renderComponent
```javascript
ReactComponent renderComponent(
ReactComponent component,
DOMElement container,
[function callback]
)
```
Renders a React component into the DOM in the supplied `container`.
If the React component was previously rendered into `container`, this will perform an update on it and only mutate the DOM as necessary to reflect the latest React component.
If the optional callback is provided, it will be executed after the component is rendered or updated.
### React.unmountAndReleaseReactRootNode
```javascript
unmountAndReleaseReactRootNode(DOMElement container)
```
Remove a mounted React component from the DOM and clean up its event handlers and state.
### React.renderComponentToString
```javascript
renderComponentToString(ReactComponent component, function callback)
```
Render a component to its initial HTML. This should only be used on the server. React will call `callback` with an HTML string when the markup is ready. You can use this method to can generate HTML on the server and send the markup down on the initial request for faster page loads and to allow search engines to crawl your pages for SEO purposes.
If you call `React.renderComponent()` on a node that already has this server-rendered markup, React will preserve it and only attach event handlers, allowing you to have a very performant first-load experience.

View File

@@ -0,0 +1,109 @@
---
id: component-api
title: Component API
layout: docs
permalink: component-api.html
prev: top-level-api.html
next: component-specs.html
---
## ReactComponent
Component classses created by `createClass()` return instances of `ReactComponent` when called. Most of the time when you're using React you're either creating or consuming these component objects.
### getDOMNode
```javascript
DOMElement getDOMNode()
```
If this component has been mounted into the DOM, this returns the corresponding native browser DOM element. This method is useful for reading values out of the DOM, such as form field values and performing DOM measurements.
### setProps
```javascript
setProps(object nextProps)
```
When you're integrating with an external JavaScript application you may want to signal a change to a React component rendered with `renderComponent()`. Simply call `setProps()` to change its properties and trigger a re-render.
> Note:
>
> This method can only be called on a root-level component. That is, it's only available on the component passed directly to `renderComponent()` 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()`.
### replaceProps
```javascript
replaceProps(object nextProps)
```
Like `setProps()` but deletes any pre-existing props instead of merging the two objects.
### transferPropsTo
```javascript
ReactComponent transferPropsTo(ReactComponent targetComponent)
```
Transfer properties from this component to a target component that have not already been set on the target component. After the props are updated, `targetComponent` is returned as a convenience. This function is useful when creating simple HTML-like components:
```javascript
var Avatar = React.createClass({
render: function() {
return this.transferPropsTo(
<img src={"/avatars/" + this.props.userId + ".png"} userId={null} />
);
}
});
// <AvatarImage userId={17} width={200} height={200} />
```
Properties that are specified directly on the target component instance (such as `src` and `userId` in the above example) will not be overwritten by `transferPropsTo`.
> Note:
>
> Use `transferPropsTo` with caution; it encourages tight coupling and makes it easy to accidentally introduce implicit dependencies between components. When in doubt, it's safer to explicitly copy the properties that you need onto the child component.
### setState
```javascript
setState(object nextState[, function callback])
```
Merges nextState with the current state. This is the primary method you use to trigger UI updates from event handlers and server request callbacks. In addition, you can supply an optional callback function that is executed once `setState` is completed.
> Notes:
>
> *NEVER* mutate `this.state` directly, as calling `setState()` afterwards may replace the mutation you made. Treat `this.state` as if it were immutable.
>
> `setState()` does not immediately mutate `this.state` but creates a pending state transition. Accessing `this.state` after calling this method can potentially return the existing value.
>
> There is no guarantee of synchronous operation of calls to `setState` and calls may be batched for performance gains.
### replaceState
```javascript
replaceState(object nextState[, function callback])
```
Like `setState()` but deletes any pre-existing state keys that are not in nextState.
### forceUpdate()
```javascript
forceUpdate([function callback])
```
If your `render()` method reads from something other than `this.props` or `this.state`, you'll need to tell React when it needs to re-run `render()` by calling `forceUpdate()`. You'll also need to call `forceUpdate()` if you mutate `this.state` directly.
Calling `forceUpdate()` will cause `render()` to be called on the component and its children, but React will still only update the DOM if the markup changes.
Normally you should try to avoid all uses of `forceUpdate()` and only read from `this.props` and `this.state` in `render()`. This makes your application much simpler and more efficient.

View File

@@ -0,0 +1,176 @@
---
id: component-specs
title: Component Specs and Lifecycle
layout: docs
permalink: component-specs.html
prev: component-api.html
next: tags-and-attributes.html
---
## Component Specifications
When creating a component class by invoking `React.createClass()`, you should provide a specification object that contains a `render` method and can optionally contain other lifecycle methods described here.
### render
```javascript
ReactComponent render()
```
The `render()` method is required.
When called, it should examine `this.props` and `this.state` and return a single child component. This child component can be either a native DOM component (such as `<div>`) or another composite component that you've defined yourself.
The `render()` function should be *pure*, meaning that it does not modify component state, it returns the same result each time it's invoked, and it does not read from or write to the DOM or otherwise interact with the browser (e.g., by using `setTimeout`). If you need to interact with the browser, perform your work in `componentDidMount()` or the other lifecycle methods instead. Keeping `render()` pure makes server rendering more practical and makes components easier to think about.
### getInitialState
```javascript
object getInitialState()
```
Invoked once when the component is mounted. The return value will be used as the initial value of `this.state`.
### getDefaultProps
```javascript
object getDefaultProps()
```
Invoked once when the component is mounted. Values in the mapping will be set on `this.props` if that prop is not specified by the parent component (i.e. using an `in` check).
This method is invoked before `getInitialState` and therefore cannot rely on `this.state` or use `this.setState`.
### propTypes
```javascript
object propTypes
```
The `propTypes` object allows you to validate props being passed to your components. For more information about `propTypes`, see [Reusable Components](reusable-components.html).
<!-- TODO: Document propTypes here directly. -->
### mixins
```javascript
array mixins
```
The `mixins` array allows you to use mixins to share behavior among multiple components. For more information about mixins, see [Reusable Components](reusable-components.html).
<!-- TODO: Document mixins here directly. -->
## Lifecycle Methods
Various methods are executed at specific points in a component's lifecycle.
### Mounting: componentWillMount
```javascript
componentWillMount()
```
Invoked immediately before 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.
### Mounting: componentDidMount
```javascript
componentDidMount(DOMElement rootNode)
```
Invoked immediately after rendering occurs. At this point in the lifecycle, the component has a DOM representation which you can access via the `rootNode` argument or by calling `this.getDOMNode()`.
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.
### Updating: componentWillReceiveProps
```javascript
componentWillReceiveProps(object nextProps)
```
Invoked when a component is receiving new props. This method is not called for the initial render.
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.
```javascript
componentWillReceiveProps: function(nextProps) {
this.setState({
likesIncreasing: nextProps.likeCount > this.props.likeCount
});
}
```
> Note:
>
> 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`.
### Updating: shouldComponentUpdate
```javascript
boolean shouldComponentUpdate(object nextProps, object nextState)
```
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.
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.
```javascript
shouldComponentUpdate: function(nextProps, nextState) {
return !equal(nextProps, this.props) || !equal(nextState, this.state);
}
```
If `shouldComponentUpdate` returns false, then `render()` will be completely skipped until the next state change. (In addition, `componentWillUpdate` and `componentDidUpdate` will not be called.)
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.
If performance is a bottleneck, especially with dozens or hundreds of components, use `shouldComponentUpdate` to speed up your app.
### Updating: componentWillUpdate
```javascript
componentWillUpdate(object nextProps, object nextState)
```
Invoked immediately before rendering when new props or state are being received. This method is not called for the initial render.
Use this as an opportunity to perform preparation before an update occurs.
> Note:
>
> You *cannot* use `this.setState()` in this method. If you need to update state in response to a prop change, use `componentWillReceiveProps` instead.
### Updating: componentDidUpdate
```javascript
componentDidUpdate(object prevProps, object prevState, DOMElement rootNode)
```
Invoked immediately after updating occurs. This method is not called for the initial render.
Use this as an opportunity to operate on the DOM when the component has been updated.
### Unmounting: componentWillUnmount
```javascript
componentWillUnmount()
```
Invoked immediately before a component is unmounted from the DOM.
Perform any necessary cleanup in this method, such as invalidating timers or cleaning up any DOM elements that were created in `componentDidMount`.

View File

@@ -0,0 +1,65 @@
---
id: tags-and-attributes
title: Tags and Attributes
layout: docs
permalink: tags-and-attributes.html
prev: component-specs.html
next: events.html
---
## Supported Tags
React attempts to support all common elements. If you need an element that isn't listed here, please file an issue.
The following elements are supported:
### HTML Elements
```
a abbr address area article aside audio b base bdi bdo big blockquote body br
button canvas caption cite code col colgroup data datalist dd del details dfn
div dl dt em embed fieldset figcaption figure footer form h1 h2 h3 h4 h5 h6
head header hr html i iframe img input ins kbd keygen label legend li link main
map mark menu menuitem meta meter nav noscript object ol optgroup option output
p param pre progress q rp rt ruby s samp script section select small source
span strong style sub summary sup table tbody td textarea tfoot th thead time
title tr track u ul var video wbr
```
### SVG elements
```
circle g line path polyline rect svg text
```
## Supported Attributes
React supports all `data-*` and `aria-*` attributes as well as every attribute
in the following lists. Note that all attributes are camel-cased and the attributes `class` and `for` are `className` and `htmlFor`, respectively, to match the DOM API specification.
For a list of events, see [Supported Events](events.html).
### HTML Attributes
```
accept accessKey action allowFullScreen allowTransparency alt autoCapitalize
autoComplete autoFocus autoPlay cellPadding cellSpacing charSet checked
className colSpan content contentEditable contextMenu controls data dateTime
dir disabled draggable encType form frameBorder height hidden href htmlFor
httpEquiv icon id label lang list max maxLength method min multiple name
pattern placeholder poster preload radioGroup readOnly rel required role
rowSpan scrollLeft scrollTop selected size spellCheck src step style tabIndex
target title type value width wmode
```
In addition, the non-standard `autoCapitalize` attribute is supported for Mobile Safari.
### SVG Attributes
```
cx cy d fill fx fy gradientTransform gradientUnits offset points r rx ry
spreadMethod stopColor stopOpacity stroke strokeLinecap strokeWidth transform
version viewBox x1 x2 x y1 y2 y
```

205
docs/docs/ref-05-events.md Normal file
View File

@@ -0,0 +1,205 @@
---
id: events
title: Event System
layout: docs
permalink: events.html
prev: tags-and-attributes.html
next: dom-differences.html
---
## SyntheticEvent
Your event handlers will be passed instances of `SyntheticEvent`, a cross-browser wrapper around the browser's native event. It has the same interface as the browser's native event, including `stopPropagation()` and `preventDefault()`, except the events work identically across all browsers.
If you find that you need the underlying browser event for some reason, simply use the `nativeEvent` attribute to get it. Every `SyntheticEvent` object has the following attributes:
```javascript
boolean bubbles
boolean cancelable
DOMEventTarget currentTarget
boolean defaultPrevented
Number eventPhase
boolean isTrusted
DOMEvent nativeEvent
void preventDefault()
void stopPropagation()
DOMEventTarget target
Date timeStamp
String type
```
## Supported Events
React normalizes events so that they have consistent properties across
different browsers.
### Clipboard Events
Event names:
```
onCopy onCut onPaste
```
Properties:
```javascript
DOMDataTransfer clipboardData
```
### Keyboard Events
Event names:
```
onKeyDown onKeyPress onKeyUp
```
Properties:
```javascript
boolean altKey
String char
boolean ctrlKey
String key
String locale
Number location
boolean metaKey
boolean repeat
boolean shiftKey
```
### Focus Events
Event names:
```
onFocus onBlur
```
Properties:
```javascript
DOMEventTarget relatedTarget
```
### Form Events
Event names:
```
onChange onInput onSubmit
```
For more information about the onChange event, see [Forms](forms.html).
### Mouse Events
Event names:
```
onClick onDoubleClick onDrag onDragEnd onDragEnter onDragExit onDragLeave
onDragOver onDragStart onDrop onMouseDown onMouseEnter onMouseLeave
onMouseMove onMouseUp
```
Properties:
```javascript
boolean altKey
Number button
Number buttons
Number clientX
Number clientY
boolean ctrlKey
boolean metaKey
Number pageX
Number pageY
DOMEventTarget relatedTarget
Number screenX
Number screenY
boolean shiftKey
```
### Mutation Events
Event names:
```
onDOMCharacterDataModified
```
Properties:
```javascript
Number attrChange
String attrName
String newValue
String prevValue
Node relatedNode
```
### Touch events
To enable touch events, call `React.initializeTouchEvents(true)` before
rendering any component.
Event names:
```
onTouchCancel onTouchEnd onTouchMove onTouchStart
```
Properties:
```javascript
boolean altKey
DOMTouchList changedTouches
boolean ctrlKey
boolean metaKey
boolean shiftKey
DOMTouchList targetTouches
DOMTouchList touches
```
### UI Events
Event names:
```
onScroll
```
Properties:
```javascript
Number detail
DOMAbstractView view
```
### Wheel Events
Event names:
```
onWheel
```
Properties:
```javascript
Number deltaX
Number deltaMode
Number deltaY
Number deltaZ
```

View File

@@ -0,0 +1,14 @@
---
id: dom-differences
title: DOM Differences
layout: docs
permalink: dom-differences.html
prev: events.html
---
React has implemented a browser-independent events and DOM system for performance and cross-browser compatibility reasons. We took the opportunity to clean up a few rough edges in browser DOM implementations.
* 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.
* 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.
* All event objects conform to the W3C spec, and all events (including submit) bubble correctly per the W3C spec. See [Event System](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](forms.html) for more details.

4
docs/docs/reference.html Normal file
View File

@@ -0,0 +1,4 @@
---
layout: redirect
destination: top-level-api.html
---

View File

@@ -1,11 +1,8 @@
---
id: docs-tutorial
id: tutorial
title: Tutorial
layout: docs
prev: getting-started.html
next: common-questions.html
---
We'll be building a simple, but realistic comments box that you can drop into a blog, similar to Disqus, LiveFyre or Facebook comments.
We'll provide:
@@ -20,11 +17,11 @@ It'll also have a few neat features:
* **Live updates:** as other users comment we'll pop them into the comment view in real time
* **Markdown formatting:** users can use Markdown to format their text
## Want to skip all this and just see the source?
### Want to skip all this and just see the source?
[It's all on GitHub.](https://github.com/petehunt/react-tutorial)
## Getting started
### Getting started
For this tutorial we'll use prebuilt JavaScript files on a CDN. Open up your favorite editor and create a new HTML document:
@@ -50,7 +47,7 @@ For this tutorial we'll use prebuilt JavaScript files on a CDN. Open up your fav
For the remainder of this tutorial, we'll be writing our JavaScript code in this script tag.
## Your first component
### Your first component
React is all about modular, composable components. For our comment box example, we'll have the following component structure:
@@ -80,7 +77,7 @@ React.renderComponent(
);
```
### JSX Syntax
#### JSX Syntax
The first thing you'll notice is the XML-ish syntax in your JavaScript. We have a simple precompiler that translates the syntactic sugar to this plain JavaScript:
@@ -102,19 +99,19 @@ React.renderComponent(
);
```
Its use is optional but we've found JSX syntax easier to use than plain JavaScript. Read more on the [JSX Syntax article](syntax.html).
Its use is optional but we've found JSX syntax easier to use than plain JavaScript. Read more on the [JSX Syntax article](jsx-in-depth.html).
### What's going on
#### What's going on
We pass some methods in a JavaScript object to `React.createClass()` to create a new React component. The most important of these methods is called `render` which returns a tree of React components that will eventually render to HTML.
The `<div>` tags are not actual DOM nodes; they are instantiations of React `div` components. You can think of these as markers or pieces of data that React knows how to handle. React is **safe**. We are not generating HTML strings so XSS protection is the default.
You do not have to return basic HTML. You can return a tree of components that you (or someone else built). This is what makes React **composable**: a key tenet of maintainable frontends.
You do not have to return basic HTML. You can return a tree of components that you (or someone else) built. This is what makes React **composable**: a key tenet of maintainable frontends.
`React.renderComponent()` instantiates the root component, starts the framework, and injects the markup into a raw DOM element, provided as the second argument.
# Composing components
## Composing components
Let's build skeletons for `CommentList` and `CommentForm` which will, again, be simple `<div>`s:
@@ -160,7 +157,7 @@ var CommentBox = React.createClass({
Notice how we're mixing HTML tags and components we've built. HTML components are regular React components, just like the ones you define, with one difference. The JSX compiler will automatically rewrite HTML tags to "React.DOM.tagName" expressions and leave everything else alone. This is to prevent the pollution of the global namespace.
## Component Properties
### Component Properties
Let's create our third component, `Comment`. We will want to pass it the author name and comment text so we can reuse the same code for each unique comment. First let's add some comments to the `CommentList`:
@@ -180,7 +177,7 @@ var CommentList = React.createClass({
Note that we have passed some data from the parent `CommentList` component to the child `Comment` component as both XML-like children and attributes. Data passed from parent to child is called **props**, short for properties.
## Using props
### Using props
Let's create the Comment component. It will read the data passed to it from the CommentList and render some markup:
@@ -202,11 +199,21 @@ var Comment = React.createClass({
By surrounding a JavaScript expression in braces inside JSX (as either an attribute or child), you can drop text or React components into the tree. We access named attributes passed to the component as keys on `this.props` and any nested elements as `this.props.children`.
## Adding Markdown
### Adding Markdown
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 **Showdown** library 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).
First, add the third-party **Showdown** library 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{6}
<!-- template.html -->
<head>
<title>Hello React</title>
<script src="http://fb.me/react-{{site.react_version}}.js"></script>
<script src="http://fb.me/JSXTransformer-{{site.react_version}}.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/showdown/0.3.1/showdown.min.js"></script>
</head>
```
Next, let's convert the comment text to Markdown and output it:
@@ -255,15 +262,15 @@ This is a special API that intentionally makes it difficult to insert raw HTML,
**Remember:** by using this feature you're relying on Showdown to be secure.
## Hook up the data model
### Hook up the data model
So far we've been inserting the comments directly in the source code. Instead, let's render a blob of JSON data into the comment list. Eventually this will come from the server, but for now, write it in your source:
```javascript
// tutorial8.js
var data = [
{author: 'Pete Hunt', text: 'This is one comment'},
{author: 'Jordan Walke', text: 'This is *another* comment'}
{author: "Pete Hunt", text: "This is one comment"},
{author: "Jordan Walke", text: "This is *another* comment"}
];
```
@@ -309,7 +316,7 @@ var CommentList = React.createClass({
That's it!
## Fetching from the server
### Fetching from the server
Let's replace the hard-coded data with some dynamic data from the server. We will remove the data prop and replace it with a URL to fetch:
@@ -317,13 +324,13 @@ Let's replace the hard-coded data with some dynamic data from the server. We wil
// tutorial11.js
React.renderComponent(
<CommentBox url="comments.json" />,
document.getElementById('example')
document.getElementById('content')
);
```
This component is different from the prior components because it will have to re-render itself. The component won't have any data until the request from the server comes back, at which point the component may need to render some new comments.
## Reactive state
### Reactive state
So far, each component has rendered itself once based on its props. `props` are immutable: they are passed from the parent and are "owned" by the parent. To implement interactions, we introduce mutable **state** to the component. `this.state` is private to the component and can be changed by calling `this.setState()`. When the state is updated, the component re-renders itself.
@@ -351,14 +358,14 @@ 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
#### 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. In a real application this would be a dynamic endpoint, but for this example, we will use a static JSON file to keep things simple:
```javascript
// tutorial13.json
[
{'author': 'Pete Hunt', 'text': 'This is one comment'},
{'author': 'Jordan Walke', 'text': 'This is *another* comment'}
{"author": "Pete Hunt", "text": "This is one comment"},
{"author": "Jordan Walke", "text": "This is *another* comment"}
]
```
@@ -435,13 +442,13 @@ React.renderComponent(
```
All we have done here is move the AJAX call to a separate method and call it when the component is first loaded and every 60 seconds after that. Try running this in your browser and changing the `comments.json` file; within 5 seconds, the changes will show!
All we have done here is move the AJAX call to a separate method and call it when the component is first loaded and every 5 seconds after that. Try running this in your browser and changing the `comments.json` file; within 5 seconds, the changes will show!
## Adding new comments
### Adding new comments
Now it's time to build the form. Our `CommentForm` component should ask the user for their name and comment text and send a request to the server to save the comment.
```javascript{5-8}
```javascript{5-9}
// tutorial15.js
var CommentForm = React.createClass({
render: function() {
@@ -461,7 +468,7 @@ Let's make the form interactive. When the user submits the form, we should clear
```javascript{3-13,16,21}
// tutorial16.js
var CommentForm = React.createClass({
handleSubmit: React.autoBind(function() {
handleSubmit: function() {
var author = this.refs.author.getDOMNode().value.trim();
var text = this.refs.text.getDOMNode().value.trim();
if (!text || !author) {
@@ -471,7 +478,7 @@ var CommentForm = React.createClass({
this.refs.author.getDOMNode().value = '';
this.refs.text.getDOMNode().value = '';
return false;
}),
},
render: function() {
return (
<form class="commentForm" onSubmit={this.handleSubmit}>
@@ -488,19 +495,17 @@ 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.
We always return `false` from the event handler to prevent the browser's default action of submitting the form. (If you prefer, you can instead take the event as an argument and call `preventDefault()` on it &ndash; read more about [event handling](event-handling.html).)
We always return `false` from the event handler to prevent the browser's default action of submitting the form. (If you prefer, you can instead take the event as an argument and call `preventDefault()` on it.)
`React.autoBind()` is a simple way to ensure that a method is always bound to its component. Inside the method, `this` will be bound to the component instance.
#### Refs
##### Refs
We use the `ref` attribute to assign a name to a child component and `this.refs` to reference the component. We can call `getDOMNode()` on a component to get the native browser DOM element.
#### 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.
@@ -519,9 +524,9 @@ var CommentBox = React.createClass({
}.bind(this)
});
},
handleCommentSubmit: React.autoBind(function(comment) {
handleCommentSubmit: function(comment) {
// TODO: submit to the server and refresh the list
}),
},
getInitialState: function() {
return {data: []};
},
@@ -551,14 +556,14 @@ Let's call the callback from the `CommentForm` when the user submits the form:
```javascript{6}
// tutorial18.js
var CommentForm = React.createClass({
handleSubmit: React.autoBind(function() {
handleSubmit: function() {
var author = this.refs.author.getDOMNode().value.trim();
var text = this.refs.text.getDOMNode().value.trim();
this.props.onCommentSubmit({author: author, text: text});
this.refs.author.getDOMNode().value = '';
this.refs.text.getDOMNode().value = '';
return false;
}),
},
render: function() {
return (
<form class="commentForm" onSubmit={this.handleSubmit}>
@@ -590,7 +595,7 @@ var CommentBox = React.createClass({
}.bind(this)
});
},
handleCommentSubmit: React.autoBind(function(comment) {
handleCommentSubmit: function(comment) {
$.ajax({
url: this.props.url,
data: comment,
@@ -600,7 +605,7 @@ var CommentBox = React.createClass({
this.setState({data: data});
}.bind(this)
});
}),
},
getInitialState: function() {
return {data: []};
},
@@ -625,7 +630,7 @@ var CommentBox = React.createClass({
});
```
## Optimization: optimistic updates
### Optimization: optimistic updates
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.
@@ -642,7 +647,7 @@ var CommentBox = React.createClass({
}.bind(this)
});
},
handleCommentSubmit: React.autoBind(function(comment) {
handleCommentSubmit: function(comment) {
var comments = this.state.data;
comments.push(comment);
this.setState({data: comments});
@@ -655,7 +660,7 @@ var CommentBox = React.createClass({
this.setState({data: data});
}.bind(this)
});
}),
},
getInitialState: function() {
return {data: []};
},
@@ -680,6 +685,6 @@ var CommentBox = React.createClass({
});
```
## Congrats!
### Congrats!
You have just built a comment box in a few simple steps. Learn more about React in the [reference](syntax.html) or start hacking! Good luck!
You have just built a comment box in a few simple steps. Learn more about [why to use React](why-react.html), or dive into the [API reference](top-level-api.html) and start hacking! Good luck!

View File

@@ -29,12 +29,14 @@ The uncompressed, development version of React core with inline documentation.
```
#### <a href="http://fb.me/JSXTransformer-{{site.react_version}}.js">JSX Transform</a>
The JSX transformer used to support [XML syntax](/react/docs/syntax.html) in JavaScript.
The JSX transformer used to support [XML syntax](/react/docs/jsx-in-depth.html) in JavaScript.
```html
<script src="http://fb.me/JSXTransformer-{{site.react_version}}.js"></script>
```
All scripts are also available via [CDNJS](http://cdnjs.com/#react).
## Bower
```sh
@@ -47,14 +49,3 @@ $ bower install --save react
$ npm install -g react-tools
```
## Release Notes
**0.3.2** Improve compatibility of JSX Transformer; make `react-tools` compatible with [browserify](https://github.com/substack/node-browserify)
**0.3.1** Fix `react-tools` module
**0.3** Initial public release.
**0.2** Standardize API & refactor component lifecycle. Normalize DOM interactions.
**0.1** Initial release.

BIN
docs/img/blog/chatapp.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

BIN
docs/img/blog/monkeys.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 532 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
docs/img/blog/quiztime.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
docs/img/blog/snake.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

BIN
docs/img/blog/todomvc.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

BIN
docs/img/blog/unite.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

BIN
docs/img/blog/xreact.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

View File

@@ -56,10 +56,11 @@ id: home
<div class="example">
<h3>An Application</h3>
<p>
Using properties and state, we can put together a small Todo
application. React provides an interface to the DOM via `refs`. Although
event handlers appear to be rendered inline, they will be
collected and implemented using event delegation.
Using `props` and `state`, we can put together a small Todo application.
This example uses `state` to track the current list of items as well as
the text that the user has entered. Although event handlers appear to be
rendered inline, they will be collected and implemented using event
delegation.
</p>
<div id="todoExample"></div>
</div>

View File

@@ -6,7 +6,7 @@ id: jsx-compiler
<div class="jsxCompiler">
<h1>JSX Compiler</h1>
<p>
This tool demonstrates how <a href="/react/docs/syntax.html">JSX syntax</a>
This tool demonstrates how <a href="/react/docs/jsx-in-depth.html">JSX syntax</a>
is desguared into native JavaScript.
</p>
<div id="jsxCompiler"></div>

View File

@@ -6,10 +6,20 @@ id: support
**React** is worked on full-time by Facebook's product infrastructure and Instagram's user interface engineering teams. They're often around and available for questions.
## Stack Overflow
Many members of the community use Stack Overflow to ask questions. Read through the [existing questions](http://stackoverflow.com/questions/tagged/reactjs) tagged with **reactjs** or [ask your own](http://stackoverflow.com/questions/ask)!
## Google Groups mailing list
<a href="http://groups.google.com/group/reactjs" target="_blank">The **reactjs** Google Group</a> is the best place to ask questions and find answers.
<a href="http://groups.google.com/group/reactjs" target="_blank">The **reactjs** Google Group</a> is also a good place to ask questions and find answers.
## IRC
Many developers and users idle on Freenode.net's IRC network in **[#reactjs on freenode](irc://chat.freenode.net/reactjs)**.
## Twitter
[**#reactjs** hash tag on Twitter](https://twitter.com/search?q=%23reactjs) is used to keep up with the latest React news.
<center><a class="twitter-timeline" data-dnt="true" data-chrome="nofooter noheader transparent" href="https://twitter.com/search?q=%23reactjs" data-widget-id="342522405270470656"></a></center>

View File

@@ -14,9 +14,9 @@ var BallmerPeakCalculator = React.createClass({
getInitialState: function() {
return {bac: 0};
},
handleChange: React.autoBind(function() {
this.setState({bac: this.refs.bac.getDOMNode().value});
}),
handleChange: function(event) {
this.setState({bac: event.target.value});
},
render: function() {
var bac;
var pct;
@@ -33,7 +33,7 @@ var BallmerPeakCalculator = React.createClass({
<h4>Compute your Ballmer Peak:</h4>
<p>
If your BAC is{' '}
<input ref="bac" type="text" onKeyUp={this.handleChange} value={this.state.bac} />
<input type="text" onChange={this.handleChange} value={this.state.bac} />
{', '}then <b>{pct}</b> of your lines of code will have bugs.
</p>
</div>

View File

@@ -14,7 +14,7 @@
<pre>
python -m SimpleHTTPServer
</pre>
and going to <a href="http://localhost:8080/">http://localhost:8080/</a>.
and going to <a href="http://localhost:8000/">http://localhost:8000/</a>.
</p>
</div>
<h4>Example Details</h4>

View File

@@ -54,7 +54,7 @@
<pre id="chromeServerCLI" class="codeBox">
cd /Path/To/This/File
python -m SimpleHTTPServer
open -a "Google Chrome" <a href="http://localhost:8080/">http://localhost:8080/</a>. </pre>
open -a "Google Chrome" <a href="http://localhost:8000/">http://localhost:8000/</a>. </pre>
</li>
</ol>
<h4 id="chromeErrorFooter" style="color: #733"></h4>

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