diff --git a/404.html b/404.html index 3fe9e1b951..fc4f4ec81f 100644 --- a/404.html +++ b/404.html @@ -63,7 +63,7 @@ diff --git a/acknowledgements.html b/acknowledgements.html index 7a9120d99d..8ec3ee005c 100644 --- a/acknowledgements.html +++ b/acknowledgements.html @@ -63,7 +63,7 @@ diff --git a/blog/2013/06/02/jsfiddle-integration.html b/blog/2013/06/02/jsfiddle-integration.html index f3f12649be..c8fa1de651 100644 --- a/blog/2013/06/02/jsfiddle-integration.html +++ b/blog/2013/06/02/jsfiddle-integration.html @@ -64,7 +64,7 @@ @@ -114,6 +114,8 @@

Recent posts

diff --git a/blog/2013/06/05/why-react.html b/blog/2013/06/05/why-react.html index 987a993fe4..7506f48682 100644 --- a/blog/2013/06/05/why-react.html +++ b/blog/2013/06/05/why-react.html @@ -65,7 +65,7 @@ and why would you want to use it? @@ -199,6 +199,8 @@ but if you are interested in the nuts and bolts

Recent posts

diff --git a/blog/2013/06/12/community-roundup.html b/blog/2013/06/12/community-roundup.html index e6dd08fd07..56a6dc6df8 100644 --- a/blog/2013/06/12/community-roundup.html +++ b/blog/2013/06/12/community-roundup.html @@ -64,7 +64,7 @@ @@ -159,6 +159,8 @@

Recent posts

diff --git a/blog/2013/06/19/community-roundup-2.html b/blog/2013/06/19/community-roundup-2.html index 63f17a685f..8140da9a70 100644 --- a/blog/2013/06/19/community-roundup-2.html +++ b/blog/2013/06/19/community-roundup-2.html @@ -64,7 +64,7 @@ @@ -186,6 +186,8 @@

Recent posts

diff --git a/blog/2013/06/21/react-v0-3-3.html b/blog/2013/06/21/react-v0-3-3.html index f22b236898..ee1013fa5b 100644 --- a/blog/2013/06/21/react-v0-3-3.html +++ b/blog/2013/06/21/react-v0-3-3.html @@ -64,7 +64,7 @@ @@ -130,6 +130,8 @@

Recent posts

diff --git a/blog/2013/06/27/community-roundup-3.html b/blog/2013/06/27/community-roundup-3.html index 5d12597c96..2ca4da4b93 100644 --- a/blog/2013/06/27/community-roundup-3.html +++ b/blog/2013/06/27/community-roundup-3.html @@ -64,7 +64,7 @@ @@ -195,6 +195,8 @@

Recent posts

diff --git a/blog/2013/07/02/react-v0-4-autobind-by-default.html b/blog/2013/07/02/react-v0-4-autobind-by-default.html index 59e6483fdf..f773c884ed 100644 --- a/blog/2013/07/02/react-v0-4-autobind-by-default.html +++ b/blog/2013/07/02/react-v0-4-autobind-by-default.html @@ -64,7 +64,7 @@ @@ -144,6 +144,8 @@

Recent posts

diff --git a/blog/2013/07/03/community-roundup-4.html b/blog/2013/07/03/community-roundup-4.html index e0d92d6804..7add46caf9 100644 --- a/blog/2013/07/03/community-roundup-4.html +++ b/blog/2013/07/03/community-roundup-4.html @@ -64,7 +64,7 @@ @@ -177,6 +177,8 @@

Recent posts

diff --git a/blog/2013/07/11/react-v0-4-prop-validation-and-default-values.html b/blog/2013/07/11/react-v0-4-prop-validation-and-default-values.html index 50f15a4096..67256c341c 100644 --- a/blog/2013/07/11/react-v0-4-prop-validation-and-default-values.html +++ b/blog/2013/07/11/react-v0-4-prop-validation-and-default-values.html @@ -64,7 +64,7 @@ @@ -155,6 +155,8 @@

Recent posts

diff --git a/blog/2013/07/17/react-v0-4-0.html b/blog/2013/07/17/react-v0-4-0.html index 192f77f70f..dc4f6c18ea 100644 --- a/blog/2013/07/17/react-v0-4-0.html +++ b/blog/2013/07/17/react-v0-4-0.html @@ -64,7 +64,7 @@ @@ -147,6 +147,8 @@ If you were using React without JSX previously, your code should still work.Recent posts diff --git a/blog/2013/07/23/community-roundup-5.html b/blog/2013/07/23/community-roundup-5.html index 263b7c8d45..6d187b9706 100644 --- a/blog/2013/07/23/community-roundup-5.html +++ b/blog/2013/07/23/community-roundup-5.html @@ -64,7 +64,7 @@ @@ -210,6 +210,8 @@

Recent posts

diff --git a/blog/2013/07/26/react-v0-4-1.html b/blog/2013/07/26/react-v0-4-1.html index dfa7934878..f2f2dd3110 100644 --- a/blog/2013/07/26/react-v0-4-1.html +++ b/blog/2013/07/26/react-v0-4-1.html @@ -64,7 +64,7 @@ @@ -129,6 +129,8 @@

Recent posts

diff --git a/blog/2013/07/30/use-react-and-jsx-in-ruby-on-rails.html b/blog/2013/07/30/use-react-and-jsx-in-ruby-on-rails.html index 71859e683b..8bda2549be 100644 --- a/blog/2013/07/30/use-react-and-jsx-in-ruby-on-rails.html +++ b/blog/2013/07/30/use-react-and-jsx-in-ruby-on-rails.html @@ -64,7 +64,7 @@ @@ -144,6 +144,8 @@

Recent posts

diff --git a/blog/2013/08/05/community-roundup-6.html b/blog/2013/08/05/community-roundup-6.html index 9b8d8c99f9..6f2f5d6bc2 100644 --- a/blog/2013/08/05/community-roundup-6.html +++ b/blog/2013/08/05/community-roundup-6.html @@ -64,7 +64,7 @@ @@ -183,6 +183,8 @@

Recent posts

diff --git a/blog/2013/08/19/use-react-and-jsx-in-python-applications.html b/blog/2013/08/19/use-react-and-jsx-in-python-applications.html index ff1d100109..e69f0c2d17 100644 --- a/blog/2013/08/19/use-react-and-jsx-in-python-applications.html +++ b/blog/2013/08/19/use-react-and-jsx-in-python-applications.html @@ -64,7 +64,7 @@ @@ -148,6 +148,8 @@

Recent posts

diff --git a/blog/2013/08/26/community-roundup-7.html b/blog/2013/08/26/community-roundup-7.html index c30da91115..8c02481aaa 100644 --- a/blog/2013/08/26/community-roundup-7.html +++ b/blog/2013/08/26/community-roundup-7.html @@ -64,7 +64,7 @@ @@ -188,6 +188,8 @@

Recent posts

diff --git a/blog/2013/09/24/community-roundup-8.html b/blog/2013/09/24/community-roundup-8.html index bfdcc436c3..641544954c 100644 --- a/blog/2013/09/24/community-roundup-8.html +++ b/blog/2013/09/24/community-roundup-8.html @@ -64,7 +64,7 @@ @@ -174,6 +174,8 @@

Recent posts

diff --git a/blog/2013/10/03/community-roundup-9.html b/blog/2013/10/03/community-roundup-9.html index 6bfaec585b..fa23274d37 100644 --- a/blog/2013/10/03/community-roundup-9.html +++ b/blog/2013/10/03/community-roundup-9.html @@ -64,7 +64,7 @@ @@ -198,6 +198,8 @@

Recent posts

diff --git a/blog/2013/10/16/react-v0.5.0.html b/blog/2013/10/16/react-v0.5.0.html index 5b677c0130..6836f41144 100644 --- a/blog/2013/10/16/react-v0.5.0.html +++ b/blog/2013/10/16/react-v0.5.0.html @@ -64,7 +64,7 @@ @@ -160,6 +160,8 @@

Recent posts

diff --git a/blog/2013/10/29/react-v0-5-1.html b/blog/2013/10/29/react-v0-5-1.html index f8aeb6e32b..3eaed996d7 100644 --- a/blog/2013/10/29/react-v0-5-1.html +++ b/blog/2013/10/29/react-v0-5-1.html @@ -64,7 +64,7 @@ @@ -127,6 +127,8 @@

Recent posts

diff --git a/blog/2013/11/06/community-roundup-10.html b/blog/2013/11/06/community-roundup-10.html index a76e9d2c50..615932b98f 100644 --- a/blog/2013/11/06/community-roundup-10.html +++ b/blog/2013/11/06/community-roundup-10.html @@ -64,7 +64,7 @@ @@ -233,6 +233,8 @@

Recent posts

diff --git a/blog/2013/11/18/community-roundup-11.html b/blog/2013/11/18/community-roundup-11.html index 2615b94c6d..7b3a314e26 100644 --- a/blog/2013/11/18/community-roundup-11.html +++ b/blog/2013/11/18/community-roundup-11.html @@ -64,7 +64,7 @@ @@ -196,6 +196,8 @@ Is this some sort of template language? Specifically no. This might have been th

Recent posts

diff --git a/blog/2013/12/18/react-v0.5.2-v0.4.2.html b/blog/2013/12/18/react-v0.5.2-v0.4.2.html index 2a2f2ccffd..5dab436ab3 100644 --- a/blog/2013/12/18/react-v0.5.2-v0.4.2.html +++ b/blog/2013/12/18/react-v0.5.2-v0.4.2.html @@ -64,7 +64,7 @@ @@ -120,6 +120,8 @@

Recent posts

diff --git a/blog/2013/12/19/react-v0.8.0.html b/blog/2013/12/19/react-v0.8.0.html index 20e505d3ef..de25dce918 100644 --- a/blog/2013/12/19/react-v0.8.0.html +++ b/blog/2013/12/19/react-v0.8.0.html @@ -64,7 +64,7 @@ @@ -160,6 +160,8 @@

Recent posts

diff --git a/blog/2013/12/23/community-roundup-12.html b/blog/2013/12/23/community-roundup-12.html index 0fd7d2c4b0..5c720783bd 100644 --- a/blog/2013/12/23/community-roundup-12.html +++ b/blog/2013/12/23/community-roundup-12.html @@ -64,7 +64,7 @@ @@ -198,6 +198,8 @@ componentDidUpdate: function() {

Recent posts

diff --git a/blog/2013/12/30/community-roundup-13.html b/blog/2013/12/30/community-roundup-13.html index 6549b44d53..195bf8d1e6 100644 --- a/blog/2013/12/30/community-roundup-13.html +++ b/blog/2013/12/30/community-roundup-13.html @@ -64,7 +64,7 @@ @@ -213,6 +213,8 @@

Recent posts

diff --git a/blog/2014/01/02/react-chrome-developer-tools.html b/blog/2014/01/02/react-chrome-developer-tools.html index 6483d3942d..1ef755db81 100644 --- a/blog/2014/01/02/react-chrome-developer-tools.html +++ b/blog/2014/01/02/react-chrome-developer-tools.html @@ -64,7 +64,7 @@ @@ -121,6 +121,8 @@

Recent posts

diff --git a/blog/2014/01/06/community-roundup-14.html b/blog/2014/01/06/community-roundup-14.html index 3dbc7cff44..5f9ac96d50 100644 --- a/blog/2014/01/06/community-roundup-14.html +++ b/blog/2014/01/06/community-roundup-14.html @@ -64,7 +64,7 @@ @@ -190,6 +190,8 @@ rails s

Recent posts

diff --git a/blog/2014/02/05/community-roundup-15.html b/blog/2014/02/05/community-roundup-15.html index 308f837e04..e2baaf7559 100644 --- a/blog/2014/02/05/community-roundup-15.html +++ b/blog/2014/02/05/community-roundup-15.html @@ -64,7 +64,7 @@ @@ -234,6 +234,8 @@

Recent posts

diff --git a/blog/2014/02/15/community-roundup-16.html b/blog/2014/02/15/community-roundup-16.html index 69e8d734cc..945e85c90f 100644 --- a/blog/2014/02/15/community-roundup-16.html +++ b/blog/2014/02/15/community-roundup-16.html @@ -64,7 +64,7 @@ @@ -187,6 +187,8 @@

Recent posts

diff --git a/blog/2014/02/16/react-v0.9-rc1.html b/blog/2014/02/16/react-v0.9-rc1.html index 13e548faa0..4fa6842825 100644 --- a/blog/2014/02/16/react-v0.9-rc1.html +++ b/blog/2014/02/16/react-v0.9-rc1.html @@ -64,7 +64,7 @@ @@ -242,6 +242,8 @@ Minified build for production: React v15.5.0 +
  • React v15.4.0
  • Our First 50,000 Stars
  • @@ -260,8 +262,6 @@ Minified build for production: React v0.14.8 -
  • React v15.0 Release Candidate 2
  • -
  • All posts ...
  • diff --git a/blog/2014/02/20/react-v0.9.html b/blog/2014/02/20/react-v0.9.html index 4a91ef8d7b..2a028f43d5 100644 --- a/blog/2014/02/20/react-v0.9.html +++ b/blog/2014/02/20/react-v0.9.html @@ -64,7 +64,7 @@ @@ -254,6 +254,8 @@ Minified build for production: React v15.5.0 +
  • React v15.4.0
  • Our First 50,000 Stars
  • @@ -272,8 +274,6 @@ Minified build for production: React v0.14.8 -
  • React v15.0 Release Candidate 2
  • -
  • All posts ...
  • diff --git a/blog/2014/02/24/community-roundup-17.html b/blog/2014/02/24/community-roundup-17.html index 1bfdeeaaf1..6fd0a997b7 100644 --- a/blog/2014/02/24/community-roundup-17.html +++ b/blog/2014/02/24/community-roundup-17.html @@ -64,7 +64,7 @@ @@ -194,6 +194,8 @@

    Recent posts

    diff --git a/blog/2014/03/14/community-roundup-18.html b/blog/2014/03/14/community-roundup-18.html index 5224a8c90d..e2bdcaa13f 100644 --- a/blog/2014/03/14/community-roundup-18.html +++ b/blog/2014/03/14/community-roundup-18.html @@ -64,7 +64,7 @@ @@ -213,6 +213,8 @@ Thomas Boyt (@thomasaboyt) wrote <

    Recent posts

    diff --git a/blog/2014/03/19/react-v0.10-rc1.html b/blog/2014/03/19/react-v0.10-rc1.html index c70d4fabe8..13fa8fab1e 100644 --- a/blog/2014/03/19/react-v0.10-rc1.html +++ b/blog/2014/03/19/react-v0.10-rc1.html @@ -64,7 +64,7 @@ @@ -188,6 +188,8 @@ Minified build for production: React v15.5.0 +
  • React v15.4.0
  • Our First 50,000 Stars
  • @@ -206,8 +208,6 @@ Minified build for production: React v0.14.8 -
  • React v15.0 Release Candidate 2
  • -
  • All posts ...
  • diff --git a/blog/2014/03/21/react-v0.10.html b/blog/2014/03/21/react-v0.10.html index 4bb6700fce..a4438b3fc6 100644 --- a/blog/2014/03/21/react-v0.10.html +++ b/blog/2014/03/21/react-v0.10.html @@ -64,7 +64,7 @@ @@ -188,6 +188,8 @@ Minified build for production: React v15.5.0 +
  • React v15.4.0
  • Our First 50,000 Stars
  • @@ -206,8 +208,6 @@ Minified build for production: React v0.14.8 -
  • React v15.0 Release Candidate 2
  • -
  • All posts ...
  • diff --git a/blog/2014/03/28/the-road-to-1.0.html b/blog/2014/03/28/the-road-to-1.0.html index 5ff7c3e3c6..c21c6110eb 100644 --- a/blog/2014/03/28/the-road-to-1.0.html +++ b/blog/2014/03/28/the-road-to-1.0.html @@ -64,7 +64,7 @@ @@ -153,6 +153,8 @@

    Recent posts

    diff --git a/blog/2014/04/04/reactnet.html b/blog/2014/04/04/reactnet.html index c230e3f3f9..b0d6e61c8b 100644 --- a/blog/2014/04/04/reactnet.html +++ b/blog/2014/04/04/reactnet.html @@ -67,7 +67,7 @@ It has several purposes: @@ -146,6 +146,8 @@ report bugs on GitHub.

    Recent posts

    diff --git a/blog/2014/05/06/flux.html b/blog/2014/05/06/flux.html index 486c1330d7..5a83b7364e 100644 --- a/blog/2014/05/06/flux.html +++ b/blog/2014/05/06/flux.html @@ -64,7 +64,7 @@ @@ -125,6 +125,8 @@

    Recent posts

    diff --git a/blog/2014/05/29/one-year-of-open-source-react.html b/blog/2014/05/29/one-year-of-open-source-react.html index 872d345e0e..c6a82ebc6f 100644 --- a/blog/2014/05/29/one-year-of-open-source-react.html +++ b/blog/2014/05/29/one-year-of-open-source-react.html @@ -64,7 +64,7 @@ @@ -118,6 +118,8 @@

    Recent posts

    diff --git a/blog/2014/06/27/community-roundup-19.html b/blog/2014/06/27/community-roundup-19.html index b497be387c..5d4e0cb57f 100644 --- a/blog/2014/06/27/community-roundup-19.html +++ b/blog/2014/06/27/community-roundup-19.html @@ -66,7 +66,7 @@ Ever wanted to find developers who also share the same interest in React than yo @@ -170,6 +170,8 @@ Ever wanted to find developers who also share the same interest in React than yo

    Recent posts

    diff --git a/blog/2014/07/13/react-v0.11-rc1.html b/blog/2014/07/13/react-v0.11-rc1.html index e58da33991..bd13c7223f 100644 --- a/blog/2014/07/13/react-v0.11-rc1.html +++ b/blog/2014/07/13/react-v0.11-rc1.html @@ -64,7 +64,7 @@ @@ -261,6 +261,8 @@ Minified build for production: React v15.5.0 +
  • React v15.4.0
  • Our First 50,000 Stars
  • @@ -279,8 +281,6 @@ Minified build for production: React v0.14.8 -
  • React v15.0 Release Candidate 2
  • -
  • All posts ...
  • diff --git a/blog/2014/07/17/react-v0.11.html b/blog/2014/07/17/react-v0.11.html index ec905f0e93..fe0890cc56 100644 --- a/blog/2014/07/17/react-v0.11.html +++ b/blog/2014/07/17/react-v0.11.html @@ -64,7 +64,7 @@ @@ -280,6 +280,8 @@ Minified build for production: React v15.5.0 +
  • React v15.4.0
  • Our First 50,000 Stars
  • @@ -298,8 +300,6 @@ Minified build for production: React v0.14.8 -
  • React v15.0 Release Candidate 2
  • -
  • All posts ...
  • diff --git a/blog/2014/07/25/react-v0.11.1.html b/blog/2014/07/25/react-v0.11.1.html index 33717a0086..48f43837f1 100644 --- a/blog/2014/07/25/react-v0.11.1.html +++ b/blog/2014/07/25/react-v0.11.1.html @@ -64,7 +64,7 @@ @@ -155,6 +155,8 @@ Minified build for production: React v15.5.0 +
  • React v15.4.0
  • Our First 50,000 Stars
  • @@ -173,8 +175,6 @@ Minified build for production: React v0.14.8 -
  • React v15.0 Release Candidate 2
  • -
  • All posts ...
  • diff --git a/blog/2014/07/28/community-roundup-20.html b/blog/2014/07/28/community-roundup-20.html index 2bcfa349ed..b2f7bfee7c 100644 --- a/blog/2014/07/28/community-roundup-20.html +++ b/blog/2014/07/28/community-roundup-20.html @@ -64,7 +64,7 @@ @@ -207,6 +207,8 @@

    Recent posts

    diff --git a/blog/2014/07/30/flux-actions-and-the-dispatcher.html b/blog/2014/07/30/flux-actions-and-the-dispatcher.html index 490433367f..d16080c7ba 100644 --- a/blog/2014/07/30/flux-actions-and-the-dispatcher.html +++ b/blog/2014/07/30/flux-actions-and-the-dispatcher.html @@ -64,7 +64,7 @@ @@ -142,6 +142,8 @@

    Recent posts

    diff --git a/blog/2014/08/03/community-roundup-21.html b/blog/2014/08/03/community-roundup-21.html index 5f6a519c7f..7e194674d6 100644 --- a/blog/2014/08/03/community-roundup-21.html +++ b/blog/2014/08/03/community-roundup-21.html @@ -66,7 +66,7 @@ Ryan Florence and Michael Jackson ported Ember's router to React in a projec @@ -206,6 +206,8 @@ This is not the intended way to use React but can be useful as last resort if yo

    Recent posts

    diff --git a/blog/2014/09/03/introducing-the-jsx-specification.html b/blog/2014/09/03/introducing-the-jsx-specification.html index 7aa5c77eb5..b825a4e7c6 100644 --- a/blog/2014/09/03/introducing-the-jsx-specification.html +++ b/blog/2014/09/03/introducing-the-jsx-specification.html @@ -64,7 +64,7 @@ @@ -118,6 +118,8 @@

    Recent posts

    diff --git a/blog/2014/09/12/community-round-up-22.html b/blog/2014/09/12/community-round-up-22.html index 2c02d1f732..25f49050d8 100644 --- a/blog/2014/09/12/community-round-up-22.html +++ b/blog/2014/09/12/community-round-up-22.html @@ -64,7 +64,7 @@ @@ -208,6 +208,8 @@

    Recent posts

    diff --git a/blog/2014/09/16/react-v0.11.2.html b/blog/2014/09/16/react-v0.11.2.html index 8c4b4acf4e..2733667fad 100644 --- a/blog/2014/09/16/react-v0.11.2.html +++ b/blog/2014/09/16/react-v0.11.2.html @@ -64,7 +64,7 @@ @@ -164,6 +164,8 @@ Minified build for production: React v15.5.0 +
  • React v15.4.0
  • Our First 50,000 Stars
  • @@ -182,8 +184,6 @@ Minified build for production: React v0.14.8 -
  • React v15.0 Release Candidate 2
  • -
  • All posts ...
  • diff --git a/blog/2014/09/24/testing-flux-applications.html b/blog/2014/09/24/testing-flux-applications.html index 69ad48c334..f5bfd28fb5 100644 --- a/blog/2014/09/24/testing-flux-applications.html +++ b/blog/2014/09/24/testing-flux-applications.html @@ -64,7 +64,7 @@ @@ -386,6 +386,8 @@

    Recent posts

    diff --git a/blog/2014/10/14/introducing-react-elements.html b/blog/2014/10/14/introducing-react-elements.html index 44739a3227..5c8fce9c6f 100644 --- a/blog/2014/10/14/introducing-react-elements.html +++ b/blog/2014/10/14/introducing-react-elements.html @@ -64,7 +64,7 @@ @@ -274,6 +274,8 @@

    Recent posts

    diff --git a/blog/2014/10/16/react-v0.12-rc1.html b/blog/2014/10/16/react-v0.12-rc1.html index 62be723219..69534f52f0 100644 --- a/blog/2014/10/16/react-v0.12-rc1.html +++ b/blog/2014/10/16/react-v0.12-rc1.html @@ -64,7 +64,7 @@ @@ -227,6 +227,8 @@ Minified build for production: React v15.5.0 +
  • React v15.4.0
  • Our First 50,000 Stars
  • @@ -245,8 +247,6 @@ Minified build for production: React v0.14.8 -
  • React v15.0 Release Candidate 2
  • -
  • All posts ...
  • diff --git a/blog/2014/10/17/community-roundup-23.html b/blog/2014/10/17/community-roundup-23.html index 54f6749817..0be09fe7ed 100644 --- a/blog/2014/10/17/community-roundup-23.html +++ b/blog/2014/10/17/community-roundup-23.html @@ -64,7 +64,7 @@ @@ -252,6 +252,8 @@

    Recent posts

    diff --git a/blog/2014/10/27/react-js-conf.html b/blog/2014/10/27/react-js-conf.html index 292a295657..c613f63ecf 100644 --- a/blog/2014/10/27/react-js-conf.html +++ b/blog/2014/10/27/react-js-conf.html @@ -64,7 +64,7 @@ @@ -118,6 +118,8 @@

    Recent posts

    diff --git a/blog/2014/10/28/react-v0.12.html b/blog/2014/10/28/react-v0.12.html index a60dc50261..177063ee77 100644 --- a/blog/2014/10/28/react-v0.12.html +++ b/blog/2014/10/28/react-v0.12.html @@ -64,7 +64,7 @@ @@ -257,6 +257,8 @@ Minified build for production: React v15.5.0 +
  • React v15.4.0
  • Our First 50,000 Stars
  • @@ -275,8 +277,6 @@ Minified build for production: React v0.14.8 -
  • React v15.0 Release Candidate 2
  • -
  • All posts ...
  • diff --git a/blog/2014/11/24/react-js-conf-updates.html b/blog/2014/11/24/react-js-conf-updates.html index fc86eb6c50..3ecf01dc76 100644 --- a/blog/2014/11/24/react-js-conf-updates.html +++ b/blog/2014/11/24/react-js-conf-updates.html @@ -66,7 +66,7 @@ amazed that 600 people requested to be notified when ticket go on sale. This is @@ -147,6 +147,8 @@ until the next conference. All the talks will be recorded and put online shortly

    Recent posts

    diff --git a/blog/2014/11/25/community-roundup-24.html b/blog/2014/11/25/community-roundup-24.html index 330b23aa65..605734383f 100644 --- a/blog/2014/11/25/community-roundup-24.html +++ b/blog/2014/11/25/community-roundup-24.html @@ -64,7 +64,7 @@ @@ -202,6 +202,8 @@

    Recent posts

    diff --git a/blog/2014/12/18/react-v0.12.2.html b/blog/2014/12/18/react-v0.12.2.html index 673ff54315..100f40d8cc 100644 --- a/blog/2014/12/18/react-v0.12.2.html +++ b/blog/2014/12/18/react-v0.12.2.html @@ -64,7 +64,7 @@ @@ -146,6 +146,8 @@ Minified build for production: React v15.5.0 +
  • React v15.4.0
  • Our First 50,000 Stars
  • @@ -164,8 +166,6 @@ Minified build for production: React v0.14.8 -
  • React v15.0 Release Candidate 2
  • -
  • All posts ...
  • diff --git a/blog/2014/12/19/react-js-conf-diversity-scholarship.html b/blog/2014/12/19/react-js-conf-diversity-scholarship.html index 26e7b765e2..68f9693efc 100644 --- a/blog/2014/12/19/react-js-conf-diversity-scholarship.html +++ b/blog/2014/12/19/react-js-conf-diversity-scholarship.html @@ -64,7 +64,7 @@ @@ -147,6 +147,8 @@ Facebook will make determinations on scholarship recipients in its sole discreti

    Recent posts

    diff --git a/blog/2015/01/27/react-v0.13.0-beta-1.html b/blog/2015/01/27/react-v0.13.0-beta-1.html index 79f6d57235..48616335c1 100644 --- a/blog/2015/01/27/react-v0.13.0-beta-1.html +++ b/blog/2015/01/27/react-v0.13.0-beta-1.html @@ -64,7 +64,7 @@ @@ -248,6 +248,8 @@

    Recent posts

    diff --git a/blog/2015/02/18/react-conf-roundup-2015.html b/blog/2015/02/18/react-conf-roundup-2015.html index 199015dd68..36d3c19c1b 100644 --- a/blog/2015/02/18/react-conf-roundup-2015.html +++ b/blog/2015/02/18/react-conf-roundup-2015.html @@ -64,7 +64,7 @@ @@ -373,6 +373,8 @@

    Recent posts

    diff --git a/blog/2015/02/20/introducing-relay-and-graphql.html b/blog/2015/02/20/introducing-relay-and-graphql.html index c81afda22a..e167bab398 100644 --- a/blog/2015/02/20/introducing-relay-and-graphql.html +++ b/blog/2015/02/20/introducing-relay-and-graphql.html @@ -64,7 +64,7 @@ @@ -168,6 +168,8 @@

    Recent posts

    diff --git a/blog/2015/02/24/react-v0.13-rc1.html b/blog/2015/02/24/react-v0.13-rc1.html index 6a9fe1d000..3a815a0304 100644 --- a/blog/2015/02/24/react-v0.13-rc1.html +++ b/blog/2015/02/24/react-v0.13-rc1.html @@ -64,7 +64,7 @@ @@ -197,6 +197,8 @@ Minified build for production: React v15.5.0 +
  • React v15.4.0
  • Our First 50,000 Stars
  • @@ -215,8 +217,6 @@ Minified build for production: React v0.14.8 -
  • React v15.0 Release Candidate 2
  • -
  • All posts ...
  • diff --git a/blog/2015/02/24/streamlining-react-elements.html b/blog/2015/02/24/streamlining-react-elements.html index ee7288006e..9eb744500d 100644 --- a/blog/2015/02/24/streamlining-react-elements.html +++ b/blog/2015/02/24/streamlining-react-elements.html @@ -64,7 +64,7 @@ @@ -296,6 +296,8 @@

    Recent posts

    diff --git a/blog/2015/03/03/react-v0.13-rc2.html b/blog/2015/03/03/react-v0.13-rc2.html index b6bac318b6..9a0296af26 100644 --- a/blog/2015/03/03/react-v0.13-rc2.html +++ b/blog/2015/03/03/react-v0.13-rc2.html @@ -64,7 +64,7 @@ @@ -159,6 +159,8 @@ Minified build for production: React v15.5.0 +
  • React v15.4.0
  • Our First 50,000 Stars
  • @@ -177,8 +179,6 @@ Minified build for production: React v0.14.8 -
  • React v15.0 Release Candidate 2
  • -
  • All posts ...
  • diff --git a/blog/2015/03/04/community-roundup-25.html b/blog/2015/03/04/community-roundup-25.html index b499b9560e..b71d218f22 100644 --- a/blog/2015/03/04/community-roundup-25.html +++ b/blog/2015/03/04/community-roundup-25.html @@ -64,7 +64,7 @@ @@ -166,6 +166,8 @@

    Recent posts

    diff --git a/blog/2015/03/10/react-v0.13.html b/blog/2015/03/10/react-v0.13.html index 80bf3c9406..038a201608 100644 --- a/blog/2015/03/10/react-v0.13.html +++ b/blog/2015/03/10/react-v0.13.html @@ -64,7 +64,7 @@ @@ -213,6 +213,8 @@ Minified build for production: React v15.5.0 +
  • React v15.4.0
  • Our First 50,000 Stars
  • @@ -231,8 +233,6 @@ Minified build for production: React v0.14.8 -
  • React v15.0 Release Candidate 2
  • -
  • All posts ...
  • diff --git a/blog/2015/03/16/react-v0.13.1.html b/blog/2015/03/16/react-v0.13.1.html index 1783f4c79f..f1a2972712 100644 --- a/blog/2015/03/16/react-v0.13.1.html +++ b/blog/2015/03/16/react-v0.13.1.html @@ -64,7 +64,7 @@ @@ -158,6 +158,8 @@ Minified build for production: React v15.5.0 +
  • React v15.4.0
  • Our First 50,000 Stars
  • @@ -176,8 +178,6 @@ Minified build for production: React v0.14.8 -
  • React v15.0 Release Candidate 2
  • -
  • All posts ...
  • diff --git a/blog/2015/03/19/building-the-facebook-news-feed-with-relay.html b/blog/2015/03/19/building-the-facebook-news-feed-with-relay.html index 3f2100154b..6757377ec3 100644 --- a/blog/2015/03/19/building-the-facebook-news-feed-with-relay.html +++ b/blog/2015/03/19/building-the-facebook-news-feed-with-relay.html @@ -64,7 +64,7 @@ @@ -307,6 +307,8 @@

    Recent posts

    diff --git a/blog/2015/03/26/introducing-react-native.html b/blog/2015/03/26/introducing-react-native.html index cc74ac6fc9..ff634d9af8 100644 --- a/blog/2015/03/26/introducing-react-native.html +++ b/blog/2015/03/26/introducing-react-native.html @@ -64,7 +64,7 @@ @@ -122,6 +122,8 @@

    Recent posts

    diff --git a/blog/2015/03/30/community-roundup-26.html b/blog/2015/03/30/community-roundup-26.html index 35a1a8bd6a..38d0d20f69 100644 --- a/blog/2015/03/30/community-roundup-26.html +++ b/blog/2015/03/30/community-roundup-26.html @@ -64,7 +64,7 @@ @@ -186,6 +186,8 @@

    Recent posts

    diff --git a/blog/2015/04/17/react-native-v0.4.html b/blog/2015/04/17/react-native-v0.4.html index 6b88d14dce..844e751979 100644 --- a/blog/2015/04/17/react-native-v0.4.html +++ b/blog/2015/04/17/react-native-v0.4.html @@ -64,7 +64,7 @@ @@ -130,6 +130,8 @@

    Recent posts

    diff --git a/blog/2015/04/18/react-v0.13.2.html b/blog/2015/04/18/react-v0.13.2.html index 6c8990c44f..1a43e77d17 100644 --- a/blog/2015/04/18/react-v0.13.2.html +++ b/blog/2015/04/18/react-v0.13.2.html @@ -64,7 +64,7 @@ @@ -167,6 +167,8 @@ Minified build for production: React v15.5.0 +
  • React v15.4.0
  • Our First 50,000 Stars
  • @@ -185,8 +187,6 @@ Minified build for production: React v0.14.8 -
  • React v15.0 Release Candidate 2
  • -
  • All posts ...
  • diff --git a/blog/2015/05/01/graphql-introduction.html b/blog/2015/05/01/graphql-introduction.html index 284e73e8f9..4d9b61f7b1 100644 --- a/blog/2015/05/01/graphql-introduction.html +++ b/blog/2015/05/01/graphql-introduction.html @@ -64,7 +64,7 @@ @@ -205,6 +205,8 @@

    Recent posts

    diff --git a/blog/2015/05/08/react-v0.13.3.html b/blog/2015/05/08/react-v0.13.3.html index 59afba64ae..63c76d141a 100644 --- a/blog/2015/05/08/react-v0.13.3.html +++ b/blog/2015/05/08/react-v0.13.3.html @@ -64,7 +64,7 @@ @@ -154,6 +154,8 @@ Minified build for production: React v15.5.0 +
  • React v15.4.0
  • Our First 50,000 Stars
  • @@ -172,8 +174,6 @@ Minified build for production: React v0.14.8 -
  • React v15.0 Release Candidate 2
  • -
  • All posts ...
  • diff --git a/blog/2015/05/22/react-native-release-process.html b/blog/2015/05/22/react-native-release-process.html index cc546f12fe..c07526f1d7 100644 --- a/blog/2015/05/22/react-native-release-process.html +++ b/blog/2015/05/22/react-native-release-process.html @@ -64,7 +64,7 @@ @@ -128,6 +128,8 @@

    Recent posts

    diff --git a/blog/2015/06/12/deprecating-jstransform-and-react-tools.html b/blog/2015/06/12/deprecating-jstransform-and-react-tools.html index afeff4269c..80f5ba554d 100644 --- a/blog/2015/06/12/deprecating-jstransform-and-react-tools.html +++ b/blog/2015/06/12/deprecating-jstransform-and-react-tools.html @@ -64,7 +64,7 @@ @@ -134,6 +134,8 @@

    Recent posts

    diff --git a/blog/2015/07/03/react-v0.14-beta-1.html b/blog/2015/07/03/react-v0.14-beta-1.html index e0c853dc4b..3c667ab2d9 100644 --- a/blog/2015/07/03/react-v0.14-beta-1.html +++ b/blog/2015/07/03/react-v0.14-beta-1.html @@ -64,7 +64,7 @@ @@ -173,6 +173,8 @@

    Recent posts

    diff --git a/blog/2015/08/03/new-react-devtools-beta.html b/blog/2015/08/03/new-react-devtools-beta.html index 6df629ad26..a095196267 100644 --- a/blog/2015/08/03/new-react-devtools-beta.html +++ b/blog/2015/08/03/new-react-devtools-beta.html @@ -65,7 +65,7 @@ out! @@ -205,6 +205,8 @@ for more info.

    Recent posts

    diff --git a/blog/2015/08/11/relay-technical-preview.html b/blog/2015/08/11/relay-technical-preview.html index 9c82053449..4aa930c3f0 100644 --- a/blog/2015/08/11/relay-technical-preview.html +++ b/blog/2015/08/11/relay-technical-preview.html @@ -64,7 +64,7 @@ @@ -141,6 +141,8 @@

    Recent posts

    diff --git a/blog/2015/08/13/reacteurope-roundup.html b/blog/2015/08/13/reacteurope-roundup.html index c45b91f0fb..5adf818296 100644 --- a/blog/2015/08/13/reacteurope-roundup.html +++ b/blog/2015/08/13/reacteurope-roundup.html @@ -64,7 +64,7 @@ @@ -167,6 +167,8 @@

    Recent posts

    diff --git a/blog/2015/09/02/new-react-developer-tools.html b/blog/2015/09/02/new-react-developer-tools.html index 443412e74d..cf4736996c 100644 --- a/blog/2015/09/02/new-react-developer-tools.html +++ b/blog/2015/09/02/new-react-developer-tools.html @@ -64,7 +64,7 @@ @@ -132,6 +132,8 @@

    Recent posts

    diff --git a/blog/2015/09/10/react-v0.14-rc1.html b/blog/2015/09/10/react-v0.14-rc1.html index b3a00aa4bb..dc42183bc4 100644 --- a/blog/2015/09/10/react-v0.14-rc1.html +++ b/blog/2015/09/10/react-v0.14-rc1.html @@ -64,7 +64,7 @@ @@ -286,6 +286,8 @@ Minified build for production: React v15.5.0 +
  • React v15.4.0
  • Our First 50,000 Stars
  • @@ -304,8 +306,6 @@ Minified build for production: React v0.14.8 -
  • React v15.0 Release Candidate 2
  • -
  • All posts ...
  • diff --git a/blog/2015/09/14/community-roundup-27.html b/blog/2015/09/14/community-roundup-27.html index dc1747ca89..a275350572 100644 --- a/blog/2015/09/14/community-roundup-27.html +++ b/blog/2015/09/14/community-roundup-27.html @@ -64,7 +64,7 @@ @@ -187,6 +187,8 @@

    Recent posts

    diff --git a/blog/2015/10/01/react-render-and-top-level-api.html b/blog/2015/10/01/react-render-and-top-level-api.html index 5f60487c18..1c8912e10f 100644 --- a/blog/2015/10/01/react-render-and-top-level-api.html +++ b/blog/2015/10/01/react-render-and-top-level-api.html @@ -64,7 +64,7 @@ @@ -225,6 +225,8 @@

    Recent posts

    diff --git a/blog/2015/10/07/react-v0.14.html b/blog/2015/10/07/react-v0.14.html index 729a4854fa..fe9da9bb2b 100644 --- a/blog/2015/10/07/react-v0.14.html +++ b/blog/2015/10/07/react-v0.14.html @@ -64,7 +64,7 @@ @@ -313,6 +313,8 @@ Minified build for production: h

    Recent posts

    diff --git a/blog/2015/10/19/reactiflux-is-moving-to-discord.html b/blog/2015/10/19/reactiflux-is-moving-to-discord.html index f9558c2317..b24f224c85 100644 --- a/blog/2015/10/19/reactiflux-is-moving-to-discord.html +++ b/blog/2015/10/19/reactiflux-is-moving-to-discord.html @@ -64,7 +64,7 @@ @@ -190,6 +190,8 @@

    Recent posts

    diff --git a/blog/2015/10/28/react-v0.14.1.html b/blog/2015/10/28/react-v0.14.1.html index 325be504b3..726a56bb93 100644 --- a/blog/2015/10/28/react-v0.14.1.html +++ b/blog/2015/10/28/react-v0.14.1.html @@ -64,7 +64,7 @@ @@ -158,6 +158,8 @@ Minified build for production: h

    Recent posts

    diff --git a/blog/2015/11/02/react-v0.14.2.html b/blog/2015/11/02/react-v0.14.2.html index 527b9c1909..4a915a111d 100644 --- a/blog/2015/11/02/react-v0.14.2.html +++ b/blog/2015/11/02/react-v0.14.2.html @@ -64,7 +64,7 @@ @@ -140,6 +140,8 @@ Minified build for production: h

    Recent posts

    diff --git a/blog/2015/11/18/react-v0.14.3.html b/blog/2015/11/18/react-v0.14.3.html index 8a97374676..de173b2d6b 100644 --- a/blog/2015/11/18/react-v0.14.3.html +++ b/blog/2015/11/18/react-v0.14.3.html @@ -64,7 +64,7 @@ @@ -158,6 +158,8 @@ Minified build for production: React v15.5.0 +
  • React v15.4.0
  • Our First 50,000 Stars
  • @@ -176,8 +178,6 @@ Minified build for production: React v0.14.8 -
  • React v15.0 Release Candidate 2
  • -
  • All posts ...
  • diff --git a/blog/2015/12/04/react-js-conf-2016-diversity-scholarship.html b/blog/2015/12/04/react-js-conf-2016-diversity-scholarship.html index 8e8207e172..e688be5e9b 100644 --- a/blog/2015/12/04/react-js-conf-2016-diversity-scholarship.html +++ b/blog/2015/12/04/react-js-conf-2016-diversity-scholarship.html @@ -64,7 +64,7 @@ @@ -154,6 +154,8 @@

    Recent posts

    diff --git a/blog/2015/12/16/ismounted-antipattern.html b/blog/2015/12/16/ismounted-antipattern.html index 08b0778a17..2874567bdb 100644 --- a/blog/2015/12/16/ismounted-antipattern.html +++ b/blog/2015/12/16/ismounted-antipattern.html @@ -64,7 +64,7 @@ @@ -173,6 +173,8 @@

    Recent posts

    diff --git a/blog/2015/12/18/react-components-elements-and-instances.html b/blog/2015/12/18/react-components-elements-and-instances.html index 2b89088499..44887bcb16 100644 --- a/blog/2015/12/18/react-components-elements-and-instances.html +++ b/blog/2015/12/18/react-components-elements-and-instances.html @@ -64,7 +64,7 @@ @@ -461,6 +461,8 @@

    Recent posts

    diff --git a/blog/2015/12/29/react-v0.14.4.html b/blog/2015/12/29/react-v0.14.4.html index d0a5cefb04..1712b471b7 100644 --- a/blog/2015/12/29/react-v0.14.4.html +++ b/blog/2015/12/29/react-v0.14.4.html @@ -64,7 +64,7 @@ @@ -152,6 +152,8 @@ Minified build for production: React v15.5.0 +
  • React v15.4.0
  • Our First 50,000 Stars
  • @@ -170,8 +172,6 @@ Minified build for production: React v0.14.8 -
  • React v15.0 Release Candidate 2
  • -
  • All posts ...
  • diff --git a/blog/2016/01/08/A-implies-B-does-not-imply-B-implies-A.html b/blog/2016/01/08/A-implies-B-does-not-imply-B-implies-A.html index 2e282cb54a..93926c651d 100644 --- a/blog/2016/01/08/A-implies-B-does-not-imply-B-implies-A.html +++ b/blog/2016/01/08/A-implies-B-does-not-imply-B-implies-A.html @@ -64,7 +64,7 @@ @@ -159,6 +159,8 @@

    Recent posts

    diff --git a/blog/2016/01/12/discontinuing-ie8-support.html b/blog/2016/01/12/discontinuing-ie8-support.html index 2019de24a3..201068c3fd 100644 --- a/blog/2016/01/12/discontinuing-ie8-support.html +++ b/blog/2016/01/12/discontinuing-ie8-support.html @@ -64,7 +64,7 @@ @@ -114,6 +114,8 @@

    Recent posts

    diff --git a/blog/2016/02/19/new-versioning-scheme.html b/blog/2016/02/19/new-versioning-scheme.html index 75d0165671..83f4152bbd 100644 --- a/blog/2016/02/19/new-versioning-scheme.html +++ b/blog/2016/02/19/new-versioning-scheme.html @@ -64,7 +64,7 @@ @@ -164,6 +164,8 @@

    Recent posts

    diff --git a/blog/2016/03/07/react-v15-rc1.html b/blog/2016/03/07/react-v15-rc1.html index 26537fdd74..d76b28fb4a 100644 --- a/blog/2016/03/07/react-v15-rc1.html +++ b/blog/2016/03/07/react-v15-rc1.html @@ -64,7 +64,7 @@ @@ -206,6 +206,8 @@ Minified build for production: React v15.5.0 +
  • React v15.4.0
  • Our First 50,000 Stars
  • @@ -224,8 +226,6 @@ Minified build for production: React v0.14.8 -
  • React v15.0 Release Candidate 2
  • -
  • All posts ...
  • diff --git a/blog/2016/03/16/react-v15-rc2.html b/blog/2016/03/16/react-v15-rc2.html index 4cd3f75c9c..749fbf8cc1 100644 --- a/blog/2016/03/16/react-v15-rc2.html +++ b/blog/2016/03/16/react-v15-rc2.html @@ -64,7 +64,7 @@ @@ -140,6 +140,8 @@ Minified build for production: React v15.5.0 +
  • React v15.4.0
  • Our First 50,000 Stars
  • @@ -158,8 +160,6 @@ Minified build for production: React v0.14.8 -
  • React v15.0 Release Candidate 2
  • -
  • All posts ...
  • diff --git a/blog/2016/03/29/react-v0.14.8.html b/blog/2016/03/29/react-v0.14.8.html index be47bbb60b..e5cd478e6f 100644 --- a/blog/2016/03/29/react-v0.14.8.html +++ b/blog/2016/03/29/react-v0.14.8.html @@ -64,7 +64,7 @@ @@ -141,6 +141,8 @@ Minified build for production: React v15.5.0 +
  • React v15.4.0
  • Our First 50,000 Stars
  • @@ -159,8 +161,6 @@ Minified build for production: React v0.14.8 -
  • React v15.0 Release Candidate 2
  • -
  • All posts ...
  • diff --git a/blog/2016/04/07/react-v15.html b/blog/2016/04/07/react-v15.html index 5dd543f643..2a2bf0dd2d 100644 --- a/blog/2016/04/07/react-v15.html +++ b/blog/2016/04/07/react-v15.html @@ -64,7 +64,7 @@ @@ -332,6 +332,8 @@ Minified build for production: h

    Recent posts

    diff --git a/blog/2016/04/08/react-v15.0.1.html b/blog/2016/04/08/react-v15.0.1.html index eea462d626..7305f11a15 100644 --- a/blog/2016/04/08/react-v15.0.1.html +++ b/blog/2016/04/08/react-v15.0.1.html @@ -64,7 +64,7 @@ @@ -146,6 +146,8 @@ Minified build for production: h

    Recent posts

    diff --git a/blog/2016/07/11/introducing-reacts-error-code-system.html b/blog/2016/07/11/introducing-reacts-error-code-system.html index 7e1710654b..24da12f21d 100644 --- a/blog/2016/07/11/introducing-reacts-error-code-system.html +++ b/blog/2016/07/11/introducing-reacts-error-code-system.html @@ -64,7 +64,7 @@ @@ -126,6 +126,8 @@

    Recent posts

    diff --git a/blog/2016/07/13/mixins-considered-harmful.html b/blog/2016/07/13/mixins-considered-harmful.html index f9a76b152a..a40543d019 100644 --- a/blog/2016/07/13/mixins-considered-harmful.html +++ b/blog/2016/07/13/mixins-considered-harmful.html @@ -64,7 +64,7 @@ @@ -672,6 +672,8 @@

    Recent posts

    diff --git a/blog/2016/07/22/create-apps-with-no-configuration.html b/blog/2016/07/22/create-apps-with-no-configuration.html index 5a72398ce7..9ca34a991e 100644 --- a/blog/2016/07/22/create-apps-with-no-configuration.html +++ b/blog/2016/07/22/create-apps-with-no-configuration.html @@ -64,7 +64,7 @@ @@ -262,6 +262,8 @@ The console output is tuned to be minimal to help you focus on the problems:

    Recent posts

    diff --git a/blog/2016/08/05/relay-state-of-the-state.html b/blog/2016/08/05/relay-state-of-the-state.html index 90f5e0b254..5f9585da78 100644 --- a/blog/2016/08/05/relay-state-of-the-state.html +++ b/blog/2016/08/05/relay-state-of-the-state.html @@ -64,7 +64,7 @@ @@ -195,6 +195,8 @@

    Recent posts

    diff --git a/blog/2016/09/28/our-first-50000-stars.html b/blog/2016/09/28/our-first-50000-stars.html index a928bb2d5e..294f4ebf26 100644 --- a/blog/2016/09/28/our-first-50000-stars.html +++ b/blog/2016/09/28/our-first-50000-stars.html @@ -64,7 +64,7 @@ @@ -335,6 +335,8 @@ I think we should just treat arrays of elements as a frag. This is useful for co

    Recent posts

    diff --git a/blog/2016/11/16/react-v15.4.0.html b/blog/2016/11/16/react-v15.4.0.html index f1697b1b34..85ca3e0237 100644 --- a/blog/2016/11/16/react-v15.4.0.html +++ b/blog/2016/11/16/react-v15.4.0.html @@ -64,7 +64,7 @@ @@ -281,6 +281,8 @@ Minified build for production: React v15.5.0 +
  • React v15.4.0
  • Our First 50,000 Stars
  • @@ -299,8 +301,6 @@ Minified build for production: React v0.14.8 -
  • React v15.0 Release Candidate 2
  • -
  • All posts ...
  • diff --git a/blog/2017/04/07/react-v15.5.0.html b/blog/2017/04/07/react-v15.5.0.html new file mode 100644 index 0000000000..84bed0f7c9 --- /dev/null +++ b/blog/2017/04/07/react-v15.5.0.html @@ -0,0 +1,422 @@ + + + + + + + + + React v15.5.0 - React Blog + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + +
    + +
    + + +

    + + React v15.5.0 + +

    + +

    + April 7, 2017 + by + + + Andrew Clark + + + +

    + +
    + +
    +

    It's been exactly one year since the last breaking change to React. Our next major release, React 16, will include some exciting improvements, including a complete rewrite of React's internals. We take stability seriously, and are committed to bringing those improvements to all of our users with minimal effort.

    + +

    To that end, today we're releasing React 15.5.0.

    + +

    New Deprecation Warnings

    + +

    The biggest change is that we've extracted React.PropTypes and React.createClass into their own packages. Both are still accessible via the main React object, but using either will log a one-time deprecation warning to the console when in development mode. This will enable future code size optimizations.

    + +

    These warnings will not affect the behavior of your application. However, we realize they may cause some frustration, particularly if you use a testing framework that treats console.error as a failure.

    + +

    Adding new warnings is not something we do lightly. Warnings in React are not mere suggestions — they are integral to our strategy of keeping as many people as possible on the latest version of React. We never add warnings without providing an incremental path forward.

    + +

    So while the warnings may cause frustration in the short-term, we believe prodding developers to migrate their codebases now prevents greater frustration in the future. Proactively fixing warnings ensures you are prepared for the next major release. If your app produces zero warnings in 15.5, it should continue to work in 16 without any changes.

    + +

    For each of these new deprecations, we've provided a codemod to automatically migrate your code. They are available as part of the react-codemod project.

    + +

    Migrating from React.PropTypes

    + +

    Prop types are a feature for runtime validation of props during development. We've extracted the built-in prop types to a separate package to reflect the fact that not everybody uses them.

    + +

    In 15.5, instead of accessing PropTypes from the main React object, install the prop-types package and import them from there:

    +
    // Before (15.4 and below)
    +import React from 'react';
    +
    +class Component extends React.Component {
    +  render() {
    +    return <div>{this.props.text}</div>;
    +  }
    +}
    +
    +Component.propTypes = {
    +  text: React.PropTypes.string.isRequired,
    +}
    +
    +// After (15.5)
    +import React from 'react';
    +import PropTypes from 'prop-types';
    +
    +class Component extends React.Component {
    +  render() {
    +    return <div>{this.props.text}</div>;
    +  }
    +}
    +
    +Component.propTypes = {
    +  text: PropTypes.string.isRequired,
    +};
    +
    +

    The codemod for this change performs this conversion automatically. Basic usage:

    +
    jscodeshift -t react-codemod/transforms/React-PropTypes-to-prop-types.js <path>
    +
    +

    The propTypes, contextTypes, and childContextTypes APIs will work exactly as before. The only change is that the built-in validators now live in a separate package.

    + +

    You may also consider using Flow to statically type check your JavaScript code, including React components.

    + +

    Migrating from React.createClass

    + +

    When React was initially released, there was no idiomatic way to create classes in JavaScript, so we provided our own: React.createClass.

    + +

    Later, classes were added to the language as part of ES2015, so we added the ability to create React components using JavaScript classes. Along with functional components, JavaScript classes are now the preferred way to create components in React.

    + +

    For your existing createClass components, we recommend that you migrate them to JavaScript classes. However, if you have components that rely on mixins, converting to classes may not be immediately feasible. If so, create-react-class is available on npm as a drop-in replacement:

    +
    // Before (15.4 and below)
    +var React = require('react');
    +
    +var Component = React.createClass({
    +  mixins: [MixinA],
    +  render() {
    +    return <Child />;
    +  }
    +});
    +
    +// After (15.5)
    +var React = require('react');
    +var createReactClass = require('create-react-class');
    +
    +var Component = createReactClass({
    +  mixins: [MixinA],
    +  render() {
    +    return <Child />;
    +  }
    +});
    +
    +

    Your components will continue to work the same as they did before.

    + +

    The codemod for this change attempts to convert a createClass component to a JavaScript class, with a fallback to create-react-class if necessary. It has converted thousands of components internally at Facebook.

    + +

    Basic usage:

    +
    jscodeshift -t react-codemod/transforms/class.js path/to/components
    +
    +

    Discontinuing support for React Addons

    + +

    We're discontinuing active maintenance of React Addons packages. In truth, most of these packages haven't been actively maintained in a long time. They will continue to work indefinitely, but we recommend migrating away as soon as you can to prevent future breakages.

    + +
      +
    • react-addons-create-fragment – React 16 will have first-class support for fragments, at which point this package won't be necessary. We recommend using arrays of keyed elements instead.
    • +
    • react-addons-css-transition-group - Use react-transition-group/CSSTransitionGroup instead. Version 1.1.1 provides a drop-in replacement.
    • +
    • react-addons-linked-state-mixin - Explicitly set the value and onChange handler instead.
    • +
    • react-addons-pure-render-mixin - Use React.PureComponent instead.
    • +
    • react-addons-shallow-compare - Use React.PureComponent instead.
    • +
    • react-addons-transition-group - Use react-transition-group/TransitionGroup instead. Version 1.1.1 provides a drop-in replacement.
    • +
    • react-addons-update - Use immutability-helper instead, a drop-in replacement.
    • +
    • react-linked-input - Explicitly set the value and onChange handler instead.
    • +
    + +

    We're also discontinuing support for the react-with-addons UMD build. It will be removed in React 16.

    + +

    React Test Utils

    + +

    Currently, the React Test Utils live inside react-addons-test-utils. As of 15.5, we're deprecating that package and moving them to react-dom/test-utils instead:

    +
    // Before (15.4 and below)
    +import TestUtils from 'react-addons-test-utils';
    +
    +// After (15.5)
    +import TestUtils from 'react-dom/test-utils';
    +
    +

    This reflects the fact that what we call the Test Utils are really a set of APIs that wrap the DOM renderer.

    + +

    The exception is shallow rendering, which is not DOM-specific. The shallow renderer has been moved to react-test-renderer/shallow.

    +
    // Before (15.4 and below)
    +import { createRenderer } from 'react-addons-test-utils';
    +
    +// After (15.5)
    +import { createRenderer } from 'react-test-renderer/shallow';
    +
    +
    + +

    Acknowledgements

    + +

    A special thank you to these folks for transferring ownership of npm package names:

    + + + +
    + +

    Installation

    + +

    We recommend using Yarn or npm for managing front-end dependencies. If you're new to package managers, the Yarn documentation is a good place to get started.

    + +

    To install React with Yarn, run:

    +
    yarn add react@15.5.0 react-dom@15.5.0
    +
    +

    To install React with npm, run:

    +
    npm install --save react@15.5.0 react-dom@15.5.0
    +
    +

    We recommend using a bundler like webpack or Browserify so you can write modular code and bundle it together into small packages to optimize load time.

    + +

    Remember that by default, React runs extra checks and provides helpful warnings in development mode. When deploying your app, make sure to compile it in production mode.

    + +

    In case you don't use a bundler, we also provide pre-built bundles in the npm packages which you can include as script tags on your page:

    + + + +

    We've also published version 15.5.0 of the react, react-dom, and addons packages on npm and the react package on bower.

    + +
    + +

    Changelog

    + +

    15.5.0 (April 7, 2017)

    + +

    React

    + +
      +
    • Added a deprecation warning for React.createClass. Points users to create-react-class instead. (@acdlite in d9a4fa4)
    • +
    • Added a deprecation warning for React.PropTypes. Points users to prop-types instead. (@acdlite in 043845c)
    • +
    • Fixed an issue when using ReactDOM together with ReactDOMServer. (@wacii in #9005)
    • +
    • Fixed issue with Closure Compiler. (@anmonteiro in #8895)
    • +
    • Another fix for Closure Compiler. (@Shastel in #8882)
    • +
    • Added component stack info to invalid element type warning. (@n3tr in #8495)
    • +
    + +

    React DOM

    + +
      +
    • Fixed Chrome bug when backspacing in number inputs. (@nhunzaker in #7359)
    • +
    • Added react-dom/test-utils, which exports the React Test Utils. (@bvaughn)
    • +
    + +

    React Test Renderer

    + +
      +
    • Fixed bug where componentWillUnmount was not called for children. (@gre in #8512)
    • +
    • Added react-test-renderer/shallow, which exports the shallow renderer. (@bvaughn)
    • +
    + +

    React Addons

    + +
      +
    • Last release for addons; they will no longer be actively maintained.
    • +
    • Removed peerDependencies so that addons continue to work indefinitely. (@acdlite and @bvaughn in 8a06cd7 and 67a8db3)
    • +
    • Updated to remove references to React.createClass and React.PropTypes (@acdlite in 12a96b9)
    • +
    • react-addons-test-utils is deprecated. Use react-dom/test-utils and react-test-renderer/shallow instead. (@bvaughn)
    • +
    + +
    + + +
    + + +
    + + +
    + + + + +
    + +
    + + + + diff --git a/blog/all.html b/blog/all.html index fb008e0439..cb55d47a7f 100644 --- a/blog/all.html +++ b/blog/all.html @@ -63,7 +63,7 @@ @@ -74,6 +74,13 @@

    All Posts

    +

    React v15.5.0 on April 7, 2017 by + + Andrew Clark + + +

    +

    React v15.4.0 on November 16, 2016 by Dan Abramov diff --git a/blog/index.html b/blog/index.html index 710ae82b1a..6365f802cf 100644 --- a/blog/index.html +++ b/blog/index.html @@ -63,7 +63,7 @@

    @@ -76,6 +76,8 @@

    Recent posts

    @@ -106,6 +106,247 @@
    +

    + + React v15.5.0 + +

    + +

    + April 7, 2017 + by + + + Andrew Clark + + + +

    + +
    + +
    +

    It's been exactly one year since the last breaking change to React. Our next major release, React 16, will include some exciting improvements, including a complete rewrite of React's internals. We take stability seriously, and are committed to bringing those improvements to all of our users with minimal effort.

    + +

    To that end, today we're releasing React 15.5.0.

    + +

    New Deprecation Warnings

    + +

    The biggest change is that we've extracted React.PropTypes and React.createClass into their own packages. Both are still accessible via the main React object, but using either will log a one-time deprecation warning to the console when in development mode. This will enable future code size optimizations.

    + +

    These warnings will not affect the behavior of your application. However, we realize they may cause some frustration, particularly if you use a testing framework that treats console.error as a failure.

    + +

    Adding new warnings is not something we do lightly. Warnings in React are not mere suggestions — they are integral to our strategy of keeping as many people as possible on the latest version of React. We never add warnings without providing an incremental path forward.

    + +

    So while the warnings may cause frustration in the short-term, we believe prodding developers to migrate their codebases now prevents greater frustration in the future. Proactively fixing warnings ensures you are prepared for the next major release. If your app produces zero warnings in 15.5, it should continue to work in 16 without any changes.

    + +

    For each of these new deprecations, we've provided a codemod to automatically migrate your code. They are available as part of the react-codemod project.

    + +

    Migrating from React.PropTypes

    + +

    Prop types are a feature for runtime validation of props during development. We've extracted the built-in prop types to a separate package to reflect the fact that not everybody uses them.

    + +

    In 15.5, instead of accessing PropTypes from the main React object, install the prop-types package and import them from there:

    +
    // Before (15.4 and below)
    +import React from 'react';
    +
    +class Component extends React.Component {
    +  render() {
    +    return <div>{this.props.text}</div>;
    +  }
    +}
    +
    +Component.propTypes = {
    +  text: React.PropTypes.string.isRequired,
    +}
    +
    +// After (15.5)
    +import React from 'react';
    +import PropTypes from 'prop-types';
    +
    +class Component extends React.Component {
    +  render() {
    +    return <div>{this.props.text}</div>;
    +  }
    +}
    +
    +Component.propTypes = {
    +  text: PropTypes.string.isRequired,
    +};
    +
    +

    The codemod for this change performs this conversion automatically. Basic usage:

    +
    jscodeshift -t react-codemod/transforms/React-PropTypes-to-prop-types.js <path>
    +
    +

    The propTypes, contextTypes, and childContextTypes APIs will work exactly as before. The only change is that the built-in validators now live in a separate package.

    + +

    You may also consider using Flow to statically type check your JavaScript code, including React components.

    + +

    Migrating from React.createClass

    + +

    When React was initially released, there was no idiomatic way to create classes in JavaScript, so we provided our own: React.createClass.

    + +

    Later, classes were added to the language as part of ES2015, so we added the ability to create React components using JavaScript classes. Along with functional components, JavaScript classes are now the preferred way to create components in React.

    + +

    For your existing createClass components, we recommend that you migrate them to JavaScript classes. However, if you have components that rely on mixins, converting to classes may not be immediately feasible. If so, create-react-class is available on npm as a drop-in replacement:

    +
    // Before (15.4 and below)
    +var React = require('react');
    +
    +var Component = React.createClass({
    +  mixins: [MixinA],
    +  render() {
    +    return <Child />;
    +  }
    +});
    +
    +// After (15.5)
    +var React = require('react');
    +var createReactClass = require('create-react-class');
    +
    +var Component = createReactClass({
    +  mixins: [MixinA],
    +  render() {
    +    return <Child />;
    +  }
    +});
    +
    +

    Your components will continue to work the same as they did before.

    + +

    The codemod for this change attempts to convert a createClass component to a JavaScript class, with a fallback to create-react-class if necessary. It has converted thousands of components internally at Facebook.

    + +

    Basic usage:

    +
    jscodeshift -t react-codemod/transforms/class.js path/to/components
    +
    +

    Discontinuing support for React Addons

    + +

    We're discontinuing active maintenance of React Addons packages. In truth, most of these packages haven't been actively maintained in a long time. They will continue to work indefinitely, but we recommend migrating away as soon as you can to prevent future breakages.

    + + + +

    We're also discontinuing support for the react-with-addons UMD build. It will be removed in React 16.

    + +

    React Test Utils

    + +

    Currently, the React Test Utils live inside react-addons-test-utils. As of 15.5, we're deprecating that package and moving them to react-dom/test-utils instead:

    +
    // Before (15.4 and below)
    +import TestUtils from 'react-addons-test-utils';
    +
    +// After (15.5)
    +import TestUtils from 'react-dom/test-utils';
    +
    +

    This reflects the fact that what we call the Test Utils are really a set of APIs that wrap the DOM renderer.

    + +

    The exception is shallow rendering, which is not DOM-specific. The shallow renderer has been moved to react-test-renderer/shallow.

    +
    // Before (15.4 and below)
    +import { createRenderer } from 'react-addons-test-utils';
    +
    +// After (15.5)
    +import { createRenderer } from 'react-test-renderer/shallow';
    +
    +
    + +

    Acknowledgements

    + +

    A special thank you to these folks for transferring ownership of npm package names:

    + + + +
    + +

    Installation

    + +

    We recommend using Yarn or npm for managing front-end dependencies. If you're new to package managers, the Yarn documentation is a good place to get started.

    + +

    To install React with Yarn, run:

    +
    yarn add react@15.5.0 react-dom@15.5.0
    +
    +

    To install React with npm, run:

    +
    npm install --save react@15.5.0 react-dom@15.5.0
    +
    +

    We recommend using a bundler like webpack or Browserify so you can write modular code and bundle it together into small packages to optimize load time.

    + +

    Remember that by default, React runs extra checks and provides helpful warnings in development mode. When deploying your app, make sure to compile it in production mode.

    + +

    In case you don't use a bundler, we also provide pre-built bundles in the npm packages which you can include as script tags on your page:

    + + + +

    We've also published version 15.5.0 of the react, react-dom, and addons packages on npm and the react package on bower.

    + +
    + +

    Changelog

    + +

    15.5.0 (April 7, 2017)

    + +

    React

    + + + +

    React DOM

    + + + +

    React Test Renderer

    + + + +

    React Addons

    + + + +
    + + + +
    + +
    + +

    React v15.4.0 @@ -858,599 +1099,6 @@ The console output is tuned to be minimal to help you focus on the problems:

    -

    - -
    - - -

    - - Mixins Considered Harmful - -

    - -

    - July 13, 2016 - by - - - Dan Abramov - - - -

    - -
    - -
    -

    “How do I share the code between several components?” is one of the first questions that people ask when they learn React. Our answer has always been to use component composition for code reuse. You can define a component and use it in several other components.

    - -

    It is not always obvious how a certain pattern can be solved with composition. React is influenced by functional programming but it came into the field that was dominated by object-oriented libraries. It was hard for engineers both inside and outside of Facebook to give up on the patterns they were used to.

    - -

    To ease the initial adoption and learning, we included certain escape hatches into React. The mixin system was one of those escape hatches, and its goal was to give you a way to reuse code between components when you aren’t sure how to solve the same problem with composition.

    - -

    Three years passed since React was released. The landscape has changed. Multiple view libraries now adopt a component model similar to React. Using composition over inheritance to build declarative user interfaces is no longer a novelty. We are also more confident in the React component model, and we have seen many creative uses of it both internally and in the community.

    - -

    In this post, we will consider the problems commonly caused by mixins. Then we will suggest several alternative patterns for the same use cases. We have found those patterns to scale better with the complexity of the codebase than mixins.

    - -

    Why Mixins are Broken

    - -

    At Facebook, React usage has grown from a few components to thousands of them. This gives us a window into how people use React. Thanks to declarative rendering and top-down data flow, many teams were able to fix a bunch of bugs while shipping new features as they adopted React.

    - -

    However it’s inevitable that some of our code using React gradually became incomprehensible. Occasionally, the React team would see groups of components in different projects that people were afraid to touch. These components were too easy to break accidentally, were confusing to new developers, and eventually became just as confusing to the people who wrote them in the first place. Much of this confusion was caused by mixins. At the time, I wasn’t working at Facebook but I came to the same conclusions after writing my fair share of terrible mixins.

    - -

    This doesn’t mean that mixins themselves are bad. People successfully employ them in different languages and paradigms, including some functional languages. At Facebook, we extensively use traits in Hack which are fairly similar to mixins. Nevertheless, we think that mixins are unnecessary and problematic in React codebases. Here’s why.

    - -

    Mixins introduce implicit dependencies

    - -

    Sometimes a component relies on a certain method defined in the mixin, such as getClassName(). Sometimes it’s the other way around, and mixin calls a method like renderHeader() on the component. JavaScript is a dynamic language so it’s hard to enforce or document these dependencies.

    - -

    Mixins break the common and usually safe assumption that you can rename a state key or a method by searching for its occurrences in the component file. You might write a stateful component and then your coworker might add a mixin that reads this state. In a few months, you might want to move that state up to the parent component so it can be shared with a sibling. Will you remember to update the mixin to read a prop instead? What if, by now, other components also use this mixin?

    - -

    These implicit dependencies make it hard for new team members to contribute to a codebase. A component’s render() method might reference some method that isn’t defined on the class. Is it safe to remove? Perhaps it’s defined in one of the mixins. But which one of them? You need to scroll up to the mixin list, open each of those files, and look for this method. Worse, mixins can specify their own mixins, so the search can be deep.

    - -

    Often, mixins come to depend on other mixins, and removing one of them breaks the other. In these situations it is very tricky to tell how the data flows in and out of mixins, and what their dependency graph looks like. Unlike components, mixins don’t form a hierarchy: they are flattened and operate in the same namespace.

    - -

    Mixins cause name clashes

    - -

    There is no guarantee that two particular mixins can be used together. For example, if FluxListenerMixin defines handleChange() and WindowSizeMixin defines handleChange(), you can’t use them together. You also can’t define a method with this name on your own component.

    - -

    It’s not a big deal if you control the mixin code. When you have a conflict, you can rename that method on one of the mixins. However it’s tricky because some components or other mixins may already be calling this method directly, and you need to find and fix those calls as well.

    - -

    If you have a name conflict with a mixin from a third party package, you can’t just rename a method on it. Instead, you have to use awkward method names on your component to avoid clashes.

    - -

    The situation is no better for mixin authors. Even adding a new method to a mixin is always a potentially breaking change because a method with the same name might already exist on some of the components using it, either directly or through another mixin. Once written, mixins are hard to remove or change. Bad ideas don’t get refactored away because refactoring is too risky.

    - -

    Mixins cause snowballing complexity

    - -

    Even when mixins start out simple, they tend to become complex over time. The example below is based on a real scenario I’ve seen play out in a codebase.

    - -

    A component needs some state to track mouse hover. To keep this logic reusable, you might extract handleMouseEnter(), handleMouseLeave() and isHovering() into a HoverMixin. Next, somebody needs to implement a tooltip. They don’t want to duplicate the logic in HoverMixin so they create a TooltipMixin that uses HoverMixin. TooltipMixin reads isHovering() provided by HoverMixin in its componentDidUpdate() and either shows or hides the tooltip.

    - -

    A few months later, somebody wants to make the tooltip direction configurable. In an effort to avoid code duplication, they add support for a new optional method called getTooltipOptions() to TooltipMixin. By this time, components that show popovers also use HoverMixin. However popovers need a different hover delay. To solve this, somebody adds support for an optional getHoverOptions() method and implements it in TooltipMixin. Those mixins are now tightly coupled.

    - -

    This is fine while there are no new requirements. However this solution doesn’t scale well. What if you want to support displaying multiple tooltips in a single component? You can’t define the same mixin twice in a component. What if the tooltips need to be displayed automatically in a guided tour instead of on hover? Good luck decoupling TooltipMixin from HoverMixin. What if you need to support the case where the hover area and the tooltip anchor are located in different components? You can’t easily hoist the state used by mixin up into the parent component. Unlike components, mixins don’t lend themselves naturally to such changes.

    - -

    Every new requirement makes the mixins harder to understand. Components using the same mixin become increasingly coupled with time. Any new capability gets added to all of the components using that mixin. There is no way to split a “simpler” part of the mixin without either duplicating the code or introducing more dependencies and indirection between mixins. Gradually, the encapsulation boundaries erode, and since it’s hard to change or remove the existing mixins, they keep getting more abstract until nobody understands how they work.

    - -

    These are the same problems we faced building apps before React. We found that they are solved by declarative rendering, top-down data flow, and encapsulated components. At Facebook, we have been migrating our code to use alternative patterns to mixins, and we are generally happy with the results. You can read about those patterns below.

    - -

    Migrating from Mixins

    - -

    Let’s make it clear that mixins are not technically deprecated. If you use React.createClass(), you may keep using them. We only say that they didn’t work well for us, and so we won’t recommend using them in the future.

    - -

    Every section below corresponds to a mixin usage pattern that we found in the Facebook codebase. For each of them, we describe the problem and a solution that we think works better than mixins. The examples are written in ES5 but once you don’t need mixins, you can switch to ES6 classes if you’d like.

    - -

    We hope that you find this list helpful. Please let us know if we missed important use cases so we can either amend the list or be proven wrong!

    - -

    Performance Optimizations

    - -

    One of the most commonly used mixins is PureRenderMixin. You might be using it in some components to prevent unnecessary re-renders when the props and state are shallowly equal to the previous props and state:

    -
    var PureRenderMixin = require('react-addons-pure-render-mixin');
    -
    -var Button = React.createClass({
    -  mixins: [PureRenderMixin],
    -
    -  // ...
    -
    -});
    -
    -

    Solution

    - -

    To express the same without mixins, you can use the shallowCompare function directly instead:

    -
    var shallowCompare = require('react-addons-shallow-compare');
    -
    -var Button = React.createClass({
    -  shouldComponentUpdate: function(nextProps, nextState) {
    -    return shallowCompare(this, nextProps, nextState);
    -  },
    -
    -  // ...
    -
    -});
    -
    -

    If you use a custom mixin implementing a shouldComponentUpdate function with different algorithm, we suggest exporting just that single function from a module and calling it directly from your components.

    - -

    We understand that more typing can be annoying. For the most common case, we plan to introduce a new base class called React.PureComponent in the next minor release. It uses the same shallow comparison as PureRenderMixin does today.

    - -

    Subscriptions and Side Effects

    - -

    The second most common type of mixins that we encountered are mixins that subscribe a React component to a third-party data source. Whether this data source is a Flux Store, an Rx Observable, or something else, the pattern is very similar: the subscription is created in componentDidMount, destroyed in componentWillUnmount, and the change handler calls this.setState().

    -
    var SubscriptionMixin = {
    -  getInitialState: function() {
    -    return {
    -      comments: DataSource.getComments()
    -    };
    -  },
    -
    -  componentDidMount: function() {
    -    DataSource.addChangeListener(this.handleChange);
    -  },
    -
    -  componentWillUnmount: function() {
    -    DataSource.removeChangeListener(this.handleChange);
    -  },
    -
    -  handleChange: function() {
    -    this.setState({
    -      comments: DataSource.getComments()
    -    });
    -  }
    -};
    -
    -var CommentList = React.createClass({
    -  mixins: [SubscriptionMixin],
    -
    -  render: function() {
    -    // Reading comments from state managed by mixin.
    -    var comments = this.state.comments;
    -    return (
    -      <div>
    -        {comments.map(function(comment) {
    -          return <Comment comment={comment} key={comment.id} />
    -        })}
    -      </div>
    -    )
    -  }
    -});
    -
    -module.exports = CommentList;
    -
    -

    Solution

    - -

    If there is just one component subscribed to this data source, it is fine to embed the subscription logic right into the component. Avoid premature abstractions.

    - -

    If several components used this mixin to subscribe to a data source, a nice way to avoid repetition is to use a pattern called “higher-order components”. It can sound intimidating so we will take a closer look at how this pattern naturally emerges from the component model.

    - -

    Higher-Order Components Explained

    - -

    Let’s forget about React for a second. Consider these two functions that add and multiply numbers, logging the results as they do that:

    -
    function addAndLog(x, y) {
    -  var result = x + y;
    -  console.log('result:', result);
    -  return result;
    -}
    -
    -function multiplyAndLog(x, y) {
    -  var result = x * y;
    -  console.log('result:', result);
    -  return result;
    -}
    -
    -

    These two functions are not very useful but they help us demonstrate a pattern that we can later apply to components.

    - -

    Let’s say that we want to extract the logging logic out of these functions without changing their signatures. How can we do this? An elegant solution is to write a higher-order function, that is, a function that takes a function as an argument and returns a function.

    - -

    Again, it sounds more intimidating than it really is:

    -
    function withLogging(wrappedFunction) {
    -  // Return a function with the same API...
    -  return function(x, y) {
    -    // ... that calls the original function
    -    var result = wrappedFunction(x, y);
    -    // ... but also logs its result!
    -    console.log('result:', result);
    -    return result;
    -  };
    -}
    -
    -

    The withLogging higher-order function lets us write add and multiply without the logging statements, and later wrap them to get addAndLog and multiplyAndLog with exactly the same signatures as before:

    -
    function add(x, y) {
    -  return x + y;
    -}
    -
    -function multiply(x, y) {
    -  return x * y;
    -}
    -
    -function withLogging(wrappedFunction) {
    -  return function(x, y) {
    -    var result = wrappedFunction(x, y);
    -    console.log('result:', result);
    -    return result;
    -  };
    -}
    -
    -// Equivalent to writing addAndLog by hand:
    -var addAndLog = withLogging(add);
    -
    -// Equivalent to writing multiplyAndLog by hand:
    -var multiplyAndLog = withLogging(multiply);
    -
    -

    Higher-order components are a very similar pattern, but applied to components in React. We will apply this transformation from mixins in two steps.

    - -

    As a first step, we will split our CommentList component in two, a child and a parent. The child will be only concerned with rendering the comments. The parent will set up the subscription and pass the up-to-date data to the child via props.

    -
    // This is a child component.
    -// It only renders the comments it receives as props.
    -var CommentList = React.createClass({
    -  render: function() {
    -    // Note: now reading from props rather than state.
    -    var comments = this.props.comments;
    -    return (
    -      <div>
    -        {comments.map(function(comment) {
    -          return <Comment comment={comment} key={comment.id} />
    -        })}
    -      </div>
    -    )
    -  }
    -});
    -
    -// This is a parent component.
    -// It subscribes to the data source and renders <CommentList />.
    -var CommentListWithSubscription = React.createClass({
    -  getInitialState: function() {
    -    return {
    -      comments: DataSource.getComments()
    -    };
    -  },
    -
    -  componentDidMount: function() {
    -    DataSource.addChangeListener(this.handleChange);
    -  },
    -
    -  componentWillUnmount: function() {
    -    DataSource.removeChangeListener(this.handleChange);
    -  },
    -
    -  handleChange: function() {
    -    this.setState({
    -      comments: DataSource.getComments()
    -    });
    -  },
    -
    -  render: function() {
    -    // We pass the current state as props to CommentList.
    -    return <CommentList comments={this.state.comments} />;
    -  }
    -});
    -
    -module.exports = CommentListWithSubscription;
    -
    -

    There is just one final step left to do.

    - -

    Remember how we made withLogging() take a function and return another function wrapping it? We can apply a similar pattern to React components.

    - -

    We will write a new function called withSubscription(WrappedComponent). Its argument could be any React component. We will pass CommentList as WrappedComponent, but we could also apply withSubscription() to any other component in our codebase.

    - -

    This function would return another component. The returned component would manage the subscription and render <WrappedComponent /> with the current data.

    - -

    We call this pattern a “higher-order component”.

    - -

    The composition happens at React rendering level rather than with a direct function call. This is why it doesn’t matter whether the wrapped component is defined with createClass(), as an ES6 class or a function. If WrappedComponent is a React component, the component created by withSubscription() can render it.

    -
    // This function takes a component...
    -function withSubscription(WrappedComponent) {
    -  // ...and returns another component...
    -  return React.createClass({
    -    getInitialState: function() {
    -      return {
    -        comments: DataSource.getComments()
    -      };
    -    },
    -
    -    componentDidMount: function() {
    -      // ... that takes care of the subscription...
    -      DataSource.addChangeListener(this.handleChange);
    -    },
    -
    -    componentWillUnmount: function() {
    -      DataSource.removeChangeListener(this.handleChange);
    -    },
    -
    -    handleChange: function() {
    -      this.setState({
    -        comments: DataSource.getComments()
    -      });
    -    },
    -
    -    render: function() {
    -      // ... and renders the wrapped component with the fresh data!
    -      return <WrappedComponent comments={this.state.comments} />;
    -    }
    -  });
    -}
    -
    -

    Now we can declare CommentListWithSubscription by applying withSubscription to CommentList:

    -
    var CommentList = React.createClass({
    -  render: function() {
    -    var comments = this.props.comments;
    -    return (
    -      <div>
    -        {comments.map(function(comment) {
    -          return <Comment comment={comment} key={comment.id} />
    -        })}
    -      </div>
    -    )
    -  }
    -});
    -
    -// withSubscription() returns a new component that
    -// is subscribed to the data source and renders
    -// <CommentList /> with up-to-date data.
    -var CommentListWithSubscription = withSubscription(CommentList);
    -
    -// The rest of the app is interested in the subscribed component
    -// so we export it instead of the original unwrapped CommentList.
    -module.exports = CommentListWithSubscription;
    -
    -

    Solution, Revisited

    - -

    Now that we understand higher-order components better, let’s take another look at the complete solution that doesn’t involve mixins. There are a few minor changes that are annotated with inline comments:

    -
    function withSubscription(WrappedComponent) {
    -  return React.createClass({
    -    getInitialState: function() {
    -      return {
    -        comments: DataSource.getComments()
    -      };
    -    },
    -
    -    componentDidMount: function() {
    -      DataSource.addChangeListener(this.handleChange);
    -    },
    -
    -    componentWillUnmount: function() {
    -      DataSource.removeChangeListener(this.handleChange);
    -    },
    -
    -    handleChange: function() {
    -      this.setState({
    -        comments: DataSource.getComments()
    -      });
    -    },
    -
    -    render: function() {
    -      // Use JSX spread syntax to pass all props and state down automatically.
    -      return <WrappedComponent {...this.props} {...this.state} />;
    -    }
    -  });
    -}
    -
    -// Optional change: convert CommentList to a functional component
    -// because it doesn't use lifecycle hooks or state.
    -function CommentList(props) {
    -  var comments = props.comments;
    -  return (
    -    <div>
    -      {comments.map(function(comment) {
    -        return <Comment comment={comment} key={comment.id} />
    -      })}
    -    </div>
    -  )
    -}
    -
    -// Instead of declaring CommentListWithSubscription,
    -// we export the wrapped component right away.
    -module.exports = withSubscription(CommentList);
    -
    -

    Higher-order components are a powerful pattern. You can pass additional arguments to them if you want to further customize their behavior. After all, they are not even a feature of React. They are just functions that receive components and return components that wrap them.

    - -

    Like any solution, higher-order components have their own pitfalls. For example, if you heavily use refs, you might notice that wrapping something into a higher-order component changes the ref to point to the wrapping component. In practice we discourage using refs for component communication so we don’t think it’s a big issue. In the future, we might consider adding ref forwarding to React to solve this annoyance.

    - -

    Rendering Logic

    - -

    The next most common use case for mixins that we discovered in our codebase is sharing rendering logic between components.

    - -

    Here is a typical example of this pattern:

    -
    var RowMixin = {
    -  // Called by components from render()
    -  renderHeader: function() {
    -    return (
    -      <div className='row-header'>
    -        <h1>
    -          {this.getHeaderText() /* Defined by components */}
    -        </h1>
    -      </div>
    -    );
    -  }
    -};
    -
    -var UserRow = React.createClass({
    -  mixins: [RowMixin],
    -
    -  // Called by RowMixin.renderHeader()
    -  getHeaderText: function() {
    -    return this.props.user.fullName;
    -  },
    -
    -  render: function() {
    -    return (
    -      <div>
    -        {this.renderHeader() /* Defined by RowMixin */}
    -        <h2>{this.props.user.biography}</h2>
    -      </div>
    -    )
    -  }
    -});
    -
    -

    Multiple components may be sharing RowMixin to render the header, and each of them would need to define getHeaderText().

    - -

    Solution

    - -

    If you see rendering logic inside a mixin, it’s time to extract a component!

    - -

    Instead of RowMixin, we will define a <RowHeader> component. We will also replace the convention of defining a getHeaderText() method with the standard mechanism of top-data flow in React: passing props.

    - -

    Finally, since neither of those components currently need lifecycle hooks or state, we can declare them as simple functions:

    -
    function RowHeader(props) {
    -  return (
    -    <div className='row-header'>
    -      <h1>{props.text}</h1>
    -    </div>
    -  );
    -}
    -
    -function UserRow(props) {
    -  return (
    -    <div>
    -      <RowHeader text={props.user.fullName} />
    -      <h2>{props.user.biography}</h2>
    -    </div>
    -  );
    -}
    -
    -

    Props keep component dependencies explicit, easy to replace, and enforceable with tools like Flow and TypeScript.

    - -
    -

    Note:

    - -

    Defining components as functions is not required. There is also nothing wrong with using lifecycle hooks and state—they are first-class React features. We use functional components in this example because they are easier to read and we didn’t need those extra features, but classes would work just as fine.

    -
    - -

    Context

    - -

    Another group of mixins we discovered were helpers for providing and consuming React context. Context is an experimental unstable feature, has certain issues, and will likely change its API in the future. We don’t recommend using it unless you’re confident there is no other way of solving your problem.

    - -

    Nevertheless, if you already use context today, you might have been hiding its usage with mixins like this:

    -
    var RouterMixin = {
    -  contextTypes: {
    -    router: React.PropTypes.object.isRequired
    -  },
    -
    -  // The mixin provides a method so that components
    -  // don't have to use the context API directly.
    -  push: function(path) {
    -    this.context.router.push(path)
    -  }
    -};
    -
    -var Link = React.createClass({
    -  mixins: [RouterMixin],
    -
    -  handleClick: function(e) {
    -    e.stopPropagation();
    -
    -    // This method is defined in RouterMixin.
    -    this.push(this.props.to);
    -  },
    -
    -  render: function() {
    -    return (
    -      <a onClick={this.handleClick}>
    -        {this.props.children}
    -      </a>
    -    );
    -  }
    -});
    -
    -module.exports = Link;
    -
    -

    Solution

    - -

    We agree that hiding context usage from consuming components is a good idea until the context API stabilizes. However, we recommend using higher-order components instead of mixins for this.

    - -

    Let the wrapping component grab something from the context, and pass it down with props to the wrapped component:

    -
    function withRouter(WrappedComponent) {
    -  return React.createClass({
    -    contextTypes: {
    -      router: React.PropTypes.object.isRequired
    -    },
    -
    -    render: function() {
    -      // The wrapper component reads something from the context
    -      // and passes it down as a prop to the wrapped component.
    -      var router = this.context.router;
    -      return <WrappedComponent {...this.props} router={router} />;
    -    }
    -  });
    -};
    -
    -var Link = React.createClass({
    -  handleClick: function(e) {
    -    e.stopPropagation();
    -
    -    // The wrapped component uses props instead of context.
    -    this.props.router.push(this.props.to);
    -  },
    -
    -  render: function() {
    -    return (
    -      <a onClick={this.handleClick}>
    -        {this.props.children}
    -      </a>
    -    );
    -  }
    -});
    -
    -// Don't forget to wrap the component!
    -module.exports = withRouter(Link);
    -
    -

    If you’re using a third party library that only provides a mixin, we encourage you to file an issue with them linking to this post so that they can provide a higher-order component instead. In the meantime, you can create a higher-order component around it yourself in exactly the same way.

    - -

    Utility Methods

    - -

    Sometimes, mixins are used solely to share utility functions between components:

    -
    var ColorMixin = {
    -  getLuminance(color) {
    -    var c = parseInt(color, 16);
    -    var r = (c & 0xFF0000) >> 16;
    -    var g = (c & 0x00FF00) >> 8;
    -    var b = (c & 0x0000FF);
    -    return (0.299 * r + 0.587 * g + 0.114 * b);
    -  }
    -};
    -
    -var Button = React.createClass({
    -  mixins: [ColorMixin],
    -
    -  render: function() {
    -    var theme = this.getLuminance(this.props.color) > 160 ? 'dark' : 'light';
    -    return (
    -      <div className={theme}>
    -        {this.props.children}
    -      </div>
    -    )
    -  }
    -});
    -
    -

    Solution

    - -

    Put utility functions into regular JavaScript modules and import them. This also makes it easier to test them or use them outside of your components:

    -
    var getLuminance = require('../utils/getLuminance');
    -
    -var Button = React.createClass({
    -  render: function() {
    -    var theme = getLuminance(this.props.color) > 160 ? 'dark' : 'light';
    -    return (
    -      <div className={theme}>
    -        {this.props.children}
    -      </div>
    -    )
    -  }
    -});
    -
    -

    Other Use Cases

    - -

    Sometimes people use mixins to selectively add logging to lifecycle hooks in some components. In the future, we intend to provide an official DevTools API that would let you implement something similar without touching the components. However it’s still very much a work in progress. If you heavily depend on logging mixins for debugging, you might want to keep using those mixins for a little longer.

    - -

    If you can’t accomplish something with a component, a higher-order component, or a utility module, it could be mean that React should provide this out of the box. File an issue to tell us about your use case for mixins, and we’ll help you consider alternatives or perhaps implement your feature request.

    - -

    Mixins are not deprecated in the traditional sense. You can keep using them with React.createClass(), as we won’t be changing it further. Eventually, as ES6 classes gain more adoption and their usability problems in React are solved, we might split React.createClass() into a separate package because most people wouldn’t need it. Even in that case, your old mixins would keep working.

    - -

    We believe that the alternatives above are better for the vast majority of cases, and we invite you to try writing React apps without using mixins.

    - -
    - - -
    diff --git a/blog/page10/index.html b/blog/page10/index.html index 417a358bc1..6a5c0f9e61 100644 --- a/blog/page10/index.html +++ b/blog/page10/index.html @@ -63,7 +63,7 @@ @@ -76,6 +76,8 @@

    Recent posts

    @@ -106,6 +106,124 @@
    +

    + + React v0.13 RC + +

    + +

    + February 24, 2015 + by + + + Paul O’Shannessy + + + +

    + +
    + +
    +

    Over the weekend we pushed out our first (and hopefully only) release candidate for React v0.13!

    + +

    We've talked a little bit about the changes that are coming. The splashiest of these changes is support for ES6 Classes. You can read more about this in our beta announcement. We're really excited about this! Sebastian also posted earlier this morning about some of the other changes coming focused around ReactElement. The changes we've been working on there will hopefully enable lots of improvements to performance and developer experience.

    + +

    The release candidate is available for download:

    + + + +

    We've also published version 0.13.0-rc1 of the react and react-tools packages on npm and the react package on bower.

    + +
    + +

    Changelog

    + +

    React Core

    + +

    Breaking Changes

    + + + +

    New Features

    + + + +

    Deprecations

    + + + +

    React with Add-Ons

    + +

    Deprecations

    + + + +

    React Tools

    + +

    Breaking Changes

    + + + +

    New Features

    + + + +

    JSX

    + +

    Breaking Changes

    + + + +
    + + + +
    + +
    + +

    Streamlining React Elements @@ -870,74 +988,6 @@ -

    - -
    - - -

    - - React.js Conf Diversity Scholarship - -

    - -

    - December 19, 2014 - by - - - Paul O’Shannessy - - - -

    - -
    - -
    -

    Today I'm really happy to announce the React.js Conf Diversity Scholarship! We believe that a diverse set of viewpoints and opinions is really important to build a thriving community. In an ideal world, every part of the tech community would be made up of people from all walks of life. However the reality is that we must be proactive and make an effort to make sure everybody has a voice. As conference organizers we worked closely with the Diversity Team here at Facebook to set aside 10 tickets and provide a scholarship. 10 tickets may not be many in the grand scheme but we really believe that this will have a positive impact on the discussions we have at the conference.

    - -

    I'm really excited about this and I hope you are too! The full announcement is below:

    - -
    - -

    The Diversity Team at Facebook is excited to announce that we are now accepting applications for the React.js Conf scholarship!

    - -

    Beginning today, those studying or working in computer science or a related field can apply for an all-expense paid scholarship to attend the React.js Conf at Facebook’s Headquarters in Menlo Park, CA on January 28 & 29, 2015. React opens a world of new possibilities such as server-side rendering, real-time updates, different rendering targets like SVG and canvas. Join us at React.js Conf to shape the future of client-side applications! For more information about the React.js conference, please see the website and previous updates on our blog.

    - -

    At Facebook, we believe that anyone anywhere can make a positive impact by developing products to make the world more open and connected to the people and things they care about. Given the current realities of the tech industry and the lack of representation of communities we seek to serve, applicants currently under-represented in Computer Science and related fields are strongly encouraged to apply. -Facebook will make determinations on scholarship recipients in its sole discretion. Facebook complies with all equal opportunity laws.

    - -

    To apply for the scholarship, please visit the Application Page: https://www.surveymonkey.com/s/XVJGK6R

    - -

    Award Includes

    - - - -

    Important Dates

    - - - -

    Eligibility

    - - - -
    - - -
    diff --git a/blog/page11/index.html b/blog/page11/index.html index 7196263787..5a0a9c4318 100644 --- a/blog/page11/index.html +++ b/blog/page11/index.html @@ -63,7 +63,7 @@ @@ -76,6 +76,8 @@

    Recent posts

    @@ -106,6 +106,74 @@
    +

    + + React.js Conf Diversity Scholarship + +

    + +

    + December 19, 2014 + by + + + Paul O’Shannessy + + + +

    + +
    + +
    +

    Today I'm really happy to announce the React.js Conf Diversity Scholarship! We believe that a diverse set of viewpoints and opinions is really important to build a thriving community. In an ideal world, every part of the tech community would be made up of people from all walks of life. However the reality is that we must be proactive and make an effort to make sure everybody has a voice. As conference organizers we worked closely with the Diversity Team here at Facebook to set aside 10 tickets and provide a scholarship. 10 tickets may not be many in the grand scheme but we really believe that this will have a positive impact on the discussions we have at the conference.

    + +

    I'm really excited about this and I hope you are too! The full announcement is below:

    + +
    + +

    The Diversity Team at Facebook is excited to announce that we are now accepting applications for the React.js Conf scholarship!

    + +

    Beginning today, those studying or working in computer science or a related field can apply for an all-expense paid scholarship to attend the React.js Conf at Facebook’s Headquarters in Menlo Park, CA on January 28 & 29, 2015. React opens a world of new possibilities such as server-side rendering, real-time updates, different rendering targets like SVG and canvas. Join us at React.js Conf to shape the future of client-side applications! For more information about the React.js conference, please see the website and previous updates on our blog.

    + +

    At Facebook, we believe that anyone anywhere can make a positive impact by developing products to make the world more open and connected to the people and things they care about. Given the current realities of the tech industry and the lack of representation of communities we seek to serve, applicants currently under-represented in Computer Science and related fields are strongly encouraged to apply. +Facebook will make determinations on scholarship recipients in its sole discretion. Facebook complies with all equal opportunity laws.

    + +

    To apply for the scholarship, please visit the Application Page: https://www.surveymonkey.com/s/XVJGK6R

    + +

    Award Includes

    + + + +

    Important Dates

    + + + +

    Eligibility

    + + + +
    + + + +
    + +
    + +

    React v0.12.2 @@ -535,45 +603,6 @@ Minified build for production: - - -

    - - React.js Conf - -

    - -

    - October 27, 2014 - by - - - Vjeux - - - -

    - -
    - -
    -

    Every few weeks someone asks us when we are going to organize a conference for React. Our answer has always been "some day". In the mean time, people have been talking about React at other JavaScript conferences around the world. But now the time has finally come for us to have a conference of our own.

    - -

    We're happy to announce React.js Conf! It will take place January 28-29, 2015 on Facebook's campus in Menlo Park, California.

    - -

    Before we open registration, we're looking for great talks. We want to see how you pushed application development forward! If you ever talked to a meet-up, pitched React to your co-workers, or done something awesome and want to talk about it, let us know!

    - -

    Here are some areas of research we want to explore during the conference if you need some inspiration: server-side rendering, data fetching, language features (eg es6, clojure), immutability, rendering targets (eg svg, canvas), real-time updates...

    - -

    We look forward to seeing many of you in person in just a few short months!

    - -
    - - -

    diff --git a/blog/page12/index.html b/blog/page12/index.html index d2dfd1e1dd..41d0f61d98 100644 --- a/blog/page12/index.html +++ b/blog/page12/index.html @@ -63,7 +63,7 @@ @@ -76,6 +76,8 @@

    Recent posts

    @@ -106,6 +106,45 @@
    +

    + + React.js Conf + +

    + +

    + October 27, 2014 + by + + + Vjeux + + + +

    + +
    + +
    +

    Every few weeks someone asks us when we are going to organize a conference for React. Our answer has always been "some day". In the mean time, people have been talking about React at other JavaScript conferences around the world. But now the time has finally come for us to have a conference of our own.

    + +

    We're happy to announce React.js Conf! It will take place January 28-29, 2015 on Facebook's campus in Menlo Park, California.

    + +

    Before we open registration, we're looking for great talks. We want to see how you pushed application development forward! If you ever talked to a meet-up, pitched React to your co-workers, or done something awesome and want to talk about it, let us know!

    + +

    Here are some areas of research we want to explore during the conference if you need some inspiration: server-side rendering, data fetching, language features (eg es6, clojure), immutability, rendering targets (eg svg, canvas), real-time updates...

    + +

    We look forward to seeing many of you in person in just a few short months!

    + +
    + + + +
    + +
    + +

    Community Round-up #23 @@ -924,91 +963,6 @@ Minified build for production: - - -

    - - React v0.11.2 - -

    - -

    - September 16, 2014 - by - - - Paul O’Shannessy - - - -

    - -
    - -
    -

    Today we're releasing React v0.11.2 to add a few small features.

    - -

    We're adding support for two more DOM elements, <dialog> and <picture>, as well as the associated attributes needed to use these elements: open, media, and sizes. While not all browsers support these natively, some of our cutting edge users want to make use of them, so we're making them available to everybody.

    - -

    We're also doing some work to prepare for v0.12 and improve compatibility between the versions. To do this we are replacing React.createDescriptor with React.createElement. createDescriptor will continue to work with a warning and will be gone in v0.12. Chances are that this won't affect anybody.

    - -

    And lastly, on the heels of announcing Flow at @Scale yesterday, we're adding the ability to strip TypeScript-like type annotations as part of the jsx transform. To use, simply use the --strip-types flag on the command line, or set stripTypes in the options object when calling the API. We'll be talking about Flow more in the coming months. But for now, it's helpful to know that it is a flow-sensitive JavaScript type checker we will be open sourcing soon.

    - -

    The release is available for download from the CDN:

    - - - -

    We've also published version 0.11.2 of the react and react-tools packages on npm and the react package on bower.

    - -

    Please try these builds out and file an issue on GitHub if you see anything awry.

    - -

    React Core

    - -

    New Features

    - -
      -
    • Added support for <dialog> element and associated open attribute
    • -
    • Added support for <picture> element and associated media and sizes attributes
    • -
    • Added React.createElement API in preparation for React v0.12 - -
        -
      • React.createDescriptor has been deprecated as a result
      • -
    • -
    - -

    JSX

    - -
      -
    • <picture> is now parsed into React.DOM.picture
    • -
    - -

    React Tools

    - -
      -
    • Update esprima and jstransform for correctness fixes
    • -
    • The jsx executable now exposes a --strip-types flag which can be used to remove TypeScript-like type annotations - -
        -
      • This option is also exposed to require('react-tools').transform as stripTypes
      • -
    • -
    - -
    - - -

    diff --git a/blog/page13/index.html b/blog/page13/index.html index d308ce7ad8..d3cea9d808 100644 --- a/blog/page13/index.html +++ b/blog/page13/index.html @@ -63,7 +63,7 @@ @@ -76,6 +76,8 @@

    Recent posts

    @@ -106,6 +106,91 @@
    +

    + + React v0.11.2 + +

    + +

    + September 16, 2014 + by + + + Paul O’Shannessy + + + +

    + +
    + +
    +

    Today we're releasing React v0.11.2 to add a few small features.

    + +

    We're adding support for two more DOM elements, <dialog> and <picture>, as well as the associated attributes needed to use these elements: open, media, and sizes. While not all browsers support these natively, some of our cutting edge users want to make use of them, so we're making them available to everybody.

    + +

    We're also doing some work to prepare for v0.12 and improve compatibility between the versions. To do this we are replacing React.createDescriptor with React.createElement. createDescriptor will continue to work with a warning and will be gone in v0.12. Chances are that this won't affect anybody.

    + +

    And lastly, on the heels of announcing Flow at @Scale yesterday, we're adding the ability to strip TypeScript-like type annotations as part of the jsx transform. To use, simply use the --strip-types flag on the command line, or set stripTypes in the options object when calling the API. We'll be talking about Flow more in the coming months. But for now, it's helpful to know that it is a flow-sensitive JavaScript type checker we will be open sourcing soon.

    + +

    The release is available for download from the CDN:

    + + + +

    We've also published version 0.11.2 of the react and react-tools packages on npm and the react package on bower.

    + +

    Please try these builds out and file an issue on GitHub if you see anything awry.

    + +

    React Core

    + +

    New Features

    + + + +

    JSX

    + + + +

    React Tools

    + + + +
    + + + +
    + +
    + +

    Community Round-up #22 @@ -457,134 +542,6 @@ This is not the intended way to use React but can be useful as last resort if yo -

    - -
    - - -

    - - Community Round-up #20 - -

    - -

    - July 28, 2014 - by - - - Lou Husson - - - -

    - -
    - -
    -

    It's an exciting time for React as there are now more commits from open source contributors than from Facebook engineers! Keep up the good work :)

    - -

    Atom moves to React

    - -

    Atom, GitHub's code editor, is now using React to build the editing experience. They made the move in order to improve performance. By default, React helped them eliminate unnecessary reflows, enabling them to focus on architecting the rendering pipeline in order to minimize repaints by using hardware acceleration. This is a testament to the fact that React's architecture is perfect for high performant applications.

    - -

    - -

    Why Does React Scale?

    - -

    At the last JSConf.us, Vjeux talked about the design decisions made in the API that allows it to scale to a large number of developers. If you don't have 20 minutes, take a look at the annotated slides.

    - - - -

    Live Editing

    - -

    One of the best features of React is that it provides the foundations to implement concepts that were otherwise extremely difficult, like server-side rendering, undo-redo, rendering to non-DOM environments like canvas... Dan Abramov got hot code reloading working with webpack in order to live edit a React project!

    - - - -

    ReactIntl Mixin by Yahoo

    - -

    There are a couple of React-related projects that recently appeared on Yahoo's GitHub, the first one being an internationalization mixin. It's great to see them getting excited about React and contributing back to the community.

    -
    var MyComponent = React.createClass({
    -  mixins: [ReactIntlMixin],
    -  render: function() {
    -    return (
    -      <div>
    -        <p>{this.intlDate(1390518044403, { hour: 'numeric', minute: 'numeric' })}</p>
    -        <p>{this.intlNumber(400, { style: 'percent' })}</p>
    -      </div>
    -    );
    -  }
    -});
    -
    -React.renderComponent(
    -  <MyComponent locales={['fr-FR']} />,
    -  document.getElementById('example')
    -);
    -
    -

    Thinking and Learning React

    - -

    Josephine Hall, working at Icelab, used React to write a mobile-focused application. She wrote a blog post “Thinking and Learning React.js” to share her experience with elements they had to use. You'll learn about routing, event dispatch, touchable components, and basic animations.

    - -

    London React Meetup

    - -

    If you missed the last London React Meetup, the video is available, with lots of great content.

    - - - - - -

    In related news, the next React SF Meetup will be from Prezi: “Immediate Mode on the Web: How We Implemented the Prezi Viewer in JavaScript”. While not in React, their tech is really awesome and shares a lot of React's design principles and perf optimizations.

    - -

    Using React and KendoUI Together

    - -

    One of the strengths of React is that it plays nicely with other libraries. Jim Cowart proved it by writing a tutorial that explains how to write React component adapters for KendoUI.

    - -
    - -

    Acorn JSX

    - -

    Ingvar Stepanyan extended the Acorn JavaScript parser to support JSX. The result is a JSX parser that's 1.5–2.0x faster than the official JSX implementation. It is an experiment and is not meant to be used for serious things, but it's always a good thing to get competition on performance!

    - -

    ReactScriptLoader

    - -

    Yariv Sadan created ReactScriptLoader to make it easier to write components that require an external script.

    -
    var Foo = React.createClass({
    -  mixins: [ReactScriptLoaderMixin],
    -  getScriptURL: function() {
    -    return 'http://d3js.org/d3.v3.min.js';
    -  },
    -  getInitialState: function() {
    -    return { scriptLoading: true, scriptLoadError: false };
    -  },
    -  onScriptLoaded: function() {
    -    this.setState({scriptLoading: false});
    -  },
    -  onScriptError: function() {
    -    this.setState({scriptLoading: false, scriptLoadError: true});
    -  },
    -  render: function() {
    -    var message =
    -      this.state.scriptLoading ? 'Loading script...' :
    -      this.state.scriptLoadError ? 'Loading failed' :
    -      'Loading succeeded';
    -    return <span>{message}</span>;
    -  }
    -});
    -
    -

    Random Tweet

    - - - -
    - - -
    diff --git a/blog/page14/index.html b/blog/page14/index.html index b39ae1dfe7..9503635bd3 100644 --- a/blog/page14/index.html +++ b/blog/page14/index.html @@ -63,7 +63,7 @@ @@ -76,6 +76,8 @@

    Recent posts

    @@ -106,6 +106,134 @@
    +

    + + Community Round-up #20 + +

    + +

    + July 28, 2014 + by + + + Lou Husson + + + +

    + +
    + +
    +

    It's an exciting time for React as there are now more commits from open source contributors than from Facebook engineers! Keep up the good work :)

    + +

    Atom moves to React

    + +

    Atom, GitHub's code editor, is now using React to build the editing experience. They made the move in order to improve performance. By default, React helped them eliminate unnecessary reflows, enabling them to focus on architecting the rendering pipeline in order to minimize repaints by using hardware acceleration. This is a testament to the fact that React's architecture is perfect for high performant applications.

    + +

    + +

    Why Does React Scale?

    + +

    At the last JSConf.us, Vjeux talked about the design decisions made in the API that allows it to scale to a large number of developers. If you don't have 20 minutes, take a look at the annotated slides.

    + + + +

    Live Editing

    + +

    One of the best features of React is that it provides the foundations to implement concepts that were otherwise extremely difficult, like server-side rendering, undo-redo, rendering to non-DOM environments like canvas... Dan Abramov got hot code reloading working with webpack in order to live edit a React project!

    + + + +

    ReactIntl Mixin by Yahoo

    + +

    There are a couple of React-related projects that recently appeared on Yahoo's GitHub, the first one being an internationalization mixin. It's great to see them getting excited about React and contributing back to the community.

    +
    var MyComponent = React.createClass({
    +  mixins: [ReactIntlMixin],
    +  render: function() {
    +    return (
    +      <div>
    +        <p>{this.intlDate(1390518044403, { hour: 'numeric', minute: 'numeric' })}</p>
    +        <p>{this.intlNumber(400, { style: 'percent' })}</p>
    +      </div>
    +    );
    +  }
    +});
    +
    +React.renderComponent(
    +  <MyComponent locales={['fr-FR']} />,
    +  document.getElementById('example')
    +);
    +
    +

    Thinking and Learning React

    + +

    Josephine Hall, working at Icelab, used React to write a mobile-focused application. She wrote a blog post “Thinking and Learning React.js” to share her experience with elements they had to use. You'll learn about routing, event dispatch, touchable components, and basic animations.

    + +

    London React Meetup

    + +

    If you missed the last London React Meetup, the video is available, with lots of great content.

    + + + + + +

    In related news, the next React SF Meetup will be from Prezi: “Immediate Mode on the Web: How We Implemented the Prezi Viewer in JavaScript”. While not in React, their tech is really awesome and shares a lot of React's design principles and perf optimizations.

    + +

    Using React and KendoUI Together

    + +

    One of the strengths of React is that it plays nicely with other libraries. Jim Cowart proved it by writing a tutorial that explains how to write React component adapters for KendoUI.

    + +
    + +

    Acorn JSX

    + +

    Ingvar Stepanyan extended the Acorn JavaScript parser to support JSX. The result is a JSX parser that's 1.5–2.0x faster than the official JSX implementation. It is an experiment and is not meant to be used for serious things, but it's always a good thing to get competition on performance!

    + +

    ReactScriptLoader

    + +

    Yariv Sadan created ReactScriptLoader to make it easier to write components that require an external script.

    +
    var Foo = React.createClass({
    +  mixins: [ReactScriptLoaderMixin],
    +  getScriptURL: function() {
    +    return 'http://d3js.org/d3.v3.min.js';
    +  },
    +  getInitialState: function() {
    +    return { scriptLoading: true, scriptLoadError: false };
    +  },
    +  onScriptLoaded: function() {
    +    this.setState({scriptLoading: false});
    +  },
    +  onScriptError: function() {
    +    this.setState({scriptLoading: false, scriptLoadError: true});
    +  },
    +  render: function() {
    +    var message =
    +      this.state.scriptLoading ? 'Loading script...' :
    +      this.state.scriptLoadError ? 'Loading failed' :
    +      'Loading succeeded';
    +    return <span>{message}</span>;
    +  }
    +});
    +
    +

    Random Tweet

    + + + +
    + + + +
    + +
    + +

    React v0.11.1 @@ -649,45 +777,6 @@ Minified build for production: - - -

    - - One Year of Open-Source React - -

    - -

    - May 29, 2014 - by - - - Cheng Lou - - - -

    - -
    - -
    -

    Today marks the one-year open-source anniversary of React.

    - -

    It’s been a crazy ride. 2.3k commits and 1.5k issues and pull requests later, we’re approaching version 1.0 and nearing 7k Github stars, with big names such as Khan Academy, New York Times, and Airbnb (and naturally, Facebook and Instagram) using React in production, and many more developers blogging their success stories with it. The roadmap gives a glimpse into the future of the library; exciting stuff lies ahead!

    - -

    Every success has its story. React was born out of our frustration at existing solutions for building UIs. When it was first suggested at Facebook, few people thought that functionally re-rendering everything and diffing the results could ever perform well. However, support grew after we built the first implementation and people wrote their first components. When we open-sourced React, the initial reception was similarly skeptical. It challenges many pre-established conventions and received mostly disapproving first-impressions, intermingled with positive ones that often were votes of confidence in Facebook’s engineering capabilities. On an open, competitive platform such as the web, it's been hard to convince people to try React. JSX, in particular, filtered out a huge chunk of potential early adopters.

    - -

    Fast forward one year, React has strongly grown in popularity. Special acknowledgments go to Khan Academy, the ClojureScript community, and established frameworks such as Ember and Angular for contributing to and debating on our work. We'd also like to thank all the individual contributors who have taken the time to help out over the past year. React, as a library and as a new paradigm on the web, wouldn't have gained as much traction without them. In the future, we will continue to try to set an example of what's possible to achieve when we rethink about current “best practices”.

    - -

    Here’s to another year!

    - -
    - - -

    diff --git a/blog/page15/index.html b/blog/page15/index.html index 3a2c59dd83..0a29852c69 100644 --- a/blog/page15/index.html +++ b/blog/page15/index.html @@ -63,7 +63,7 @@ @@ -76,6 +76,8 @@

    Recent posts

    @@ -106,6 +106,45 @@
    +

    + + One Year of Open-Source React + +

    + +

    + May 29, 2014 + by + + + Cheng Lou + + + +

    + +
    + +
    +

    Today marks the one-year open-source anniversary of React.

    + +

    It’s been a crazy ride. 2.3k commits and 1.5k issues and pull requests later, we’re approaching version 1.0 and nearing 7k Github stars, with big names such as Khan Academy, New York Times, and Airbnb (and naturally, Facebook and Instagram) using React in production, and many more developers blogging their success stories with it. The roadmap gives a glimpse into the future of the library; exciting stuff lies ahead!

    + +

    Every success has its story. React was born out of our frustration at existing solutions for building UIs. When it was first suggested at Facebook, few people thought that functionally re-rendering everything and diffing the results could ever perform well. However, support grew after we built the first implementation and people wrote their first components. When we open-sourced React, the initial reception was similarly skeptical. It challenges many pre-established conventions and received mostly disapproving first-impressions, intermingled with positive ones that often were votes of confidence in Facebook’s engineering capabilities. On an open, competitive platform such as the web, it's been hard to convince people to try React. JSX, in particular, filtered out a huge chunk of potential early adopters.

    + +

    Fast forward one year, React has strongly grown in popularity. Special acknowledgments go to Khan Academy, the ClojureScript community, and established frameworks such as Ember and Angular for contributing to and debating on our work. We'd also like to thank all the individual contributors who have taken the time to help out over the past year. React, as a library and as a new paradigm on the web, wouldn't have gained as much traction without them. In the future, we will continue to try to set an example of what's possible to achieve when we rethink about current “best practices”.

    + +

    Here’s to another year!

    + +
    + + + +
    + +
    + +

    Flux: An Application Architecture for React @@ -394,115 +433,6 @@ Minified build for production: - - -

    - - React v0.10 RC - -

    - -

    - March 19, 2014 - by - - - Paul O’Shannessy - - - -

    - -
    - -
    -

    v0.9 has only been out for a month, but we’re getting ready to push out v0.10 already. Unlike v0.9 which took a long time, we don't have a long list of changes to talk about.

    - -

    The release candidate is available for download from the CDN:

    - - - -

    We've also published version 0.10.0-rc1 of the react and react-tools packages on npm and the react package on bower.

    - -

    Please try these builds out and file an issue on GitHub if you see anything awry.

    - -

    Clone On Mount

    - -

    The main purpose of this release is to provide a smooth upgrade path as we evolve some of the implementation of core. In v0.9 we started warning in cases where you called methods on unmounted components. This is part of an effort to enforce the idea that the return value of a component (React.DOM.div(), MyComponent()) is in fact not a reference to the component instance React uses in the virtual DOM. The return value is instead a light-weight object that React knows how to use. Since the return value currently is a reference to the same object React uses internally, we need to make this transition in stages as many people have come to depend on this implementation detail.

    - -

    In 0.10, we’re adding more warnings to catch a similar set of patterns. When a component is mounted we clone it and use that object for our internal representation. This allows us to capture calls you think you’re making to a mounted component. We’ll forward them on to the right object, but also warn you that this is breaking. See “Access to the Mounted Instance” on this page. Most of the time you can solve your pattern by using refs.

    - -

    Storing a reference to your top level component is a pattern touched upon on that page, but another examples that demonstrates what we see a lot of:

    -
    // This is a common pattern. However instance here really refers to a
    -// "descriptor", not necessarily the mounted instance.
    -var instance = <MyComponent/>;
    -React.renderComponent(instance);
    -// ...
    -instance.setProps(...);
    -
    -// The change here is very simple. The return value of renderComponent will be
    -// the mounted instance.
    -var instance = React.renderComponent(<MyComponent/>)
    -// ...
    -instance.setProps(...);
    -
    -

    These warnings and method forwarding are only enabled in the development build. The production builds continue to work as they did in v0.9. We strongly encourage you to use the development builds to catch these warnings and fix the call sites.

    - -

    The plan for v0.11 is that we will go fully to "descriptors". Method calls on the return value of MyComponent() will fail hard.

    - -

    Changelog

    - -

    React Core

    - -

    New Features

    - -
      -
    • Added warnings to help migrate towards descriptors
    • -
    • Made it possible to server render without React-related markup (data-reactid, data-react-checksum). This DOM will not be mountable by React. Read the docs for React.renderComponentToStaticMarkup
    • -
    • Added support for more attributes: - -
        -
      • srcSet for <img> to specify images at different pixel ratios
      • -
      • textAnchor for SVG
      • -
    • -
    - -

    Bug Fixes

    - -
      -
    • Ensure all void elements don’t insert a closing tag into the markup.
    • -
    • Ensure className={false} behaves consistently
    • -
    • Ensure this.refs is defined, even if no refs are specified.
    • -
    - -

    Addons

    - - - -

    react-tools

    - -
      -
    • Added an option argument to transform function. The only option supported is harmony, which behaves the same as jsx --harmony on the command line. This uses the ES6 transforms from jstransform.
    • -
    - -
    - - -

    diff --git a/blog/page16/index.html b/blog/page16/index.html index 3e5b2cbcfe..15e4275b49 100644 --- a/blog/page16/index.html +++ b/blog/page16/index.html @@ -63,7 +63,7 @@ @@ -76,6 +76,8 @@

    Recent posts

    @@ -106,6 +106,115 @@
    +

    + + React v0.10 RC + +

    + +

    + March 19, 2014 + by + + + Paul O’Shannessy + + + +

    + +
    + +
    +

    v0.9 has only been out for a month, but we’re getting ready to push out v0.10 already. Unlike v0.9 which took a long time, we don't have a long list of changes to talk about.

    + +

    The release candidate is available for download from the CDN:

    + + + +

    We've also published version 0.10.0-rc1 of the react and react-tools packages on npm and the react package on bower.

    + +

    Please try these builds out and file an issue on GitHub if you see anything awry.

    + +

    Clone On Mount

    + +

    The main purpose of this release is to provide a smooth upgrade path as we evolve some of the implementation of core. In v0.9 we started warning in cases where you called methods on unmounted components. This is part of an effort to enforce the idea that the return value of a component (React.DOM.div(), MyComponent()) is in fact not a reference to the component instance React uses in the virtual DOM. The return value is instead a light-weight object that React knows how to use. Since the return value currently is a reference to the same object React uses internally, we need to make this transition in stages as many people have come to depend on this implementation detail.

    + +

    In 0.10, we’re adding more warnings to catch a similar set of patterns. When a component is mounted we clone it and use that object for our internal representation. This allows us to capture calls you think you’re making to a mounted component. We’ll forward them on to the right object, but also warn you that this is breaking. See “Access to the Mounted Instance” on this page. Most of the time you can solve your pattern by using refs.

    + +

    Storing a reference to your top level component is a pattern touched upon on that page, but another examples that demonstrates what we see a lot of:

    +
    // This is a common pattern. However instance here really refers to a
    +// "descriptor", not necessarily the mounted instance.
    +var instance = <MyComponent/>;
    +React.renderComponent(instance);
    +// ...
    +instance.setProps(...);
    +
    +// The change here is very simple. The return value of renderComponent will be
    +// the mounted instance.
    +var instance = React.renderComponent(<MyComponent/>)
    +// ...
    +instance.setProps(...);
    +
    +

    These warnings and method forwarding are only enabled in the development build. The production builds continue to work as they did in v0.9. We strongly encourage you to use the development builds to catch these warnings and fix the call sites.

    + +

    The plan for v0.11 is that we will go fully to "descriptors". Method calls on the return value of MyComponent() will fail hard.

    + +

    Changelog

    + +

    React Core

    + +

    New Features

    + + + +

    Bug Fixes

    + + + +

    Addons

    + + + +

    react-tools

    + + + +
    + + + +
    + +
    + +

    Community Round-up #18 @@ -688,114 +797,6 @@ Minified build for production: - - -

    - - Community Round-up #16 - -

    - -

    - February 15, 2014 - by - - - Jonas Gebhardt - - - -

    - -
    - -
    -

    There have been many posts recently covering the why and how of React. This week's community round-up includes a collection of recent articles to help you get started with React, along with a few posts that explain some of the inner workings.

    - -

    React in a nutshell

    - -

    Got five minutes to pitch React to your coworkers? John Lynch (@johnrlynch) put together this excellent and refreshing slideshow:

    - - - -

    React's diff algorithm

    - -

    React core team member Christopher Chedeau (@vjeux) explores the innards of React's tree diffing algorithm in this extensive and well-illustrated post.

    - -

    While we're talking about tree diffing: Matt Esch (@MatthewEsch) created this project, which aims to implement the virtual DOM and a corresponding diff algorithm as separate modules.

    - -

    Many, many new introductions to React!

    - -

    James Padosley wrote a short post on the basics (and merits) of React: What is React?

    - -
    -

    What I like most about React is that it doesn't impose heady design patterns and data-modelling abstractions on me. [...] Its opinions are so minimal and its abstractions so focused on the problem of the DOM, that you can merrily slap your design choices atop.

    - -

    Read the full post...

    -
    - -

    Taylor Lapeyre (@taylorlapeyre) wrote another nice introduction to React.

    - -
    -

    React expects you to do the work of getting and pushing data from the server. This makes it very easy to implement React as a front end solution, since it simply expects you to hand it data. React does all the other work.

    - -

    Read the full post...

    -
    - -

    This "Deep explanation for newbies" by @ProJavaScript explains how to get started building a React game without using the optional JSX syntax.

    - -

    React around the world

    - -

    It's great to see the React community expand internationally. This site features a React introduction in Russian.

    - -

    React tutorial series

    - -

    Christopher Pitt explains React Components and React Properties. The former includes a nice introduction to using JSX, while the latter focuses on adding interactivity and linking multiple components together. Also check out the other posts in his React Tutorial series, e.g. on using React + Backbone Model and React + Backbone Router.

    - -

    Beginner tutorial: Implementing the board game Go

    - -

    Chris LaRose walks through the steps of creating a Go app in React, showing how to separate application logic from the rendered components. Check out his tutorial or go straight to the code.

    - -

    Egghead.io video tutorials

    - -

    Joe Maddalone (@joemaddalone) of egghead.io created a series of React video tutorials, such as this introduction to React Components. [part 1], [part 2]

    - -

    "React: Finally, a great server/client web stack"

    - -

    Eric Florenzano (@ericflo) sheds some light on what makes React perfect for server rendering:

    - -
    -

    [...] the ideal solution would fully render the markup on the server, deliver it to the client so that it can be shown to the user instantly. Then it would asynchronously load some Javascript that would attach to the rendered markup, and invisibly promote the page into a full app that can render its own markup. [...]

    - -

    What I've discovered is that enough of the pieces have come together, that this futuristic-sounding web environment is actually surprisingly easy to do now with React.js.

    - -

    Read the full post...

    -
    - -

    Building a complex React component

    - -

    Matt Harrison walks through the process of creating an SVG-based Resistance Calculator using React.

    - -

    Random Tweets

    - -
    - -
    - -
    - -
    - -
    - -
    - - -

    diff --git a/blog/page17/index.html b/blog/page17/index.html index 248868e453..f04ae185f2 100644 --- a/blog/page17/index.html +++ b/blog/page17/index.html @@ -63,7 +63,7 @@ @@ -76,6 +76,8 @@

    Recent posts

    @@ -106,6 +106,114 @@
    +

    + + Community Round-up #16 + +

    + +

    + February 15, 2014 + by + + + Jonas Gebhardt + + + +

    + +
    + +
    +

    There have been many posts recently covering the why and how of React. This week's community round-up includes a collection of recent articles to help you get started with React, along with a few posts that explain some of the inner workings.

    + +

    React in a nutshell

    + +

    Got five minutes to pitch React to your coworkers? John Lynch (@johnrlynch) put together this excellent and refreshing slideshow:

    + + + +

    React's diff algorithm

    + +

    React core team member Christopher Chedeau (@vjeux) explores the innards of React's tree diffing algorithm in this extensive and well-illustrated post.

    + +

    While we're talking about tree diffing: Matt Esch (@MatthewEsch) created this project, which aims to implement the virtual DOM and a corresponding diff algorithm as separate modules.

    + +

    Many, many new introductions to React!

    + +

    James Padosley wrote a short post on the basics (and merits) of React: What is React?

    + +
    +

    What I like most about React is that it doesn't impose heady design patterns and data-modelling abstractions on me. [...] Its opinions are so minimal and its abstractions so focused on the problem of the DOM, that you can merrily slap your design choices atop.

    + +

    Read the full post...

    +
    + +

    Taylor Lapeyre (@taylorlapeyre) wrote another nice introduction to React.

    + +
    +

    React expects you to do the work of getting and pushing data from the server. This makes it very easy to implement React as a front end solution, since it simply expects you to hand it data. React does all the other work.

    + +

    Read the full post...

    +
    + +

    This "Deep explanation for newbies" by @ProJavaScript explains how to get started building a React game without using the optional JSX syntax.

    + +

    React around the world

    + +

    It's great to see the React community expand internationally. This site features a React introduction in Russian.

    + +

    React tutorial series

    + +

    Christopher Pitt explains React Components and React Properties. The former includes a nice introduction to using JSX, while the latter focuses on adding interactivity and linking multiple components together. Also check out the other posts in his React Tutorial series, e.g. on using React + Backbone Model and React + Backbone Router.

    + +

    Beginner tutorial: Implementing the board game Go

    + +

    Chris LaRose walks through the steps of creating a Go app in React, showing how to separate application logic from the rendered components. Check out his tutorial or go straight to the code.

    + +

    Egghead.io video tutorials

    + +

    Joe Maddalone (@joemaddalone) of egghead.io created a series of React video tutorials, such as this introduction to React Components. [part 1], [part 2]

    + +

    "React: Finally, a great server/client web stack"

    + +

    Eric Florenzano (@ericflo) sheds some light on what makes React perfect for server rendering:

    + +
    +

    [...] the ideal solution would fully render the markup on the server, deliver it to the client so that it can be shown to the user instantly. Then it would asynchronously load some Javascript that would attach to the rendered markup, and invisibly promote the page into a full app that can render its own markup. [...]

    + +

    What I've discovered is that enough of the pieces have come together, that this futuristic-sounding web environment is actually surprisingly easy to do now with React.js.

    + +

    Read the full post...

    +
    + +

    Building a complex React component

    + +

    Matt Harrison walks through the process of creating an SVG-based Resistance Calculator using React.

    + +

    Random Tweets

    + +
    + +
    + +
    + +
    + +
    + +
    + + + +
    + +
    + +

    Community Round-up #15 @@ -543,125 +651,6 @@ rails s -

    - -
    - - -

    - - Community Round-up #12 - -

    - -

    - December 23, 2013 - by - - - Vjeux - - - -

    - -
    - -
    -

    React got featured on the front-page of Hacker News thanks to the Om library. If you try it out for the first time, take a look at the docs and do not hesitate to ask questions on the Google Group, IRC or Stack Overflow. We are trying our best to help you out!

    - -

    The Future of Javascript MVC

    - -

    David Nolen announced Om, a thin wrapper on-top of React in ClojureScript. It stands out by only using immutable data structures. This unlocks the ability to write a very efficient shouldComponentUpdate and get huge performance improvements on some tasks.

    - -
    -

    We've known this for some time over here in the ClojureScript corner of the world - all of our collections are immutable and modeled directly on the original Clojure versions written in Java. Modern JavaScript engines have now been tuned to the point that it's no longer uncommon to see collection performance within 2.5X of the Java Virtual Machine.

    - -

    Wait, wait, wait. What does the performance of persistent data structures have to do with the future of JavaScript MVCs?

    - -

    A whole lot. -

    - -

    Read the full article...

    -
    - -

    Scroll Position with React

    - -

    Managing the scroll position when new content is inserted is usually very tricky to get right. Vjeux discovered that componentWillUpdate and componentDidUpdate were triggered exactly at the right time to manage the scroll position.

    - -
    -

    We can check the scroll position before the component has updated with componentWillUpdate and scroll if necessary at componentDidUpdate

    -
    componentWillUpdate: function() {
    -  var node = this.getDOMNode();
    -  this.shouldScrollBottom =
    -    (node.scrollTop + node.offsetHeight) === node.scrollHeight;
    -},
    -componentDidUpdate: function() {
    -  if (this.shouldScrollBottom) {
    -    var node = this.getDOMNode();
    -    node.scrollTop = node.scrollHeight
    -  }
    -},
    -
    -

    Check out the blog article...

    -
    - -

    Lights Out

    - -

    React declarative approach is well suited to write games. Cheng Lou wrote the famous Lights Out game in React. It's a good example of use of TransitionGroup to implement animations. -

    - -

    Try it out!

    - -

    Reactive Table Bookmarklet

    - -

    Stoyan Stefanov wrote a bookmarklet to process tables on the internet. It adds a little "pop" button that expands to a full-screen view with sorting, editing and export to csv and json. -

    - -

    Check out the blog post...

    - -

    MontageJS Tutorial in React

    - -

    Ross Allen implemented MontageJS's Reddit tutorial in React. This is a good opportunity to compare the philosophies of the two libraries.

    - -

    View the source on JSFiddle...

    - -

    Writing Good React Components

    - -

    William Högman Rudenmalm wrote an article on how to write good React components. This is full of good advice.

    - -
    -

    The idea of dividing software into smaller parts or components is hardly new - It is the essance of good software. The same principles that apply to software in general apply to building React components. That doesn’t mean that writing good React components is just about applying general rules.

    - -

    The web offers a unique set of challenges, which React offers interesting solutions to. First and foremost among these solutions is the what is called the Mock DOM. Rather than having user code interface with the DOM in a direct fashion, as is the case with most DOM manipulation libraries.

    - -

    You build a model of how you want the DOM end up like. React then inserts this model into the DOM. This is very useful for updates because React simply compares the model or mock DOM against the actual DOM, and then only updates based on the difference between the two states.

    - -

    Read the full article ...

    -
    - -

    Hoodie React TodoMVC

    - -

    Sven Lito integrated the React TodoMVC example within an Hoodie web app environment. This should let you get started using Hoodie and React.

    -
    hoodie new todomvc -t "hoodiehq/hoodie-react-todomvc"
    -
    -

    Check out on GitHub...

    - -

    JSX Compiler

    - -

    Ever wanted to have a quick way to see what a JSX tag would be converted to? Tim Yung made a page for it. -

    - -

    Try it out!

    - -

    Random Tweet

    - -

    - -
    - - -
    diff --git a/blog/page18/index.html b/blog/page18/index.html index a98b1d431a..3b8406fbf2 100644 --- a/blog/page18/index.html +++ b/blog/page18/index.html @@ -63,7 +63,7 @@ @@ -76,6 +76,8 @@

    Recent posts

    @@ -106,6 +106,125 @@
    +

    + + Community Round-up #12 + +

    + +

    + December 23, 2013 + by + + + Vjeux + + + +

    + +
    + +
    +

    React got featured on the front-page of Hacker News thanks to the Om library. If you try it out for the first time, take a look at the docs and do not hesitate to ask questions on the Google Group, IRC or Stack Overflow. We are trying our best to help you out!

    + +

    The Future of Javascript MVC

    + +

    David Nolen announced Om, a thin wrapper on-top of React in ClojureScript. It stands out by only using immutable data structures. This unlocks the ability to write a very efficient shouldComponentUpdate and get huge performance improvements on some tasks.

    + +
    +

    We've known this for some time over here in the ClojureScript corner of the world - all of our collections are immutable and modeled directly on the original Clojure versions written in Java. Modern JavaScript engines have now been tuned to the point that it's no longer uncommon to see collection performance within 2.5X of the Java Virtual Machine.

    + +

    Wait, wait, wait. What does the performance of persistent data structures have to do with the future of JavaScript MVCs?

    + +

    A whole lot. +

    + +

    Read the full article...

    +
    + +

    Scroll Position with React

    + +

    Managing the scroll position when new content is inserted is usually very tricky to get right. Vjeux discovered that componentWillUpdate and componentDidUpdate were triggered exactly at the right time to manage the scroll position.

    + +
    +

    We can check the scroll position before the component has updated with componentWillUpdate and scroll if necessary at componentDidUpdate

    +
    componentWillUpdate: function() {
    +  var node = this.getDOMNode();
    +  this.shouldScrollBottom =
    +    (node.scrollTop + node.offsetHeight) === node.scrollHeight;
    +},
    +componentDidUpdate: function() {
    +  if (this.shouldScrollBottom) {
    +    var node = this.getDOMNode();
    +    node.scrollTop = node.scrollHeight
    +  }
    +},
    +
    +

    Check out the blog article...

    +
    + +

    Lights Out

    + +

    React declarative approach is well suited to write games. Cheng Lou wrote the famous Lights Out game in React. It's a good example of use of TransitionGroup to implement animations. +

    + +

    Try it out!

    + +

    Reactive Table Bookmarklet

    + +

    Stoyan Stefanov wrote a bookmarklet to process tables on the internet. It adds a little "pop" button that expands to a full-screen view with sorting, editing and export to csv and json. +

    + +

    Check out the blog post...

    + +

    MontageJS Tutorial in React

    + +

    Ross Allen implemented MontageJS's Reddit tutorial in React. This is a good opportunity to compare the philosophies of the two libraries.

    + +

    View the source on JSFiddle...

    + +

    Writing Good React Components

    + +

    William Högman Rudenmalm wrote an article on how to write good React components. This is full of good advice.

    + +
    +

    The idea of dividing software into smaller parts or components is hardly new - It is the essance of good software. The same principles that apply to software in general apply to building React components. That doesn’t mean that writing good React components is just about applying general rules.

    + +

    The web offers a unique set of challenges, which React offers interesting solutions to. First and foremost among these solutions is the what is called the Mock DOM. Rather than having user code interface with the DOM in a direct fashion, as is the case with most DOM manipulation libraries.

    + +

    You build a model of how you want the DOM end up like. React then inserts this model into the DOM. This is very useful for updates because React simply compares the model or mock DOM against the actual DOM, and then only updates based on the difference between the two states.

    + +

    Read the full article ...

    +
    + +

    Hoodie React TodoMVC

    + +

    Sven Lito integrated the React TodoMVC example within an Hoodie web app environment. This should let you get started using Hoodie and React.

    +
    hoodie new todomvc -t "hoodiehq/hoodie-react-todomvc"
    +
    +

    Check out on GitHub...

    + +

    JSX Compiler

    + +

    Ever wanted to have a quick way to see what a JSX tag would be converted to? Tim Yung made a page for it. +

    + +

    Try it out!

    + +

    Random Tweet

    + +

    + +
    + + + +
    + +
    + +

    React v0.8 @@ -494,54 +613,6 @@ Is this some sort of template language? Specifically no. This might have been th -

    - -
    - - -

    - - React v0.5.1 - -

    - -

    - October 29, 2013 - by - - - Paul O’Shannessy - - - -

    - -
    - -
    -

    This release focuses on fixing some small bugs that have been uncovered over the past two weeks. I would like to thank everybody involved, specifically members of the community who fixed half of the issues found. Thanks to Ben Alpert, Andrey Popp, and Laurence Rowe for their contributions!

    - -

    Changelog

    - -

    React

    - - - -

    React with Addons

    - - - -
    - - -
    diff --git a/blog/page19/index.html b/blog/page19/index.html index 03317053dd..f7df7c2208 100644 --- a/blog/page19/index.html +++ b/blog/page19/index.html @@ -63,7 +63,7 @@ @@ -76,6 +76,8 @@

    Recent posts

    @@ -106,6 +106,54 @@
    +

    + + React v0.5.1 + +

    + +

    + October 29, 2013 + by + + + Paul O’Shannessy + + + +

    + +
    + +
    +

    This release focuses on fixing some small bugs that have been uncovered over the past two weeks. I would like to thank everybody involved, specifically members of the community who fixed half of the issues found. Thanks to Ben Alpert, Andrey Popp, and Laurence Rowe for their contributions!

    + +

    Changelog

    + +

    React

    + + + +

    React with Addons

    + + + +
    + + + +
    + +
    + +

    React v0.5 @@ -505,75 +553,6 @@ -

    - -
    - - -

    - - Use React and JSX in Python Applications - -

    - -

    - August 19, 2013 - by - - - Kunal Mehta - - - -

    - -
    - -
    -

    Today we're happy to announce the initial release of PyReact, 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:

    -
    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:

    -
    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. Add it to your project's pipeline settings like this:

    -
    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 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.

    - -

    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!

    - -
    - - -
    diff --git a/blog/page2/index.html b/blog/page2/index.html index a2775fc212..9f216e29d4 100644 --- a/blog/page2/index.html +++ b/blog/page2/index.html @@ -63,7 +63,7 @@ @@ -76,6 +76,8 @@

    Recent posts

    @@ -106,6 +106,599 @@
    +

    + + Mixins Considered Harmful + +

    + +

    + July 13, 2016 + by + + + Dan Abramov + + + +

    + +
    + +
    +

    “How do I share the code between several components?” is one of the first questions that people ask when they learn React. Our answer has always been to use component composition for code reuse. You can define a component and use it in several other components.

    + +

    It is not always obvious how a certain pattern can be solved with composition. React is influenced by functional programming but it came into the field that was dominated by object-oriented libraries. It was hard for engineers both inside and outside of Facebook to give up on the patterns they were used to.

    + +

    To ease the initial adoption and learning, we included certain escape hatches into React. The mixin system was one of those escape hatches, and its goal was to give you a way to reuse code between components when you aren’t sure how to solve the same problem with composition.

    + +

    Three years passed since React was released. The landscape has changed. Multiple view libraries now adopt a component model similar to React. Using composition over inheritance to build declarative user interfaces is no longer a novelty. We are also more confident in the React component model, and we have seen many creative uses of it both internally and in the community.

    + +

    In this post, we will consider the problems commonly caused by mixins. Then we will suggest several alternative patterns for the same use cases. We have found those patterns to scale better with the complexity of the codebase than mixins.

    + +

    Why Mixins are Broken

    + +

    At Facebook, React usage has grown from a few components to thousands of them. This gives us a window into how people use React. Thanks to declarative rendering and top-down data flow, many teams were able to fix a bunch of bugs while shipping new features as they adopted React.

    + +

    However it’s inevitable that some of our code using React gradually became incomprehensible. Occasionally, the React team would see groups of components in different projects that people were afraid to touch. These components were too easy to break accidentally, were confusing to new developers, and eventually became just as confusing to the people who wrote them in the first place. Much of this confusion was caused by mixins. At the time, I wasn’t working at Facebook but I came to the same conclusions after writing my fair share of terrible mixins.

    + +

    This doesn’t mean that mixins themselves are bad. People successfully employ them in different languages and paradigms, including some functional languages. At Facebook, we extensively use traits in Hack which are fairly similar to mixins. Nevertheless, we think that mixins are unnecessary and problematic in React codebases. Here’s why.

    + +

    Mixins introduce implicit dependencies

    + +

    Sometimes a component relies on a certain method defined in the mixin, such as getClassName(). Sometimes it’s the other way around, and mixin calls a method like renderHeader() on the component. JavaScript is a dynamic language so it’s hard to enforce or document these dependencies.

    + +

    Mixins break the common and usually safe assumption that you can rename a state key or a method by searching for its occurrences in the component file. You might write a stateful component and then your coworker might add a mixin that reads this state. In a few months, you might want to move that state up to the parent component so it can be shared with a sibling. Will you remember to update the mixin to read a prop instead? What if, by now, other components also use this mixin?

    + +

    These implicit dependencies make it hard for new team members to contribute to a codebase. A component’s render() method might reference some method that isn’t defined on the class. Is it safe to remove? Perhaps it’s defined in one of the mixins. But which one of them? You need to scroll up to the mixin list, open each of those files, and look for this method. Worse, mixins can specify their own mixins, so the search can be deep.

    + +

    Often, mixins come to depend on other mixins, and removing one of them breaks the other. In these situations it is very tricky to tell how the data flows in and out of mixins, and what their dependency graph looks like. Unlike components, mixins don’t form a hierarchy: they are flattened and operate in the same namespace.

    + +

    Mixins cause name clashes

    + +

    There is no guarantee that two particular mixins can be used together. For example, if FluxListenerMixin defines handleChange() and WindowSizeMixin defines handleChange(), you can’t use them together. You also can’t define a method with this name on your own component.

    + +

    It’s not a big deal if you control the mixin code. When you have a conflict, you can rename that method on one of the mixins. However it’s tricky because some components or other mixins may already be calling this method directly, and you need to find and fix those calls as well.

    + +

    If you have a name conflict with a mixin from a third party package, you can’t just rename a method on it. Instead, you have to use awkward method names on your component to avoid clashes.

    + +

    The situation is no better for mixin authors. Even adding a new method to a mixin is always a potentially breaking change because a method with the same name might already exist on some of the components using it, either directly or through another mixin. Once written, mixins are hard to remove or change. Bad ideas don’t get refactored away because refactoring is too risky.

    + +

    Mixins cause snowballing complexity

    + +

    Even when mixins start out simple, they tend to become complex over time. The example below is based on a real scenario I’ve seen play out in a codebase.

    + +

    A component needs some state to track mouse hover. To keep this logic reusable, you might extract handleMouseEnter(), handleMouseLeave() and isHovering() into a HoverMixin. Next, somebody needs to implement a tooltip. They don’t want to duplicate the logic in HoverMixin so they create a TooltipMixin that uses HoverMixin. TooltipMixin reads isHovering() provided by HoverMixin in its componentDidUpdate() and either shows or hides the tooltip.

    + +

    A few months later, somebody wants to make the tooltip direction configurable. In an effort to avoid code duplication, they add support for a new optional method called getTooltipOptions() to TooltipMixin. By this time, components that show popovers also use HoverMixin. However popovers need a different hover delay. To solve this, somebody adds support for an optional getHoverOptions() method and implements it in TooltipMixin. Those mixins are now tightly coupled.

    + +

    This is fine while there are no new requirements. However this solution doesn’t scale well. What if you want to support displaying multiple tooltips in a single component? You can’t define the same mixin twice in a component. What if the tooltips need to be displayed automatically in a guided tour instead of on hover? Good luck decoupling TooltipMixin from HoverMixin. What if you need to support the case where the hover area and the tooltip anchor are located in different components? You can’t easily hoist the state used by mixin up into the parent component. Unlike components, mixins don’t lend themselves naturally to such changes.

    + +

    Every new requirement makes the mixins harder to understand. Components using the same mixin become increasingly coupled with time. Any new capability gets added to all of the components using that mixin. There is no way to split a “simpler” part of the mixin without either duplicating the code or introducing more dependencies and indirection between mixins. Gradually, the encapsulation boundaries erode, and since it’s hard to change or remove the existing mixins, they keep getting more abstract until nobody understands how they work.

    + +

    These are the same problems we faced building apps before React. We found that they are solved by declarative rendering, top-down data flow, and encapsulated components. At Facebook, we have been migrating our code to use alternative patterns to mixins, and we are generally happy with the results. You can read about those patterns below.

    + +

    Migrating from Mixins

    + +

    Let’s make it clear that mixins are not technically deprecated. If you use React.createClass(), you may keep using them. We only say that they didn’t work well for us, and so we won’t recommend using them in the future.

    + +

    Every section below corresponds to a mixin usage pattern that we found in the Facebook codebase. For each of them, we describe the problem and a solution that we think works better than mixins. The examples are written in ES5 but once you don’t need mixins, you can switch to ES6 classes if you’d like.

    + +

    We hope that you find this list helpful. Please let us know if we missed important use cases so we can either amend the list or be proven wrong!

    + +

    Performance Optimizations

    + +

    One of the most commonly used mixins is PureRenderMixin. You might be using it in some components to prevent unnecessary re-renders when the props and state are shallowly equal to the previous props and state:

    +
    var PureRenderMixin = require('react-addons-pure-render-mixin');
    +
    +var Button = React.createClass({
    +  mixins: [PureRenderMixin],
    +
    +  // ...
    +
    +});
    +
    +

    Solution

    + +

    To express the same without mixins, you can use the shallowCompare function directly instead:

    +
    var shallowCompare = require('react-addons-shallow-compare');
    +
    +var Button = React.createClass({
    +  shouldComponentUpdate: function(nextProps, nextState) {
    +    return shallowCompare(this, nextProps, nextState);
    +  },
    +
    +  // ...
    +
    +});
    +
    +

    If you use a custom mixin implementing a shouldComponentUpdate function with different algorithm, we suggest exporting just that single function from a module and calling it directly from your components.

    + +

    We understand that more typing can be annoying. For the most common case, we plan to introduce a new base class called React.PureComponent in the next minor release. It uses the same shallow comparison as PureRenderMixin does today.

    + +

    Subscriptions and Side Effects

    + +

    The second most common type of mixins that we encountered are mixins that subscribe a React component to a third-party data source. Whether this data source is a Flux Store, an Rx Observable, or something else, the pattern is very similar: the subscription is created in componentDidMount, destroyed in componentWillUnmount, and the change handler calls this.setState().

    +
    var SubscriptionMixin = {
    +  getInitialState: function() {
    +    return {
    +      comments: DataSource.getComments()
    +    };
    +  },
    +
    +  componentDidMount: function() {
    +    DataSource.addChangeListener(this.handleChange);
    +  },
    +
    +  componentWillUnmount: function() {
    +    DataSource.removeChangeListener(this.handleChange);
    +  },
    +
    +  handleChange: function() {
    +    this.setState({
    +      comments: DataSource.getComments()
    +    });
    +  }
    +};
    +
    +var CommentList = React.createClass({
    +  mixins: [SubscriptionMixin],
    +
    +  render: function() {
    +    // Reading comments from state managed by mixin.
    +    var comments = this.state.comments;
    +    return (
    +      <div>
    +        {comments.map(function(comment) {
    +          return <Comment comment={comment} key={comment.id} />
    +        })}
    +      </div>
    +    )
    +  }
    +});
    +
    +module.exports = CommentList;
    +
    +

    Solution

    + +

    If there is just one component subscribed to this data source, it is fine to embed the subscription logic right into the component. Avoid premature abstractions.

    + +

    If several components used this mixin to subscribe to a data source, a nice way to avoid repetition is to use a pattern called “higher-order components”. It can sound intimidating so we will take a closer look at how this pattern naturally emerges from the component model.

    + +

    Higher-Order Components Explained

    + +

    Let’s forget about React for a second. Consider these two functions that add and multiply numbers, logging the results as they do that:

    +
    function addAndLog(x, y) {
    +  var result = x + y;
    +  console.log('result:', result);
    +  return result;
    +}
    +
    +function multiplyAndLog(x, y) {
    +  var result = x * y;
    +  console.log('result:', result);
    +  return result;
    +}
    +
    +

    These two functions are not very useful but they help us demonstrate a pattern that we can later apply to components.

    + +

    Let’s say that we want to extract the logging logic out of these functions without changing their signatures. How can we do this? An elegant solution is to write a higher-order function, that is, a function that takes a function as an argument and returns a function.

    + +

    Again, it sounds more intimidating than it really is:

    +
    function withLogging(wrappedFunction) {
    +  // Return a function with the same API...
    +  return function(x, y) {
    +    // ... that calls the original function
    +    var result = wrappedFunction(x, y);
    +    // ... but also logs its result!
    +    console.log('result:', result);
    +    return result;
    +  };
    +}
    +
    +

    The withLogging higher-order function lets us write add and multiply without the logging statements, and later wrap them to get addAndLog and multiplyAndLog with exactly the same signatures as before:

    +
    function add(x, y) {
    +  return x + y;
    +}
    +
    +function multiply(x, y) {
    +  return x * y;
    +}
    +
    +function withLogging(wrappedFunction) {
    +  return function(x, y) {
    +    var result = wrappedFunction(x, y);
    +    console.log('result:', result);
    +    return result;
    +  };
    +}
    +
    +// Equivalent to writing addAndLog by hand:
    +var addAndLog = withLogging(add);
    +
    +// Equivalent to writing multiplyAndLog by hand:
    +var multiplyAndLog = withLogging(multiply);
    +
    +

    Higher-order components are a very similar pattern, but applied to components in React. We will apply this transformation from mixins in two steps.

    + +

    As a first step, we will split our CommentList component in two, a child and a parent. The child will be only concerned with rendering the comments. The parent will set up the subscription and pass the up-to-date data to the child via props.

    +
    // This is a child component.
    +// It only renders the comments it receives as props.
    +var CommentList = React.createClass({
    +  render: function() {
    +    // Note: now reading from props rather than state.
    +    var comments = this.props.comments;
    +    return (
    +      <div>
    +        {comments.map(function(comment) {
    +          return <Comment comment={comment} key={comment.id} />
    +        })}
    +      </div>
    +    )
    +  }
    +});
    +
    +// This is a parent component.
    +// It subscribes to the data source and renders <CommentList />.
    +var CommentListWithSubscription = React.createClass({
    +  getInitialState: function() {
    +    return {
    +      comments: DataSource.getComments()
    +    };
    +  },
    +
    +  componentDidMount: function() {
    +    DataSource.addChangeListener(this.handleChange);
    +  },
    +
    +  componentWillUnmount: function() {
    +    DataSource.removeChangeListener(this.handleChange);
    +  },
    +
    +  handleChange: function() {
    +    this.setState({
    +      comments: DataSource.getComments()
    +    });
    +  },
    +
    +  render: function() {
    +    // We pass the current state as props to CommentList.
    +    return <CommentList comments={this.state.comments} />;
    +  }
    +});
    +
    +module.exports = CommentListWithSubscription;
    +
    +

    There is just one final step left to do.

    + +

    Remember how we made withLogging() take a function and return another function wrapping it? We can apply a similar pattern to React components.

    + +

    We will write a new function called withSubscription(WrappedComponent). Its argument could be any React component. We will pass CommentList as WrappedComponent, but we could also apply withSubscription() to any other component in our codebase.

    + +

    This function would return another component. The returned component would manage the subscription and render <WrappedComponent /> with the current data.

    + +

    We call this pattern a “higher-order component”.

    + +

    The composition happens at React rendering level rather than with a direct function call. This is why it doesn’t matter whether the wrapped component is defined with createClass(), as an ES6 class or a function. If WrappedComponent is a React component, the component created by withSubscription() can render it.

    +
    // This function takes a component...
    +function withSubscription(WrappedComponent) {
    +  // ...and returns another component...
    +  return React.createClass({
    +    getInitialState: function() {
    +      return {
    +        comments: DataSource.getComments()
    +      };
    +    },
    +
    +    componentDidMount: function() {
    +      // ... that takes care of the subscription...
    +      DataSource.addChangeListener(this.handleChange);
    +    },
    +
    +    componentWillUnmount: function() {
    +      DataSource.removeChangeListener(this.handleChange);
    +    },
    +
    +    handleChange: function() {
    +      this.setState({
    +        comments: DataSource.getComments()
    +      });
    +    },
    +
    +    render: function() {
    +      // ... and renders the wrapped component with the fresh data!
    +      return <WrappedComponent comments={this.state.comments} />;
    +    }
    +  });
    +}
    +
    +

    Now we can declare CommentListWithSubscription by applying withSubscription to CommentList:

    +
    var CommentList = React.createClass({
    +  render: function() {
    +    var comments = this.props.comments;
    +    return (
    +      <div>
    +        {comments.map(function(comment) {
    +          return <Comment comment={comment} key={comment.id} />
    +        })}
    +      </div>
    +    )
    +  }
    +});
    +
    +// withSubscription() returns a new component that
    +// is subscribed to the data source and renders
    +// <CommentList /> with up-to-date data.
    +var CommentListWithSubscription = withSubscription(CommentList);
    +
    +// The rest of the app is interested in the subscribed component
    +// so we export it instead of the original unwrapped CommentList.
    +module.exports = CommentListWithSubscription;
    +
    +

    Solution, Revisited

    + +

    Now that we understand higher-order components better, let’s take another look at the complete solution that doesn’t involve mixins. There are a few minor changes that are annotated with inline comments:

    +
    function withSubscription(WrappedComponent) {
    +  return React.createClass({
    +    getInitialState: function() {
    +      return {
    +        comments: DataSource.getComments()
    +      };
    +    },
    +
    +    componentDidMount: function() {
    +      DataSource.addChangeListener(this.handleChange);
    +    },
    +
    +    componentWillUnmount: function() {
    +      DataSource.removeChangeListener(this.handleChange);
    +    },
    +
    +    handleChange: function() {
    +      this.setState({
    +        comments: DataSource.getComments()
    +      });
    +    },
    +
    +    render: function() {
    +      // Use JSX spread syntax to pass all props and state down automatically.
    +      return <WrappedComponent {...this.props} {...this.state} />;
    +    }
    +  });
    +}
    +
    +// Optional change: convert CommentList to a functional component
    +// because it doesn't use lifecycle hooks or state.
    +function CommentList(props) {
    +  var comments = props.comments;
    +  return (
    +    <div>
    +      {comments.map(function(comment) {
    +        return <Comment comment={comment} key={comment.id} />
    +      })}
    +    </div>
    +  )
    +}
    +
    +// Instead of declaring CommentListWithSubscription,
    +// we export the wrapped component right away.
    +module.exports = withSubscription(CommentList);
    +
    +

    Higher-order components are a powerful pattern. You can pass additional arguments to them if you want to further customize their behavior. After all, they are not even a feature of React. They are just functions that receive components and return components that wrap them.

    + +

    Like any solution, higher-order components have their own pitfalls. For example, if you heavily use refs, you might notice that wrapping something into a higher-order component changes the ref to point to the wrapping component. In practice we discourage using refs for component communication so we don’t think it’s a big issue. In the future, we might consider adding ref forwarding to React to solve this annoyance.

    + +

    Rendering Logic

    + +

    The next most common use case for mixins that we discovered in our codebase is sharing rendering logic between components.

    + +

    Here is a typical example of this pattern:

    +
    var RowMixin = {
    +  // Called by components from render()
    +  renderHeader: function() {
    +    return (
    +      <div className='row-header'>
    +        <h1>
    +          {this.getHeaderText() /* Defined by components */}
    +        </h1>
    +      </div>
    +    );
    +  }
    +};
    +
    +var UserRow = React.createClass({
    +  mixins: [RowMixin],
    +
    +  // Called by RowMixin.renderHeader()
    +  getHeaderText: function() {
    +    return this.props.user.fullName;
    +  },
    +
    +  render: function() {
    +    return (
    +      <div>
    +        {this.renderHeader() /* Defined by RowMixin */}
    +        <h2>{this.props.user.biography}</h2>
    +      </div>
    +    )
    +  }
    +});
    +
    +

    Multiple components may be sharing RowMixin to render the header, and each of them would need to define getHeaderText().

    + +

    Solution

    + +

    If you see rendering logic inside a mixin, it’s time to extract a component!

    + +

    Instead of RowMixin, we will define a <RowHeader> component. We will also replace the convention of defining a getHeaderText() method with the standard mechanism of top-data flow in React: passing props.

    + +

    Finally, since neither of those components currently need lifecycle hooks or state, we can declare them as simple functions:

    +
    function RowHeader(props) {
    +  return (
    +    <div className='row-header'>
    +      <h1>{props.text}</h1>
    +    </div>
    +  );
    +}
    +
    +function UserRow(props) {
    +  return (
    +    <div>
    +      <RowHeader text={props.user.fullName} />
    +      <h2>{props.user.biography}</h2>
    +    </div>
    +  );
    +}
    +
    +

    Props keep component dependencies explicit, easy to replace, and enforceable with tools like Flow and TypeScript.

    + +
    +

    Note:

    + +

    Defining components as functions is not required. There is also nothing wrong with using lifecycle hooks and state—they are first-class React features. We use functional components in this example because they are easier to read and we didn’t need those extra features, but classes would work just as fine.

    +
    + +

    Context

    + +

    Another group of mixins we discovered were helpers for providing and consuming React context. Context is an experimental unstable feature, has certain issues, and will likely change its API in the future. We don’t recommend using it unless you’re confident there is no other way of solving your problem.

    + +

    Nevertheless, if you already use context today, you might have been hiding its usage with mixins like this:

    +
    var RouterMixin = {
    +  contextTypes: {
    +    router: React.PropTypes.object.isRequired
    +  },
    +
    +  // The mixin provides a method so that components
    +  // don't have to use the context API directly.
    +  push: function(path) {
    +    this.context.router.push(path)
    +  }
    +};
    +
    +var Link = React.createClass({
    +  mixins: [RouterMixin],
    +
    +  handleClick: function(e) {
    +    e.stopPropagation();
    +
    +    // This method is defined in RouterMixin.
    +    this.push(this.props.to);
    +  },
    +
    +  render: function() {
    +    return (
    +      <a onClick={this.handleClick}>
    +        {this.props.children}
    +      </a>
    +    );
    +  }
    +});
    +
    +module.exports = Link;
    +
    +

    Solution

    + +

    We agree that hiding context usage from consuming components is a good idea until the context API stabilizes. However, we recommend using higher-order components instead of mixins for this.

    + +

    Let the wrapping component grab something from the context, and pass it down with props to the wrapped component:

    +
    function withRouter(WrappedComponent) {
    +  return React.createClass({
    +    contextTypes: {
    +      router: React.PropTypes.object.isRequired
    +    },
    +
    +    render: function() {
    +      // The wrapper component reads something from the context
    +      // and passes it down as a prop to the wrapped component.
    +      var router = this.context.router;
    +      return <WrappedComponent {...this.props} router={router} />;
    +    }
    +  });
    +};
    +
    +var Link = React.createClass({
    +  handleClick: function(e) {
    +    e.stopPropagation();
    +
    +    // The wrapped component uses props instead of context.
    +    this.props.router.push(this.props.to);
    +  },
    +
    +  render: function() {
    +    return (
    +      <a onClick={this.handleClick}>
    +        {this.props.children}
    +      </a>
    +    );
    +  }
    +});
    +
    +// Don't forget to wrap the component!
    +module.exports = withRouter(Link);
    +
    +

    If you’re using a third party library that only provides a mixin, we encourage you to file an issue with them linking to this post so that they can provide a higher-order component instead. In the meantime, you can create a higher-order component around it yourself in exactly the same way.

    + +

    Utility Methods

    + +

    Sometimes, mixins are used solely to share utility functions between components:

    +
    var ColorMixin = {
    +  getLuminance(color) {
    +    var c = parseInt(color, 16);
    +    var r = (c & 0xFF0000) >> 16;
    +    var g = (c & 0x00FF00) >> 8;
    +    var b = (c & 0x0000FF);
    +    return (0.299 * r + 0.587 * g + 0.114 * b);
    +  }
    +};
    +
    +var Button = React.createClass({
    +  mixins: [ColorMixin],
    +
    +  render: function() {
    +    var theme = this.getLuminance(this.props.color) > 160 ? 'dark' : 'light';
    +    return (
    +      <div className={theme}>
    +        {this.props.children}
    +      </div>
    +    )
    +  }
    +});
    +
    +

    Solution

    + +

    Put utility functions into regular JavaScript modules and import them. This also makes it easier to test them or use them outside of your components:

    +
    var getLuminance = require('../utils/getLuminance');
    +
    +var Button = React.createClass({
    +  render: function() {
    +    var theme = getLuminance(this.props.color) > 160 ? 'dark' : 'light';
    +    return (
    +      <div className={theme}>
    +        {this.props.children}
    +      </div>
    +    )
    +  }
    +});
    +
    +

    Other Use Cases

    + +

    Sometimes people use mixins to selectively add logging to lifecycle hooks in some components. In the future, we intend to provide an official DevTools API that would let you implement something similar without touching the components. However it’s still very much a work in progress. If you heavily depend on logging mixins for debugging, you might want to keep using those mixins for a little longer.

    + +

    If you can’t accomplish something with a component, a higher-order component, or a utility module, it could be mean that React should provide this out of the box. File an issue to tell us about your use case for mixins, and we’ll help you consider alternatives or perhaps implement your feature request.

    + +

    Mixins are not deprecated in the traditional sense. You can keep using them with React.createClass(), as we won’t be changing it further. Eventually, as ES6 classes gain more adoption and their usability problems in React are solved, we might split React.createClass() into a separate package because most people wouldn’t need it. Even in that case, your old mixins would keep working.

    + +

    We believe that the alternatives above are better for the vast majority of cases, and we invite you to try writing React apps without using mixins.

    + +
    + + + +
    + +
    + +

    Introducing React's Error Code System @@ -530,67 +1123,6 @@ Minified build for production: - - -

    - - React v15.0 Release Candidate 2 - -

    - -

    - March 16, 2016 - by - - - Paul O’Shannessy - - - -

    - -
    - -
    -

    Today we're releasing a second release candidate for version 15. Primarily this is to address 2 issues, but we also picked up a few small changes from new contributors, including some improvements to some of our new warnings.

    - -

    The most pressing change that was made is to fix a bug in our new code that removes <span>s, as discussed in the original RC1 post. Specifically we have some code that takes a different path in IE11 and Edge due to the speed of some DOM operations. There was a bug in this code which didn't break out of the optimization for DocumentFragments, resulting in text not appearing at all. Thanks to the several people who reported this.

    - -

    The other change is to our SVG code. In RC1 we had made the decision to pass through all attributes directly. This led to some confusion with class vs className and ultimately led us to reconsider our position on the approach. Passing through all attributes meant that we would have two different patterns for using React where things like hyphenated attributes would work for SVG but not HTML. In the future, we might change our approach to the problem for HTML as well but in the meantime, maintaining consistency is important. So we reverted the changes that allowed the attributes to be passed through and instead expanded the SVG property list to include all attributes that are in the spec. We believe we have everything now but definitely let us know if we missed anything. It was and still is our intent to support the full range of SVG tags and attributes in this release.

    - -

    Thanks again to everybody who has tried the RC1 and reported issues. It has been extremely important and we wouldn't be able to do this without your help!

    - -

    Installation

    - -

    We recommend using React from npm and using a tool like browserify or webpack to build your code into a single bundle. To install the two packages:

    - -
      -
    • npm install --save react@15.0.0-rc.2 react-dom@15.0.0-rc.2
    • -
    - -

    Remember that by default, React runs extra checks and provides helpful warnings in development mode. When deploying your app, set the NODE_ENV environment variable to production to use the production build of React which does not include the development warnings and runs significantly faster.

    - -

    If you can’t use npm yet, we provide pre-built browser builds for your convenience, which are also available in the react package on bower.

    - - - -
    - - -

    diff --git a/blog/page20/index.html b/blog/page20/index.html index 2ddef31284..231297715f 100644 --- a/blog/page20/index.html +++ b/blog/page20/index.html @@ -63,7 +63,7 @@ @@ -76,6 +76,8 @@

    Recent posts

    @@ -106,6 +106,75 @@
    +

    + + Use React and JSX in Python Applications + +

    + +

    + August 19, 2013 + by + + + Kunal Mehta + + + +

    + +
    + +
    +

    Today we're happy to announce the initial release of PyReact, 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:

    +
    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:

    +
    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. Add it to your project's pipeline settings like this:

    +
    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 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.

    + +

    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!

    + +
    + + + +
    + +
    + +

    Community Round-up #6 @@ -451,74 +520,6 @@ -

    - -
    - - -

    - - React v0.4.0 - -

    - -

    - July 17, 2013 - by - - - 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, 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

    - - - -

    JSX

    - - - -

    react-tools

    - - - -
    - - -
    diff --git a/blog/page21/index.html b/blog/page21/index.html index 23190eb8f2..d5ddb32b51 100644 --- a/blog/page21/index.html +++ b/blog/page21/index.html @@ -63,7 +63,7 @@ @@ -76,6 +76,8 @@

    Recent posts

    @@ -106,6 +106,74 @@
    +

    + + React v0.4.0 + +

    + +

    + July 17, 2013 + by + + + 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, 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

    + + + +

    JSX

    + + + +

    react-tools

    + + + +
    + + + +
    + +
    + +

    New in React v0.4: Prop Validation and Default Values @@ -456,57 +524,6 @@ -

    - -
    - - -

    - - React v0.3.3 - -

    - -

    - June 21, 2013 - by - - - 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

    - - - -

    React

    - - - -

    JSXTransformer

    - - - -
    - - -
    diff --git a/blog/page22/index.html b/blog/page22/index.html index 6834cdbf55..8bc64e9ba7 100644 --- a/blog/page22/index.html +++ b/blog/page22/index.html @@ -63,7 +63,7 @@ @@ -76,6 +76,8 @@

    Recent posts

    @@ -106,6 +106,57 @@
    +

    + + React v0.3.3 + +

    + +

    + June 21, 2013 + by + + + 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

    + + + +

    React

    + + + +

    JSXTransformer

    + + + +
    + + + +
    + +
    + +

    Community Round-up #2 diff --git a/blog/page3/index.html b/blog/page3/index.html index f817254025..8ddc145695 100644 --- a/blog/page3/index.html +++ b/blog/page3/index.html @@ -63,7 +63,7 @@

    @@ -76,6 +76,8 @@

    Recent posts

    @@ -106,6 +106,67 @@
    +

    + + React v15.0 Release Candidate 2 + +

    + +

    + March 16, 2016 + by + + + Paul O’Shannessy + + + +

    + +
    + +
    +

    Today we're releasing a second release candidate for version 15. Primarily this is to address 2 issues, but we also picked up a few small changes from new contributors, including some improvements to some of our new warnings.

    + +

    The most pressing change that was made is to fix a bug in our new code that removes <span>s, as discussed in the original RC1 post. Specifically we have some code that takes a different path in IE11 and Edge due to the speed of some DOM operations. There was a bug in this code which didn't break out of the optimization for DocumentFragments, resulting in text not appearing at all. Thanks to the several people who reported this.

    + +

    The other change is to our SVG code. In RC1 we had made the decision to pass through all attributes directly. This led to some confusion with class vs className and ultimately led us to reconsider our position on the approach. Passing through all attributes meant that we would have two different patterns for using React where things like hyphenated attributes would work for SVG but not HTML. In the future, we might change our approach to the problem for HTML as well but in the meantime, maintaining consistency is important. So we reverted the changes that allowed the attributes to be passed through and instead expanded the SVG property list to include all attributes that are in the spec. We believe we have everything now but definitely let us know if we missed anything. It was and still is our intent to support the full range of SVG tags and attributes in this release.

    + +

    Thanks again to everybody who has tried the RC1 and reported issues. It has been extremely important and we wouldn't be able to do this without your help!

    + +

    Installation

    + +

    We recommend using React from npm and using a tool like browserify or webpack to build your code into a single bundle. To install the two packages:

    + + + +

    Remember that by default, React runs extra checks and provides helpful warnings in development mode. When deploying your app, set the NODE_ENV environment variable to production to use the production build of React which does not include the development warnings and runs significantly faster.

    + +

    If you can’t use npm yet, we provide pre-built browser builds for your convenience, which are also available in the react package on bower.

    + + + +
    + + + +
    + +
    + +

    React v15.0 Release Candidate @@ -428,79 +489,6 @@ Minified build for production: - - -

    - - React v0.14.4 - -

    - -

    - December 29, 2015 - by - - - Ben Alpert - - - -

    - -
    - -
    -

    Happy December! We have a minor point release today. It has just a few small bug fixes.

    - -

    The release is now available for download:

    - - - -

    We've also published version 0.14.4 of the react, react-dom, and addons packages on npm and the react package on bower.

    - -
    - -

    Changelog

    - -

    React

    - -
      -
    • Minor internal changes for better compatibility with React Native
    • -
    - -

    React DOM

    - -
      -
    • The autoCapitalize and autoCorrect props are now set as attributes in the DOM instead of properties to improve cross-browser compatibility
    • -
    • Fixed bug with controlled <select> elements not handling updates properly
    • -
    - -

    React Perf Add-on

    - -
      -
    • Some DOM operation names have been updated for clarity in the output of .printDOM()
    • -
    - -
    - - -

    diff --git a/blog/page4/index.html b/blog/page4/index.html index cee29463c1..392d8119c3 100644 --- a/blog/page4/index.html +++ b/blog/page4/index.html @@ -63,7 +63,7 @@ @@ -76,6 +76,8 @@

    Recent posts

    @@ -106,6 +106,79 @@
    +

    + + React v0.14.4 + +

    + +

    + December 29, 2015 + by + + + Ben Alpert + + + +

    + +
    + +
    +

    Happy December! We have a minor point release today. It has just a few small bug fixes.

    + +

    The release is now available for download:

    + + + +

    We've also published version 0.14.4 of the react, react-dom, and addons packages on npm and the react package on bower.

    + +
    + +

    Changelog

    + +

    React

    + + + +

    React DOM

    + + + +

    React Perf Add-on

    + + + +
    + + + +
    + +
    + +

    React Components, Elements, and Instances @@ -731,67 +804,6 @@ Minified build for production: - - -

    - - React v0.14.2 - -

    - -

    - November 2, 2015 - by - - - Paul O’Shannessy - - - -

    - -
    - -
    -

    We have a quick update following the release of 0.14.1 last week. It turns out we broke a couple things in the development build of React when using Internet Explorer. Luckily it was only the development build, so your production applications were unaffected. This release is mostly to address those issues. There is one notable change if consuming React from npm. For the react-dom package, we moved react from a regular dependency to a peer dependency. This will impact very few people as these two are typically installed together at the top level, but it will fix some issues with dependencies of installed components also using react as a peer dependency.

    - -

    The release is now available for download:

    - - - -

    We've also published version 0.14.2 of the react, react-dom, and addons packages on npm and the react package on bower.

    - -
    - -

    Changelog

    - -

    React DOM

    - -
      -
    • Fixed bug with development build preventing events from firing in some versions of Internet Explorer & Edge
    • -
    • Fixed bug with development build when using es5-sham in older versions of Internet Explorer
    • -
    • Added support for integrity attribute
    • -
    • Fixed bug resulting in children prop being coerced to a string for custom elements, which was not the desired behavior.
    • -
    • Moved react from dependencies to peerDependencies to match expectations and align with react-addons-* packages
    • -
    - -
    - - -

    diff --git a/blog/page5/index.html b/blog/page5/index.html index 1aa3cea21e..52f618d63c 100644 --- a/blog/page5/index.html +++ b/blog/page5/index.html @@ -63,7 +63,7 @@ @@ -76,6 +76,8 @@

    Recent posts

    @@ -106,6 +106,67 @@
    +

    + + React v0.14.2 + +

    + +

    + November 2, 2015 + by + + + Paul O’Shannessy + + + +

    + +
    + +
    +

    We have a quick update following the release of 0.14.1 last week. It turns out we broke a couple things in the development build of React when using Internet Explorer. Luckily it was only the development build, so your production applications were unaffected. This release is mostly to address those issues. There is one notable change if consuming React from npm. For the react-dom package, we moved react from a regular dependency to a peer dependency. This will impact very few people as these two are typically installed together at the top level, but it will fix some issues with dependencies of installed components also using react as a peer dependency.

    + +

    The release is now available for download:

    + + + +

    We've also published version 0.14.2 of the react, react-dom, and addons packages on npm and the react package on bower.

    + +
    + +

    Changelog

    + +

    React DOM

    + + + +
    + + + +
    + +
    + +

    React v0.14.1 @@ -671,114 +732,6 @@ Minified build for production: h -

    - -
    - - -

    - - Community Round-up #27 – Relay Edition - -

    - -

    - September 14, 2015 - by - - - Steven Luscher - - - -

    - -
    - -
    -

    In the weeks following the open-source release of the Relay technical preview, the community has been abuzz with activity. We are honored to have been able to enjoy a steady stream of ideas and contributions from such a talented group of individuals. Let's take a look at some of the things we've achieved, together!

    - -

    Teaching servers to speak GraphQL

    - -

    Every great Relay app starts by finding a GraphQL server to talk to. The community has spent the past few weeks teaching GraphQL to a few backend systems.

    - -

    Bryan Goldstein (brysgo) has built a tool to help you define a GraphQL schema that wraps a set of Bookshelf.JS models. Check out graphql-bookshelf.

    - -

    RisingStack (risingstack) created a GraphQL ORM called graffiti that you can plug into mongoose and serve using Express, Hapi, or Koa.

    - -

    David Mongeau-Petitpas (dmongeau) is working on a way to vend your Laravel models through a GraphQL endpoint, laravel-graphql.

    - -

    Gerald Monaco (devknoll) created graphql-schema to allow the creation of JavaScript GraphQL schemas using a fluent/chainable interface.

    - -

    Jason Dusek (solidsnack) dove deep into PostgreSQL to teach it how to respond to GraphQL query strings as though they were SQL queries. Check out GraphpostgresQL.

    - -

    Espen Hovlandsdal (rexxars) built a sql-to-graphql tool that can perform introspection on the tables of a MySQL or PostgreSQL database, and produce a queryable HTTP GraphQL endpoint out of it.

    - -

    Mick Hansen (mickhansen) offers a set of schema-building helpers for use with the Sequelize ORM for MySQL, PostgreSQL, SQLite, and MSSQL.

    - -

    GraphQL beyond JavaScript

    - -

    Robert Mosolgo (rmosolgo) brought the full set of schema-building and query execution tools to Ruby, in the form of graphql-ruby and graphql-relay-ruby. Check out his Rails-based demo.

    - -

    Andreas Marek (andimarek) has brewed up a Java implementation of GraphQL, graphql-java.

    - -

    vladar is hard at work on a PHP port of the GraphQL reference implementation, graphql-php.

    - -

    Taeho Kim (dittos) is bringing GraphQL to Python, with graphql-py.

    - -

    Oleg Ilyenko (OlegIlyenko) made a beautiful and delicious-looking website for a Scala implementation of GraphQL, sangria.

    - -

    Joe McBride (joemcbride) has an up-and-running example of GraphQL for .NET, graphql-dotnet.

    - -

    Show me, don't tell me

    - -

    Interact with this visual tour of Relay's architecture by Sam Gwilym (sgwilym).

    - -

    - Relay for visual learners -

    - -

    Sam has already launched a product that leverages Relay's data-fetching, optimistic responses, pagination, and mutations – all atop a Ruby GraphQL server: new.comique.co

    - -

    Prototyping in the browser

    - -

    I (steveluscher) whipped up a prototyping tool that you can use to hack on a schema and a React/Relay app, from the comfort of your browser. Thanks to Jimmy Jia (taion) for supplying the local-only network layer, relay-local-schema.

    - -

    Skeletons in the closet

    - -

    Joseph Rollins (fortruce) created a hot-reloading, auto schema-regenerating, Relay skeleton that you can use to get up and running quickly.

    - -

    Michael Hart (mhart) built a simple-relay-starter kit using Browserify.

    - -

    Routing around

    - -

    Jimmy Jia (taion) and Gerald Monaco (devknoll) have been helping lost URLs find their way to Relay apps through their work on react-router-relay. Check out Christoph Pojer's (cpojer) blog post on the topic. Jimmy completed the Relay TodoMVC example with routing, which you can check out at taion/relay-todomvc.

    - -

    Chen Hung-Tu (transedward) built a chat app atop the above mentioned router, with threaded conversations and pagination. Check it out at transedward/relay-chat.

    - -

    In your words

    - -
    -
    - - - - - -
    -
    - - - - - -
    -
    - -
    - - -
    diff --git a/blog/page6/index.html b/blog/page6/index.html index 3baf3646f2..75377df571 100644 --- a/blog/page6/index.html +++ b/blog/page6/index.html @@ -63,7 +63,7 @@ @@ -76,6 +76,8 @@

    Recent posts

    @@ -106,6 +106,114 @@
    +

    + + Community Round-up #27 – Relay Edition + +

    + +

    + September 14, 2015 + by + + + Steven Luscher + + + +

    + +
    + +
    +

    In the weeks following the open-source release of the Relay technical preview, the community has been abuzz with activity. We are honored to have been able to enjoy a steady stream of ideas and contributions from such a talented group of individuals. Let's take a look at some of the things we've achieved, together!

    + +

    Teaching servers to speak GraphQL

    + +

    Every great Relay app starts by finding a GraphQL server to talk to. The community has spent the past few weeks teaching GraphQL to a few backend systems.

    + +

    Bryan Goldstein (brysgo) has built a tool to help you define a GraphQL schema that wraps a set of Bookshelf.JS models. Check out graphql-bookshelf.

    + +

    RisingStack (risingstack) created a GraphQL ORM called graffiti that you can plug into mongoose and serve using Express, Hapi, or Koa.

    + +

    David Mongeau-Petitpas (dmongeau) is working on a way to vend your Laravel models through a GraphQL endpoint, laravel-graphql.

    + +

    Gerald Monaco (devknoll) created graphql-schema to allow the creation of JavaScript GraphQL schemas using a fluent/chainable interface.

    + +

    Jason Dusek (solidsnack) dove deep into PostgreSQL to teach it how to respond to GraphQL query strings as though they were SQL queries. Check out GraphpostgresQL.

    + +

    Espen Hovlandsdal (rexxars) built a sql-to-graphql tool that can perform introspection on the tables of a MySQL or PostgreSQL database, and produce a queryable HTTP GraphQL endpoint out of it.

    + +

    Mick Hansen (mickhansen) offers a set of schema-building helpers for use with the Sequelize ORM for MySQL, PostgreSQL, SQLite, and MSSQL.

    + +

    GraphQL beyond JavaScript

    + +

    Robert Mosolgo (rmosolgo) brought the full set of schema-building and query execution tools to Ruby, in the form of graphql-ruby and graphql-relay-ruby. Check out his Rails-based demo.

    + +

    Andreas Marek (andimarek) has brewed up a Java implementation of GraphQL, graphql-java.

    + +

    vladar is hard at work on a PHP port of the GraphQL reference implementation, graphql-php.

    + +

    Taeho Kim (dittos) is bringing GraphQL to Python, with graphql-py.

    + +

    Oleg Ilyenko (OlegIlyenko) made a beautiful and delicious-looking website for a Scala implementation of GraphQL, sangria.

    + +

    Joe McBride (joemcbride) has an up-and-running example of GraphQL for .NET, graphql-dotnet.

    + +

    Show me, don't tell me

    + +

    Interact with this visual tour of Relay's architecture by Sam Gwilym (sgwilym).

    + +

    + Relay for visual learners +

    + +

    Sam has already launched a product that leverages Relay's data-fetching, optimistic responses, pagination, and mutations – all atop a Ruby GraphQL server: new.comique.co

    + +

    Prototyping in the browser

    + +

    I (steveluscher) whipped up a prototyping tool that you can use to hack on a schema and a React/Relay app, from the comfort of your browser. Thanks to Jimmy Jia (taion) for supplying the local-only network layer, relay-local-schema.

    + +

    Skeletons in the closet

    + +

    Joseph Rollins (fortruce) created a hot-reloading, auto schema-regenerating, Relay skeleton that you can use to get up and running quickly.

    + +

    Michael Hart (mhart) built a simple-relay-starter kit using Browserify.

    + +

    Routing around

    + +

    Jimmy Jia (taion) and Gerald Monaco (devknoll) have been helping lost URLs find their way to Relay apps through their work on react-router-relay. Check out Christoph Pojer's (cpojer) blog post on the topic. Jimmy completed the Relay TodoMVC example with routing, which you can check out at taion/relay-todomvc.

    + +

    Chen Hung-Tu (transedward) built a chat app atop the above mentioned router, with threaded conversations and pagination. Check it out at transedward/relay-chat.

    + +

    In your words

    + +
    +
    + + + + + +
    +
    + + + + + +
    +
    + +
    + + + +
    + +
    + +

    React v0.14 Release Candidate @@ -511,131 +619,6 @@ Minified build for production: - - -

    - - New React Devtools Beta - -

    - -

    - August 3, 2015 - by - - - Jared Forsyth - - - -

    - -
    - -
    -

    We've made an entirely new version of the devtools, and we want you to try it -out!

    - -

    The full devtools gif

    - -

    Why entirely new?

    - -

    Perhaps the biggest reason was to create a defined API for dealing with -internals, so that other tools could benefit as well and not have to depend on -implementation details. This gives us more freedom to refactor things -internally without worrying about breaking tooling.

    - -

    The current version of the devtools is a fork of Blink's "Elements" pane, and -is imperative, mutation-driven, and tightly integrated with Chrome-specific -APIs. The new devtools are much less coupled to Chrome, and easier to reason -about thanks to React.

    - -

    What are the benefits?

    - -
      -
    • 100% React
    • -
    • Firefox compatible
    • -
    • React Native compatible
    • -
    • more extensible & hackable
    • -
    - -

    Are there any new features?

    - -

    Yeah!

    - -

    The Tree View

    - -

    The new tree view of the devtools

    - -
      -
    • Much richer view of your props, including the contents of objects and arrays
    • -
    • Custom components are emphasized, native components are de-emphasized
    • -
    • Stateful components have a red collapser
    • -
    • Improved keyboard navigation (hjkl or arrow keys)
    • -
    • Selected component is available in the console as $r
    • -
    • Props that change highlight in green
    • -
    • Right-click menu

      - -
        -
      • Scroll node into view
      • -
      • Show the source for a component in the "Sources" pane
      • -
      • Show the element in the "Elements" pane
      • -
    • -
    - -

    Searching

    - -

    Select the search bar (or press "/"), and start searching for a component by -name.

    - -

    - -

    The Side Pane

    - -
      -
    • Now shows the context for a component
    • -
    • Right-click to store a prop/state value as a global variable
    • -
    - -

    - -

    How do I install it?

    - -

    First, disable the Chrome web store version, or it will break things. Then -download the .crx and -drag it into your chrome://extensions page. If it's not working to drag it -from the downloads bar, try opening your downloads folder and drag it from -there.

    - -

    Once we've determined that there aren't any major regressions, we'll update -the official web store version, and everyone will be automatically upgraded.

    - -

    Also Firefox!

    - -

    We also have an initial version of the devtools for Firefox, which you can -download from the same release page.

    - -

    Feedback welcome

    - -

    Let us know what issues you run into -on GitHub, and check out -the README -for more info.

    - -

    Update

    - -

    August 12, 2015

    - -

    A second beta is out, with a number of bugfixes. It is also listed on the -releases page.

    - -
    - - -

    diff --git a/blog/page7/index.html b/blog/page7/index.html index f9e96bf53a..6e59f3e4c0 100644 --- a/blog/page7/index.html +++ b/blog/page7/index.html @@ -63,7 +63,7 @@ @@ -76,6 +76,8 @@

    Recent posts

    @@ -106,6 +106,131 @@
    +

    + + New React Devtools Beta + +

    + +

    + August 3, 2015 + by + + + Jared Forsyth + + + +

    + +
    + +
    +

    We've made an entirely new version of the devtools, and we want you to try it +out!

    + +

    The full devtools gif

    + +

    Why entirely new?

    + +

    Perhaps the biggest reason was to create a defined API for dealing with +internals, so that other tools could benefit as well and not have to depend on +implementation details. This gives us more freedom to refactor things +internally without worrying about breaking tooling.

    + +

    The current version of the devtools is a fork of Blink's "Elements" pane, and +is imperative, mutation-driven, and tightly integrated with Chrome-specific +APIs. The new devtools are much less coupled to Chrome, and easier to reason +about thanks to React.

    + +

    What are the benefits?

    + + + +

    Are there any new features?

    + +

    Yeah!

    + +

    The Tree View

    + +

    The new tree view of the devtools

    + + + +

    Searching

    + +

    Select the search bar (or press "/"), and start searching for a component by +name.

    + +

    + +

    The Side Pane

    + + + +

    + +

    How do I install it?

    + +

    First, disable the Chrome web store version, or it will break things. Then +download the .crx and +drag it into your chrome://extensions page. If it's not working to drag it +from the downloads bar, try opening your downloads folder and drag it from +there.

    + +

    Once we've determined that there aren't any major regressions, we'll update +the official web store version, and everyone will be automatically upgraded.

    + +

    Also Firefox!

    + +

    We also have an initial version of the devtools for Firefox, which you can +download from the same release page.

    + +

    Feedback welcome

    + +

    Let us know what issues you run into +on GitHub, and check out +the README +for more info.

    + +

    Update

    + +

    August 12, 2015

    + +

    A second beta is out, with a number of bugfixes. It is also listed on the +releases page.

    + +
    + + + +
    + +
    + +

    React v0.14 Beta 1 @@ -374,132 +499,6 @@ Minified build for production: - - -

    - - GraphQL Introduction - -

    - -

    - May 1, 2015 - by - - - Nick Schrock - - - -

    - -
    - -
    -

    At the React.js conference in late January 2015, we revealed our next major technology in the React family: Relay.

    - -

    Relay is a new way of structuring client applications that co-locates data-fetching requirements and React components. Instead of placing data fetching logic in some other part of the client application – or embedding this logic in a custom endpoint on the server – we instead co-locate a declarative data-fetching specification alongside the React component. The language of this declarative specification is GraphQL.

    - -

    GraphQL was not invented to enable Relay. In fact, GraphQL predates Relay by nearly three years. It was invented during the move from Facebook's HTML5-driven mobile applications to purely native applications. It is a query language for graph data that powers the lion's share of interactions in the Facebook Android and iOS applications. Any user of the native iOS or Android app in the last two years has used an app powered by GraphQL.

    - -

    We plan to open-source a reference implementation of a GraphQL server and publish a language specification in the coming months. Our goal is to evolve GraphQL to adapt to a wide range of backends, so that projects and companies can use this technology to access their own data. We believe that this is a compelling way to structure servers and to provide powerful abstractions, frameworks and tools – including, but not exclusively, Relay – for product developers.

    - -

    What is GraphQL?

    - -

    A GraphQL query is a string interpreted by a server that returns data in a specified format. Here is an example query:

    -
    {
    -  user(id: 3500401) {
    -    id,
    -    name,
    -    isViewerFriend,
    -    profilePicture(size: 50)  {
    -      uri,
    -      width,
    -      height
    -    }
    -  }
    -}
    -
    -

    (Note: this syntax is slightly different from previous GraphQL examples. We've recently been making improvements to the language.)

    - -

    And here is the response to that query.

    -
    {
    -  "user" : {
    -    "id": 3500401,
    -    "name": "Jing Chen",
    -    "isViewerFriend": true,
    -    "profilePicture": {
    -      "uri": "http://someurl.cdn/pic.jpg",
    -      "width": 50,
    -      "height": 50
    -    }
    -  }
    -}
    -
    -

    We will dig into the syntax and semantics of GraphQL in a later post, but even a simple example shows many of its design principles:

    - -
      -
    • Hierarchical: Most product development today involves the creation and manipulation of view hierarchies. To achieve congruence with the structure of these applications, a GraphQL query itself is a hierarchical set of fields. The query is shaped just like the data it returns. It is a natural way for product engineers to describe data requirements.
    • -
    • Product-centric: GraphQL is unapologetically driven by the requirements of views and the front-end engineers that write them. We start with their way of thinking and requirements and build the language and runtime necessary to enable that.
    • -
    • Client-specified queries: In GraphQL, the specification for queries are encoded in the client rather than the server. These queries are specified at field-level granularity. In the vast majority of applications written without GraphQL, the server determines the data returned in its various scripted endpoints. A GraphQL query, on the other hand, returns exactly what a client asks for and no more.
    • -
    • Backwards Compatible: In a world of deployed native mobile applications with no forced upgrades, backwards compatibility is a challenge. Facebook, for example, releases apps on a two week fixed cycle and pledges to maintain those apps for at least two years. This means there are at a minimum 52 versions of our clients per platform querying our servers at any given time. Client-specified queries simplifies managing our backwards compatibility guarantees.
    • -
    • Structured, Arbitrary Code: Query languages with field-level granularity have typically queried storage engines directly, such as SQL. GraphQL instead imposes a structure onto a server, and exposes fields that are backed by arbitrary code. This allows for both server-side flexibility and a uniform, powerful API across the entire surface area of an application.
    • -
    • Application-Layer Protocol: GraphQL is an application-layer protocol and does not require a particular transport. It is a string that is parsed and interpreted by a server.
    • -
    • Strongly-typed: GraphQL is strongly-typed. Given a query, tooling can ensure that the query is both syntactically correct and valid within the GraphQL type system before execution, i.e. at development time, and the server can make certain guarantees about the shape and nature of the response. This makes it easier to build high quality client tools.
    • -
    • Introspective: GraphQL is introspective. Clients and tools can query the type system using the GraphQL syntax itself. This is a powerful platform for building tools and client software, such as automatic parsing of incoming data into strongly-typed interfaces. It is especially useful in statically typed languages such as Swift, Objective-C and Java, as it obviates the need for repetitive and error-prone code to shuffle raw, untyped JSON into strongly-typed business objects.
    • -
    - -

    Why invent something new?

    - -

    Obviously GraphQL is not the first system to manage client-server interactions. In today's world there are two dominant architectural styles for client-server interaction: REST and ad hoc endpoints.

    - -

    REST

    - -

    REST, an acronym for Representational State Transfer, is an architectural style rather than a formal protocol. There is actually much debate about what exactly REST is and is not. We wish to avoid such debates. We are interested in the typical attributes of systems that self-identify as REST, rather than systems which are formally REST.

    - -

    Objects in a typical REST system are addressable by URI and interacted with using verbs in the HTTP protocol. An HTTP GET to a particular URI fetches an object and returns a server-specified set of fields. An HTTP PUT edits an object; an HTTP DELETE deletes an object; and so on.

    - -

    We believe there are a number of weakness in typical REST systems, ones that are particularly problematic in mobile applications:

    - -
      -
    • Fetching complicated object graphs require multiple round trips between the client and server to render single views. For mobile applications operating in variable network conditions, these multiple roundtrips are highly undesirable.
    • -
    • Invariably fields and additional data are added to REST endpoints as the system requirements change. However, old clients also receive this additional data as well, because the data fetching specification is encoded on the server rather than the client. As result, these payloads tend to grow over time for all clients. When this becomes a problem for a system, one solution is to overlay a versioning system onto the REST endpoints. Versioning also complicates a server, and results in code duplication, spaghetti code, or a sophisticated, hand-rolled infrastructure to manage it. Another solution to limit over-fetching is to provide multiple views – such as “compact” vs “full” – of the same REST endpoint, however this coarse granularity often does not offer adequate flexibility.
    • -
    • REST endpoints are usually weakly-typed and lack machine-readable metadata. While there is much debate about the merits of strong- versus weak-typing in distributed systems, we believe in strong typing because of the correctness guarantees and tooling opportunities it provides. Developers deal with systems that lack this metadata by inspecting frequently out-of-date documentation and then writing code against the documentation.
    • -
    • Many of these attributes are linked to the fact that “REST is intended for long-lived network-based applications that span multiple organizations” according to its inventor. This is not a requirement for APIs that serve a client app built within the same organization.
    • -
    - -

    Nearly all externally facing REST APIs we know of trend or end up in these non-ideal states, as well as nearly all internal REST APIs. The consequences of opaqueness and over-fetching are more severe in internal APIs since their velocity of change and level of usage is almost always higher.

    - -

    Because of multiple round-trips and over-fetching, applications built in the REST style inevitably end up building ad hoc endpoints that are superficially in the REST style. These actually couple the data to a particular view which explicitly violates one of REST's major goals. Most REST systems of any complexity end up as a continuum of endpoints that span from “traditional” REST to ad hoc endpoints.

    - -

    Ad Hoc Endpoints

    - -

    Many applications have no formalized client-server contract. Product developers access server capabilities through ad hoc endpoints and write custom code to fetch the data they need. Servers define procedures, and they return data. This approach has the virtue of simplicity, but can often become untenable as systems age.

    - -
      -
    • These systems typically define a custom endpoint per view. For systems with a wide surface area this can quickly grow into a maintenance nightmare of orphaned endpoints, inconsistent tooling, and massive server code duplication. Disciplined engineering organizations can mitigate these issues with great engineering practices, high quality abstractions, and custom tooling. However, given our experience we believe that custom endpoints tend to lead to entropic server codebases.
    • -
    • Much like REST, the payloads of custom endpoints grow monotonically (even with mitigation from versioning systems) as the server evolves. Deployed clients cannot break, and, with rapid release cycles and backwards compatibility guarantees, distributed applications will have large numbers of extant versions. Under these constraints it is difficult to remove data from a custom endpoint.
    • -
    • Custom endpoints tend to – for a client developer – create a clunky, multi-language, multi-environment development process. No matter if the data has been accessed before in a different view, they are required to first change the custom endpoint, then deploy that code to a server accessible from a mobile device, and only then change the client to utilize that data. In GraphQL – unless the data in the view is completely new to the entire system – a product developer adds a field to a GraphQL query and the work on the client continues unabated.
    • -
    • Much like REST, most systems with custom endpoints do not have a formalized type system, which eliminates the possibility for the tools and guarantees that introspective type systems can provide. Some custom-endpoint-driven systems do use a strongly typed serialization scheme, such as Protocol Buffers, Thrift, or XML. Those do allow for direct parsing of responses into typed classes and eliminating boilerplate shuffling from JSON into handwritten classes. These systems are as not as expressive and flexible as GraphQL, and the other downsides of ad hoc endpoints remain.
    • -
    - -

    We believe that GraphQL represents a novel way of structuring the client-server contract. Servers publish a type system specific to their application, and GraphQL provides a unified language to query data within the constraints of that type system. That language allows product developers to express data requirements in a form natural to them: a declarative and hierarchal one.

    - -

    This is a liberating platform for product developers. With GraphQL, no more contending with ad hoc endpoints or object retrieval with multiple roundtrips to access server data; instead an elegant, hierarchical, declarative query dispatched to a single endpoint. No more frequent jumps between client and server development environments to do experimentation or to change or create views of existing data; instead experiments are done and new views built within a native, client development environment exclusively. No more shuffling unstructured data from ad hoc endpoints into business objects; instead a powerful, introspective type system that serves as a platform for tool building.

    - -

    Product developers are free to focus on their client software and requirements while rarely leaving their development environment; they can more confidently support shipped clients as a system evolves; and they are using a protocol designed to operate well within the constraints of mobile applications. Product developers can query for exactly what they want, in the way they think about it, across their entire application's data model.

    - -

    What's next?

    - -

    Over the coming months, we will share more technical details about GraphQL, including additional language features, tools that support it, and how it is built and used at Facebook. These posts will culminate in a formal specification of GraphQL to guide implementors across various languages and platforms. We also plan on releasing a reference implementation in the summer, in order to provide a basis for custom deployments and a platform for experimentation. We're incredibly excited to share this system and work with the open source community to improve it.

    - -
    - - -

    diff --git a/blog/page8/index.html b/blog/page8/index.html index 7bdbc429c0..4131a01693 100644 --- a/blog/page8/index.html +++ b/blog/page8/index.html @@ -63,7 +63,7 @@ @@ -76,6 +76,8 @@

    Recent posts

    @@ -106,6 +106,132 @@
    +

    + + GraphQL Introduction + +

    + +

    + May 1, 2015 + by + + + Nick Schrock + + + +

    + +
    + +
    +

    At the React.js conference in late January 2015, we revealed our next major technology in the React family: Relay.

    + +

    Relay is a new way of structuring client applications that co-locates data-fetching requirements and React components. Instead of placing data fetching logic in some other part of the client application – or embedding this logic in a custom endpoint on the server – we instead co-locate a declarative data-fetching specification alongside the React component. The language of this declarative specification is GraphQL.

    + +

    GraphQL was not invented to enable Relay. In fact, GraphQL predates Relay by nearly three years. It was invented during the move from Facebook's HTML5-driven mobile applications to purely native applications. It is a query language for graph data that powers the lion's share of interactions in the Facebook Android and iOS applications. Any user of the native iOS or Android app in the last two years has used an app powered by GraphQL.

    + +

    We plan to open-source a reference implementation of a GraphQL server and publish a language specification in the coming months. Our goal is to evolve GraphQL to adapt to a wide range of backends, so that projects and companies can use this technology to access their own data. We believe that this is a compelling way to structure servers and to provide powerful abstractions, frameworks and tools – including, but not exclusively, Relay – for product developers.

    + +

    What is GraphQL?

    + +

    A GraphQL query is a string interpreted by a server that returns data in a specified format. Here is an example query:

    +
    {
    +  user(id: 3500401) {
    +    id,
    +    name,
    +    isViewerFriend,
    +    profilePicture(size: 50)  {
    +      uri,
    +      width,
    +      height
    +    }
    +  }
    +}
    +
    +

    (Note: this syntax is slightly different from previous GraphQL examples. We've recently been making improvements to the language.)

    + +

    And here is the response to that query.

    +
    {
    +  "user" : {
    +    "id": 3500401,
    +    "name": "Jing Chen",
    +    "isViewerFriend": true,
    +    "profilePicture": {
    +      "uri": "http://someurl.cdn/pic.jpg",
    +      "width": 50,
    +      "height": 50
    +    }
    +  }
    +}
    +
    +

    We will dig into the syntax and semantics of GraphQL in a later post, but even a simple example shows many of its design principles:

    + + + +

    Why invent something new?

    + +

    Obviously GraphQL is not the first system to manage client-server interactions. In today's world there are two dominant architectural styles for client-server interaction: REST and ad hoc endpoints.

    + +

    REST

    + +

    REST, an acronym for Representational State Transfer, is an architectural style rather than a formal protocol. There is actually much debate about what exactly REST is and is not. We wish to avoid such debates. We are interested in the typical attributes of systems that self-identify as REST, rather than systems which are formally REST.

    + +

    Objects in a typical REST system are addressable by URI and interacted with using verbs in the HTTP protocol. An HTTP GET to a particular URI fetches an object and returns a server-specified set of fields. An HTTP PUT edits an object; an HTTP DELETE deletes an object; and so on.

    + +

    We believe there are a number of weakness in typical REST systems, ones that are particularly problematic in mobile applications:

    + + + +

    Nearly all externally facing REST APIs we know of trend or end up in these non-ideal states, as well as nearly all internal REST APIs. The consequences of opaqueness and over-fetching are more severe in internal APIs since their velocity of change and level of usage is almost always higher.

    + +

    Because of multiple round-trips and over-fetching, applications built in the REST style inevitably end up building ad hoc endpoints that are superficially in the REST style. These actually couple the data to a particular view which explicitly violates one of REST's major goals. Most REST systems of any complexity end up as a continuum of endpoints that span from “traditional” REST to ad hoc endpoints.

    + +

    Ad Hoc Endpoints

    + +

    Many applications have no formalized client-server contract. Product developers access server capabilities through ad hoc endpoints and write custom code to fetch the data they need. Servers define procedures, and they return data. This approach has the virtue of simplicity, but can often become untenable as systems age.

    + + + +

    We believe that GraphQL represents a novel way of structuring the client-server contract. Servers publish a type system specific to their application, and GraphQL provides a unified language to query data within the constraints of that type system. That language allows product developers to express data requirements in a form natural to them: a declarative and hierarchal one.

    + +

    This is a liberating platform for product developers. With GraphQL, no more contending with ad hoc endpoints or object retrieval with multiple roundtrips to access server data; instead an elegant, hierarchical, declarative query dispatched to a single endpoint. No more frequent jumps between client and server development environments to do experimentation or to change or create views of existing data; instead experiments are done and new views built within a native, client development environment exclusively. No more shuffling unstructured data from ad hoc endpoints into business objects; instead a powerful, introspective type system that serves as a platform for tool building.

    + +

    Product developers are free to focus on their client software and requirements while rarely leaving their development environment; they can more confidently support shipped clients as a system evolves; and they are using a protocol designed to operate well within the constraints of mobile applications. Product developers can query for exactly what they want, in the way they think about it, across their entire application's data model.

    + +

    What's next?

    + +

    Over the coming months, we will share more technical details about GraphQL, including additional language features, tools that support it, and how it is built and used at Facebook. These posts will culminate in a formal specification of GraphQL to guide implementors across various languages and platforms. We also plan on releasing a reference implementation in the summer, in order to provide a basis for custom deployments and a platform for experimentation. We're incredibly excited to share this system and work with the open source community to improve it.

    + +
    + + + +
    + +
    + +

    React v0.13.2 @@ -390,234 +516,6 @@ Minified build for production: - - -

    - - Building The Facebook News Feed With Relay - -

    - -

    - March 19, 2015 - by - - - Joseph Savona - - - -

    - -
    - -
    -

    At React.js Conf in January we gave a preview of Relay, a new framework for building data-driven applications in React. In this post, we'll describe the process of creating a Relay application. This post assumes some familiarity with the concepts of Relay and GraphQL, so if you haven't already we recommend reading our introductory blog post or watching the conference talk.

    - -

    We're working hard to prepare GraphQL and Relay for public release. In the meantime, we'll continue to provide information about what you can expect.

    - -


    - -

    The Relay Architecture

    - -

    The diagram below shows the main parts of the Relay architecture on the client and the server:

    - -

    Relay Architecture

    - -

    The main pieces are as follows:

    - -
      -
    • Relay Components: React components annotated with declarative data descriptions.
    • -
    • Actions: Descriptions of how data should change in response to user actions.
    • -
    • Relay Store: A client-side data store that is fully managed by the framework.
    • -
    • Server: An HTTP server with GraphQL endpoints (one for reads, one for writes) that respond to GraphQL queries.
    • -
    - -

    This post will focus on Relay components that describe encapsulated units of UI and their data dependencies. These components form the majority of a Relay application.

    - -


    - -

    A Relay Application

    - -

    To see how components work and can be composed, let's implement a basic version of the Facebook News Feed in Relay. Our application will have two components: a <NewsFeed> that renders a list of <Story> items. We'll introduce the plain React version of each component first and then convert it to a Relay component. The goal is something like the following:

    - -

    Sample News Feed

    - -


    - -

    The <Story> Begins

    - -

    The first step is a React <Story> component that accepts a story prop with the story's text and author information. Note that all examples uses ES6 syntax and elide presentation details to focus on the pattern of data access.

    -
    // Story.react.js
    -export default class Story extends React.Component {
    -  render() {
    -    var story = this.props.story;
    -    return (
    -      <View>
    -        <Image uri={story.author.profilePicture.uri} />
    -        <Text>{story.author.name}</Text>
    -        <Text>{story.text}</Text>
    -      </View>
    -    );
    -  }
    -}
    -
    -


    - -

    What's the <Story>?

    - -

    Relay automates the process of fetching data for components by wrapping existing React components in Relay containers (themselves React components):

    -
    // Story.react.js
    -class Story extends React.Component { ... }
    -
    -export default Relay.createContainer(Story, {
    -  fragments: {
    -    story: /* TODO */
    -  }
    -});
    -
    -

    Before adding the GraphQL fragment, let's look at the component hierarchy this creates:

    - -

    React Container Data Flow

    - -

    Most props will be passed through from the container to the original component. However, Relay will return the query results for a prop whenever a fragment is defined. In this case we'll add a GraphQL fragment for story:

    -
    // Story.react.js
    -class Story extends React.Component { ... }
    -
    -export default Relay.createContainer(Story, {
    -  fragments: {
    -    story: () => Relay.QL`
    -      fragment on Story {
    -        author {
    -          name
    -          profilePicture {
    -            uri
    -          }
    -        }
    -        text
    -      }
    -    `,
    -  },
    -});
    -
    -

    Queries use ES6 template literals tagged with the Relay.QL function. Similar to how JSX transpiles to plain JavaScript objects and function calls, these template literals transpile to plain objects that describe fragments. Note that the fragment's structure closely matches the object structure that we expected in <Story>'s render function.

    - -


    - -

    <Story>s on Demand

    - -

    We can render a Relay component by providing Relay with the component (<Story>) and the ID of the data (a story ID). Given this information, Relay will first fetch the results of the query and then render() the component. The value of props.story will be a plain JavaScript object such as the following:

    -
    {
    -  author: {
    -    name: "Greg",
    -    profilePicture: {
    -      uri: "https://…"
    -    }
    -  },
    -  text: "The first Relay blog post is up…"
    -}
    -
    -

    Relay guarantees that all data required to render a component will be available before it is rendered. This means that <Story> does not need to handle a loading state; the story is guaranteed to be available before render() is called. We have found that this invariant simplifies our application code and improves the user experience. Of course, Relay also has options to delay the fetching of some parts of our queries.

    - -

    The diagram below shows how Relay containers make data available to our React components:

    - -

    Relay Container Data Flow

    - -


    - -

    <NewsFeed> Worthy

    - -

    Now that the <Story> is over we can continue with the <NewsFeed> component. Again, we'll start with a React version:

    -
    // NewsFeed.react.js
    -class NewsFeed extends React.Component {
    -  render() {
    -    var stories = this.props.viewer.stories; // `viewer` is the active user
    -    return (
    -      <View>
    -        {stories.map(story => <Story story={story} />)}
    -        <Button onClick={() => this.loadMore()}>Load More</Button>
    -      </View>
    -    );
    -  }
    -
    -  loadMore() {
    -    // TODO: fetch more stories
    -  }
    -}
    -
    -module.exports = NewsFeed;
    -
    -


    - -

    All the News Fit to be Relayed

    - -

    <NewsFeed> has two new requirements: it composes <Story> and requests more data at runtime.

    - -

    Just as React views can be nested, Relay components can compose query fragments from child components. Composition in GraphQL uses ES6 template literal substitution: ${Component.getFragment('prop')}. Pagination can be accomplished with a variable, specified with $variable (as in stories(first: $count)):

    -
    // NewsFeed.react.js
    -class NewsFeed extends React.Component { ... }
    -
    -export default Relay.createContainer(NewsFeed, {
    -  initialVariables: {
    -    count: 3                                /* default to 3 stories */
    -  },
    -  fragments: {
    -    viewer: () => Relay.QL`
    -      fragment on Viewer {
    -        stories(first: $count) {            /* fetch viewer's stories */
    -          edges {                           /* traverse the graph */
    -            node {
    -              ${Story.getFragment('story')} /* compose child fragment */
    -            }
    -          }
    -        }
    -      }
    -    `,
    -  },
    -});
    -
    -

    Whenever <NewsFeed> is rendered, Relay will recursively expand all the composed fragments and fetch the queries in a single trip to the server. In this case, the text and author data will be fetched for each of the 3 story nodes.

    - -

    Query variables are available to components as props.relay.variables and can be modified with props.relay.setVariables(nextVariables). We can use these to implement pagination:

    -
    // NewsFeed.react.js
    -class NewsFeed extends React.Component {
    -  render() { ... }
    -
    -  loadMore() {
    -    // read current params
    -    var count = this.props.relay.variables.count;
    -    // update params
    -    this.props.relay.setVariables({
    -      count: count + 5,
    -    });
    -  }
    -}
    -
    -

    Now when loadMore() is called, Relay will send a GraphQL request for the additional five stories. When these stories are fetched, the component will re-render with the new stories available in props.viewer.stories and the updated count reflected in props.relay.variables.count.

    - -


    - -

    In Conclusion

    - -

    These two components form a solid core for our application. With the use of Relay containers and GraphQL queries, we've enabled the following benefits:

    - -
      -
    • Automatic and efficient pre-fetching of data for an entire view hierarchy in a single network request.
    • -
    • Trivial pagination with automatic optimizations to fetch only the additional items.
    • -
    • View composition and reusability, so that <Story> can be used on its own or within <NewsFeed>, without any changes to either component.
    • -
    • Automatic subscriptions, so that components will re-render if their data changes. Unaffected components will not re-render unnecessarily.
    • -
    • Exactly zero lines of imperative data fetching logic. Relay takes full advantage of React's declarative component model.
    • -
    - -

    But Relay has many more tricks up its sleeve. For example, it's built from the start to handle reads and writes, allowing for features like optimistic client updates with transactional rollback. Relay can also defer fetching select parts of queries, and it uses a local data store to avoid fetching the same data twice. These are all powerful features that we hope to explore in future posts.

    - -
    - - -

    diff --git a/blog/page9/index.html b/blog/page9/index.html index 35e49443b2..a469c4e4d8 100644 --- a/blog/page9/index.html +++ b/blog/page9/index.html @@ -63,7 +63,7 @@ @@ -76,6 +76,8 @@

    Recent posts

    @@ -106,6 +106,234 @@
    +

    + + Building The Facebook News Feed With Relay + +

    + +

    + March 19, 2015 + by + + + Joseph Savona + + + +

    + +
    + +
    +

    At React.js Conf in January we gave a preview of Relay, a new framework for building data-driven applications in React. In this post, we'll describe the process of creating a Relay application. This post assumes some familiarity with the concepts of Relay and GraphQL, so if you haven't already we recommend reading our introductory blog post or watching the conference talk.

    + +

    We're working hard to prepare GraphQL and Relay for public release. In the meantime, we'll continue to provide information about what you can expect.

    + +


    + +

    The Relay Architecture

    + +

    The diagram below shows the main parts of the Relay architecture on the client and the server:

    + +

    Relay Architecture

    + +

    The main pieces are as follows:

    + + + +

    This post will focus on Relay components that describe encapsulated units of UI and their data dependencies. These components form the majority of a Relay application.

    + +


    + +

    A Relay Application

    + +

    To see how components work and can be composed, let's implement a basic version of the Facebook News Feed in Relay. Our application will have two components: a <NewsFeed> that renders a list of <Story> items. We'll introduce the plain React version of each component first and then convert it to a Relay component. The goal is something like the following:

    + +

    Sample News Feed

    + +


    + +

    The <Story> Begins

    + +

    The first step is a React <Story> component that accepts a story prop with the story's text and author information. Note that all examples uses ES6 syntax and elide presentation details to focus on the pattern of data access.

    +
    // Story.react.js
    +export default class Story extends React.Component {
    +  render() {
    +    var story = this.props.story;
    +    return (
    +      <View>
    +        <Image uri={story.author.profilePicture.uri} />
    +        <Text>{story.author.name}</Text>
    +        <Text>{story.text}</Text>
    +      </View>
    +    );
    +  }
    +}
    +
    +


    + +

    What's the <Story>?

    + +

    Relay automates the process of fetching data for components by wrapping existing React components in Relay containers (themselves React components):

    +
    // Story.react.js
    +class Story extends React.Component { ... }
    +
    +export default Relay.createContainer(Story, {
    +  fragments: {
    +    story: /* TODO */
    +  }
    +});
    +
    +

    Before adding the GraphQL fragment, let's look at the component hierarchy this creates:

    + +

    React Container Data Flow

    + +

    Most props will be passed through from the container to the original component. However, Relay will return the query results for a prop whenever a fragment is defined. In this case we'll add a GraphQL fragment for story:

    +
    // Story.react.js
    +class Story extends React.Component { ... }
    +
    +export default Relay.createContainer(Story, {
    +  fragments: {
    +    story: () => Relay.QL`
    +      fragment on Story {
    +        author {
    +          name
    +          profilePicture {
    +            uri
    +          }
    +        }
    +        text
    +      }
    +    `,
    +  },
    +});
    +
    +

    Queries use ES6 template literals tagged with the Relay.QL function. Similar to how JSX transpiles to plain JavaScript objects and function calls, these template literals transpile to plain objects that describe fragments. Note that the fragment's structure closely matches the object structure that we expected in <Story>'s render function.

    + +


    + +

    <Story>s on Demand

    + +

    We can render a Relay component by providing Relay with the component (<Story>) and the ID of the data (a story ID). Given this information, Relay will first fetch the results of the query and then render() the component. The value of props.story will be a plain JavaScript object such as the following:

    +
    {
    +  author: {
    +    name: "Greg",
    +    profilePicture: {
    +      uri: "https://…"
    +    }
    +  },
    +  text: "The first Relay blog post is up…"
    +}
    +
    +

    Relay guarantees that all data required to render a component will be available before it is rendered. This means that <Story> does not need to handle a loading state; the story is guaranteed to be available before render() is called. We have found that this invariant simplifies our application code and improves the user experience. Of course, Relay also has options to delay the fetching of some parts of our queries.

    + +

    The diagram below shows how Relay containers make data available to our React components:

    + +

    Relay Container Data Flow

    + +


    + +

    <NewsFeed> Worthy

    + +

    Now that the <Story> is over we can continue with the <NewsFeed> component. Again, we'll start with a React version:

    +
    // NewsFeed.react.js
    +class NewsFeed extends React.Component {
    +  render() {
    +    var stories = this.props.viewer.stories; // `viewer` is the active user
    +    return (
    +      <View>
    +        {stories.map(story => <Story story={story} />)}
    +        <Button onClick={() => this.loadMore()}>Load More</Button>
    +      </View>
    +    );
    +  }
    +
    +  loadMore() {
    +    // TODO: fetch more stories
    +  }
    +}
    +
    +module.exports = NewsFeed;
    +
    +


    + +

    All the News Fit to be Relayed

    + +

    <NewsFeed> has two new requirements: it composes <Story> and requests more data at runtime.

    + +

    Just as React views can be nested, Relay components can compose query fragments from child components. Composition in GraphQL uses ES6 template literal substitution: ${Component.getFragment('prop')}. Pagination can be accomplished with a variable, specified with $variable (as in stories(first: $count)):

    +
    // NewsFeed.react.js
    +class NewsFeed extends React.Component { ... }
    +
    +export default Relay.createContainer(NewsFeed, {
    +  initialVariables: {
    +    count: 3                                /* default to 3 stories */
    +  },
    +  fragments: {
    +    viewer: () => Relay.QL`
    +      fragment on Viewer {
    +        stories(first: $count) {            /* fetch viewer's stories */
    +          edges {                           /* traverse the graph */
    +            node {
    +              ${Story.getFragment('story')} /* compose child fragment */
    +            }
    +          }
    +        }
    +      }
    +    `,
    +  },
    +});
    +
    +

    Whenever <NewsFeed> is rendered, Relay will recursively expand all the composed fragments and fetch the queries in a single trip to the server. In this case, the text and author data will be fetched for each of the 3 story nodes.

    + +

    Query variables are available to components as props.relay.variables and can be modified with props.relay.setVariables(nextVariables). We can use these to implement pagination:

    +
    // NewsFeed.react.js
    +class NewsFeed extends React.Component {
    +  render() { ... }
    +
    +  loadMore() {
    +    // read current params
    +    var count = this.props.relay.variables.count;
    +    // update params
    +    this.props.relay.setVariables({
    +      count: count + 5,
    +    });
    +  }
    +}
    +
    +

    Now when loadMore() is called, Relay will send a GraphQL request for the additional five stories. When these stories are fetched, the component will re-render with the new stories available in props.viewer.stories and the updated count reflected in props.relay.variables.count.

    + +


    + +

    In Conclusion

    + +

    These two components form a solid core for our application. With the use of Relay containers and GraphQL queries, we've enabled the following benefits:

    + + + +

    But Relay has many more tricks up its sleeve. For example, it's built from the start to handle reads and writes, allowing for features like optimistic client updates with transactional rollback. Relay can also defer fetching select parts of queries, and it uses a local data store to avoid fetching the same data twice. These are all powerful features that we hope to explore in future posts.

    + +
    + + + +
    + +
    + +

    React v0.13.1 @@ -481,124 +709,6 @@ Minified build for production: - - -

    - - React v0.13 RC - -

    - -

    - February 24, 2015 - by - - - Paul O’Shannessy - - - -

    - -
    - -
    -

    Over the weekend we pushed out our first (and hopefully only) release candidate for React v0.13!

    - -

    We've talked a little bit about the changes that are coming. The splashiest of these changes is support for ES6 Classes. You can read more about this in our beta announcement. We're really excited about this! Sebastian also posted earlier this morning about some of the other changes coming focused around ReactElement. The changes we've been working on there will hopefully enable lots of improvements to performance and developer experience.

    - -

    The release candidate is available for download:

    - - - -

    We've also published version 0.13.0-rc1 of the react and react-tools packages on npm and the react package on bower.

    - -
    - -

    Changelog

    - -

    React Core

    - -

    Breaking Changes

    - -
      -
    • Mutating props after an element is created is deprecated and will cause warnings in development mode; future versions of React will incorporate performance optimizations assuming that props aren't mutated
    • -
    • Static methods (defined in statics) are no longer autobound to the component class
    • -
    • ref resolution order has changed slightly such that a ref to a component is available immediately after its componentDidMount method is called; this change should be observable only if your component calls a parent component's callback within your componentDidMount, which is an anti-pattern and should be avoided regardless
    • -
    • Calls to setState in life-cycle methods are now always batched and therefore asynchronous. Previously the first call on the first mount was synchronous.
    • -
    • setState and forceUpdate on an unmounted component now warns instead of throwing. That avoids a possible race condition with Promises.
    • -
    • Access to most internal properties has been completely removed, including this._pendingState and this._rootNodeID.
    • -
    - -

    New Features

    - -
      -
    • Support for using ES6 classes to build React components; see the v0.13.0 beta 1 notes for details
    • -
    • Added new top-level API React.findDOMNode(component), which should be used in place of component.getDOMNode(). The base class for ES6-based components will not have getDOMNode. This change will enable some more patterns moving forward.
    • -
    • New ref style, allowing a callback to be used in place of a name: <Photo ref={(c) => this._photo = c} /> allows you to reference the component with this._photo (as opposed to ref="photo" which gives this.refs.photo)
    • -
    • this.setState() can now take a function as the first argument for transactional state updates, such as this.setState((state, props) => ({count: state.count + 1})); -- this means that you no longer need to use this._pendingState, which is now gone.
    • -
    • Support for iterators and immutable-js sequences as children
    • -
    - -

    Deprecations

    - -
      -
    • ComponentClass.type is deprecated. Just use ComponentClass (usually as element.type === ComponentClass)
    • -
    • Some methods that are available on createClass-based components are removed or deprecated from ES6 classes (for example, getDOMNode, setProps, replaceState).
    • -
    - -

    React with Add-Ons

    - -

    Deprecations

    - -
      -
    • React.addons.classSet is now deprecated. This functionality can be replaced with several freely available modules. classnames is one such module.
    • -
    - -

    React Tools

    - -

    Breaking Changes

    - -
      -
    • When transforming ES6 syntax, class methods are no longer enumerable by default, which requires Object.defineProperty; if you support browsers such as IE8, you can pass --target es3 to mirror the old behavior
    • -
    - -

    New Features

    - -
      -
    • --target option is available on the jsx command, allowing users to specify and ECMAScript version to target. - -
        -
      • es5 is the default.
      • -
      • es3 restored the previous default behavior. An additional transform is added here to ensure the use of reserved words as properties is safe (eg this.static will become this['static'] for IE8 compatibility).
      • -
    • -
    • The transform for the call spread operator has also been enabled.
    • -
    - -

    JSX

    - -

    Breaking Changes

    - -
      -
    • A change was made to how some JSX was parsed, specifically around the use of > or } when inside an element. Previously it would be treated as a string but now it will be treated as a parse error. We will be releasing a standalone executable to find and fix potential issues in your JSX code.
    • -
    - -
    - - -

    diff --git a/community/conferences.html b/community/conferences.html index 66ae12e108..acdda3b41a 100644 --- a/community/conferences.html +++ b/community/conferences.html @@ -63,7 +63,7 @@ @@ -82,12 +82,6 @@

    Upcoming Conferences

    -

    React Conf 2017

    - -

    March 13-14 in Santa Clara, CA

    - -

    Website

    -

    React London 2017

    March 28th at the QEII Centre, London

    @@ -112,6 +106,12 @@

    Website - Twitter

    +

    React Rally

    + +

    August 24-25 in Salt Lake City, Utah USA

    + +

    Website - Twitter

    +

    ReactJS Day 2017

    October 6th in Verona, Italy

    @@ -126,7 +126,7 @@

    React Native EU 2017

    -

    Fall 2017, Poland

    +

    September 6-7 in Wroclaw, Poland

    Website

    @@ -206,6 +206,12 @@

    Website

    +

    React Conf 2017

    + +

    March 13-14 in Santa Clara, CA

    + +

    Website

    +
    diff --git a/community/support.html b/community/support.html index b4fc9504d8..791650fd86 100644 --- a/community/support.html +++ b/community/support.html @@ -63,7 +63,7 @@
    diff --git a/community/videos.html b/community/videos.html index 5ae38d720b..3b179744c3 100644 --- a/community/videos.html +++ b/community/videos.html @@ -63,7 +63,7 @@ diff --git a/contributing/codebase-overview.html b/contributing/codebase-overview.html index 4c2743da8c..59c9ed375f 100644 --- a/contributing/codebase-overview.html +++ b/contributing/codebase-overview.html @@ -63,7 +63,7 @@ @@ -443,12 +443,6 @@ You can run npm run flow locally to check your code with Flow.

    There is a video with a deep code dive into it (66 mins).

    -

    Add-ons

    - -

    Each of the React add-ons ships as a separate package on npm with a react-addons- prefix. Their source is located in src/addons with the exception of ReactPerf and ReactTestUtils.

    - -

    Additionally, we provide a standalone build called react-with-addons.js which includes React core and all add-ons exposed on the addons field of the React global object.

    -

    What Next?

    Read the next section to learn about the current implementation of reconciler in more detail.

    @@ -548,11 +542,6 @@ You can run npm run flow locally to check your code with Flow.

    -
  • - Typechecking With PropTypes - -
  • -
  • Refs and the DOM @@ -638,47 +627,6 @@ You can run npm run flow locally to check your code with Flow.

  • -
  • - Add-Ons - - - -
  • - diff --git a/contributing/design-principles.html b/contributing/design-principles.html index d3578b4c0e..5527af0adc 100644 --- a/contributing/design-principles.html +++ b/contributing/design-principles.html @@ -63,7 +63,7 @@ @@ -90,7 +90,7 @@

    For example, it should be possible to introduce some local state into a component without changing any of the components using it. Similarly, it should be possible to add some initialization and teardown code to any component when necessary.

    -

    There is nothing "bad" about using state or lifecycle hooks in components. Like any powerful features, they should be used in moderation, but we have no intention to remove them. On the contrary, we think they are integral parts of what makes React useful. We might enable more functional patterns in the future, but both local state and lifecycle hooks will be a part of that model.

    +

    There is nothing "bad" about using state or lifecycle hooks in components. Like any powerful feature, they should be used in moderation, but we have no intention to remove them. On the contrary, we think they are integral parts of what makes React useful. We might enable more functional patterns in the future, but both local state and lifecycle hooks will be a part of that model.

    Components are often described as "just functions" but in our view they need to be more than that to be useful. In React, components describe any composable behavior, and this includes rendering, lifecycle, and state. Some external libraries like Relay augment components with other responsibilities such as describing data dependencies. It is possible that those ideas might make it back into React too in some form.

    @@ -323,11 +323,6 @@ -
  • - Typechecking With PropTypes - -
  • -
  • Refs and the DOM @@ -413,47 +408,6 @@
  • -
  • - Add-Ons - - - -
  • - diff --git a/contributing/how-to-contribute.html b/contributing/how-to-contribute.html index 7df78df8fd..30f80a9971 100644 --- a/contributing/how-to-contribute.html +++ b/contributing/how-to-contribute.html @@ -63,7 +63,7 @@ @@ -151,6 +151,7 @@
  • If you've changed APIs, update the documentation.
  • Ensure the test suite passes (npm test).
  • Make sure your code lints (npm run lint).
  • +
  • Format your code with prettier (npm run prettier).
  • Run the Flow typechecks (npm run flow).
  • If you added or removed any tests, run ./scripts/fiber/record-tests before submitting the pull request, and commit the resulting changes.
  • If you haven't already, complete the CLA.
  • @@ -189,9 +190,9 @@ Then, you can run several commands:

    First, run npm run build. This will produce pre-built bundles in build folder, as well as prepare npm packages inside build/packages.

    -

    The easiest way to try your changes is to open and modify examples/basic/index.html. This file already uses react.js from the build folder so it will pick up your changes. Please make sure to rollback any unintentional changes in examples before sending a pull request.

    +

    The easiest way to try your changes is to run npm run build and then open fixtures/packaging/babel-standalone/dev.html. This file already uses react.js from the build folder so it will pick up your changes.

    -

    If you want to try your changes in your existing React project, you may copy build/react.js, build/react-dom.js, or any other build products into your app and use them instead of the stable version. If your project uses React from npm, you may delete react and react-dom in its dependencies and use npm link to point them to your local build folder:

    +

    If you want to try your changes in your existing React project, you may copy build/dist/react.development.js, build/dist/react-dom.development.js, or any other build products into your app and use them instead of the stable version. If your project uses React from npm, you may delete react and react-dom in its dependencies and use npm link to point them to your local build folder:

    cd your_project
     npm link ~/path_to_your_react_clone/build/packages/react
     npm link ~/path_to_your_react_clone/build/packages/react-dom
    @@ -329,11 +330,6 @@ You can check the status of your code styling by simply running npm run li
                 
               
             
    -          
  • - Typechecking With PropTypes - -
  • -
  • Refs and the DOM @@ -419,47 +415,6 @@ You can check the status of your code styling by simply running npm run li
  • -
  • - Add-Ons - - - -
  • -
    diff --git a/contributing/implementation-notes.html b/contributing/implementation-notes.html index 8f5e658103..c5ff83b39e 100644 --- a/contributing/implementation-notes.html +++ b/contributing/implementation-notes.html @@ -63,7 +63,7 @@ @@ -451,7 +451,7 @@
  • All the child internal instances. Each of them can be either a DOMComponent or a CompositeComponent.
  • -

    If you're struggling to imagine what how an internal instance tree is structured in more complex applications, React DevTools can give you a close approximation, as it highlights host instances with grey, and composite instances with purple:

    +

    If you're struggling to imagine how an internal instance tree is structured in more complex applications, React DevTools can give you a close approximation, as it highlights host instances with grey, and composite instances with purple:

    React DevTools tree

    @@ -868,7 +868,7 @@
  • ReactDOMComponent is the equivalent of DOMComponent in this tutorial. It implements the host component class for React DOM renderer. ReactNativeBaseComponent is its React Native analog.
  • ReactCompositeComponent is the equivalent of CompositeComponent in this tutorial. It handles calling user-defined components and maintaining their state.
  • instantiateReactComponent contains the switch that picks the right internal instance class to construct for an element. It is equivalent to instantiateComponent() in this tutorial.

  • -
  • ReactReconciler is a wrapper with mountComponent, receiveComponent(), and unmountComponent() methods. It calls the underlying implementations on the internal instances, but also includes some code around them that is shared by all internal instance implementations.

  • +
  • ReactReconciler is a wrapper with mountComponent(), receiveComponent(), and unmountComponent() methods. It calls the underlying implementations on the internal instances, but also includes some code around them that is shared by all internal instance implementations.

  • ReactChildReconciler implements the logic for mounting, updating, and unmounting children according to the key of their elements.

  • ReactMultiChild implements processing the operation queue for child insertions, deletions, and moves independently of the renderer.

  • mount(), receive(), and unmount() are really called mountComponent(), receiveComponent(), and unmountComponent() in React codebase for legacy reasons, but they receive elements.

  • @@ -978,11 +978,6 @@ -
  • - Typechecking With PropTypes - -
  • -
  • Refs and the DOM @@ -1068,47 +1063,6 @@
  • -
  • - Add-Ons - - - -
  • - diff --git a/docs/addons.html b/docs/addons.html index f6309df2c1..8dc45be733 100644 --- a/docs/addons.html +++ b/docs/addons.html @@ -63,7 +63,7 @@ @@ -78,10 +78,14 @@
    -

    The React add-ons are a collection of useful utility modules for building React apps. These should be considered experimental and tend to change more often than the core.

    +
    +

    Note: +React.addons is deprecated as of React v15.5. The add-ons have now all either been deprecated or moved to separate modules.

    +
    + +

    The React add-ons are a collection of useful utility modules for building React apps. These should be considered experimental and tend to change more often than the core.

    @@ -104,13 +108,16 @@

    Deprecated Add-ons

    -

    LinkedStateMixin has been deprecated.

    +

    Using React with Add-ons

    -

    If using npm, you can install the add-ons individually from npm (e.g. npm install react-addons-test-utils) and import them:

    -
    import Perf from 'react-addons-perf'; // ES6
    -var Perf = require('react-addons-perf'); // ES5 with npm
    +

    You can install the add-ons individually from npm (e.g. npm install react-addons-create-fragment) and import them:

    +
    import createFragment from 'react-addons-create-fragment'; // ES6
    +var createFragment = require('react-addons-create-fragment'); // ES5 with npm
     

    When using a CDN, you can use react-with-addons.js instead of react.js:

    <script src="https://unpkg.com/react@15/dist/react-with-addons.js"></script>
    @@ -208,11 +215,6 @@
                 
               
             
    -          
  • - Typechecking With PropTypes - -
  • -
  • Refs and the DOM @@ -298,47 +300,6 @@
  • -
  • - Add-Ons - - - -
  • -
    diff --git a/docs/animation.html b/docs/animation.html index 4f145a6945..6cfd877638 100644 --- a/docs/animation.html +++ b/docs/animation.html @@ -63,7 +63,7 @@
    @@ -78,16 +78,20 @@
    -

    The ReactTransitionGroup add-on component is a low-level API for animation, and ReactCSSTransitionGroup is an add-on component for easily implementing basic CSS animations and transitions.

    +
    +

    Note: +ReactTransitionGroup and ReactCSSTransitionGroup are both deprecated as of React v15.5.0. The recommendation is to use TransitionGroup and CSSTransitionGroup from 'react-transition-group' instead.

    +
    + +

    The ReactTransitionGroup add-on component is a low-level API for animation, and ReactCSSTransitionGroup is an add-on component for easily implementing basic CSS animations and transitions.

    High-level API: ReactCSSTransitionGroup

    ReactCSSTransitionGroup is a high-level API based on ReactTransitionGroup and is an easy way to perform CSS transitions and animations when a React component enters or leaves the DOM. It's inspired by the excellent ng-animate library.

    Importing

    -
    import ReactCSSTransitionGroup from 'react-addons-css-transition-group' // ES6
    -var ReactCSSTransitionGroup = require('react-addons-css-transition-group') // ES5 with npm
    -var ReactCSSTransitionGroup = React.addons.CSSTransitionGroup; // ES5 with react-with-addons.js
    +
    import ReactCSSTransitionGroup from 'react-addons-css-transition-group'; // ES6
    +var ReactCSSTransitionGroup = require('react-addons-css-transition-group'); // ES5 with npm
     
    class TodoList extends React.Component {
       constructor(props) {
         super(props);
    @@ -277,7 +281,6 @@
     

    Importing

    import ReactTransitionGroup from 'react-addons-transition-group' // ES6
     var ReactTransitionGroup = require('react-addons-transition-group') // ES5 with npm
    -var ReactTransitionGroup = React.addons.TransitionGroup; // ES5 with react-with-addons.js
     

    ReactTransitionGroup is the basis for animations. When children are declaratively added or removed from it (as in the example above), special lifecycle hooks are called on them.

    @@ -368,10 +371,6 @@
    - ← Prev - - - Next →
    @@ -460,11 +459,6 @@ -
  • - Typechecking With PropTypes - -
  • -
  • Refs and the DOM @@ -550,47 +544,6 @@
  • -
  • - Add-Ons - - - -
  • -
    diff --git a/docs/components-and-props.html b/docs/components-and-props.html index 0c1313aca5..64bda48037 100644 --- a/docs/components-and-props.html +++ b/docs/components-and-props.html @@ -63,7 +63,7 @@ @@ -389,11 +389,6 @@ -
  • - Typechecking With PropTypes - -
  • -
  • Refs and the DOM @@ -479,47 +474,6 @@
  • -
  • - Add-Ons - - - -
  • - diff --git a/docs/composition-vs-inheritance.html b/docs/composition-vs-inheritance.html index 5ce640971a..4b6692da0e 100644 --- a/docs/composition-vs-inheritance.html +++ b/docs/composition-vs-inheritance.html @@ -63,7 +63,7 @@ @@ -321,11 +321,6 @@ -
  • - Typechecking With PropTypes - -
  • -
  • Refs and the DOM @@ -411,47 +406,6 @@
  • -
  • - Add-Ons - - - -
  • - diff --git a/docs/conditional-rendering.html b/docs/conditional-rendering.html index 07e2b34afa..d7f1d637db 100644 --- a/docs/conditional-rendering.html +++ b/docs/conditional-rendering.html @@ -63,7 +63,7 @@ @@ -383,11 +383,6 @@ -
  • - Typechecking With PropTypes - -
  • -
  • Refs and the DOM @@ -473,47 +468,6 @@
  • -
  • - Add-Ons - - - -
  • - diff --git a/docs/conferences-it-IT.html b/docs/conferences-it-IT.html index a3b698bc5b..ba4347405b 100644 --- a/docs/conferences-it-IT.html +++ b/docs/conferences-it-IT.html @@ -63,7 +63,7 @@ diff --git a/docs/conferences-ko-KR.html b/docs/conferences-ko-KR.html index 4fa180ee82..df9772c193 100644 --- a/docs/conferences-ko-KR.html +++ b/docs/conferences-ko-KR.html @@ -63,7 +63,7 @@ diff --git a/docs/conferences-zh-CN.html b/docs/conferences-zh-CN.html index 1ae736b8e6..8acd802ab7 100644 --- a/docs/conferences-zh-CN.html +++ b/docs/conferences-zh-CN.html @@ -63,7 +63,7 @@ diff --git a/docs/context.html b/docs/context.html index 86ae4c0855..664c3a124a 100644 --- a/docs/context.html +++ b/docs/context.html @@ -63,7 +63,7 @@ @@ -78,7 +78,12 @@
    -

    With React, it's easy to track the flow of data through your React components. When you look at a component, you can see which props are being passed, which makes your apps easy to reason about.

    +
    +

    Note: +As of React v15.5 the React.PropTypes helper is deprecated, and we recommend using the prop-types library to define contextTypes.

    +
    + +

    With React, it's easy to track the flow of data through your React components. When you look at a component, you can see which props are being passed, which makes your apps easy to reason about.

    In some cases, you want to pass data through the component tree without having to pass the props down manually at every level. You can do this directly in React with the powerful "context" API.

    @@ -129,7 +134,9 @@ You can do this directly in React with the powerful "context" API.

    }

    In this example, we manually thread through a color prop in order to style the Button and Message components appropriately. Using context, we can pass this through the tree automatically:

    -
    class Button extends React.Component {
    +
    const PropTypes = require('prop-types');
    +
    +class Button extends React.Component {
       render() {
         return (
           <button style={{background: this.context.color}}>
    @@ -140,7 +147,7 @@ You can do this directly in React with the powerful "context" API.

    } Button.contextTypes = { - color: React.PropTypes.string + color: PropTypes.string }; class Message extends React.Component { @@ -167,7 +174,7 @@ You can do this directly in React with the powerful "context" API.

    } MessageList.childContextTypes = { - color: React.PropTypes.string + color: PropTypes.string };

    By adding childContextTypes and getChildContext to MessageList (the context provider), React passes the information down automatically and any component in the subtree (in this case, Button) can access it by defining contextTypes.

    @@ -177,7 +184,7 @@ You can do this directly in React with the powerful "context" API.

    Parent-Child Coupling

    Context can also let you build an API where parents and children communicate. For example, one library that works this way is React Router V4:

    -
    import { Router, Route, Link } from 'react-router-dom';
    +
    import { BrowserRouter as Router, Route, Link } from 'react-router-dom';
     
     const BasicExample = () => (
       <Router>
    @@ -216,12 +223,14 @@ You can do this directly in React with the powerful "context" API.

    Referencing Context in Stateless Functional Components

    Stateless functional components are also able to reference context if contextTypes is defined as a property of the function. The following code shows a Button component written as a stateless functional component.

    -
    const Button = ({children}, context) =>
    +
    const PropTypes = require('prop-types');
    +
    +const Button = ({children}, context) =>
       <button style={{background: context.color}}>
         {children}
       </button>;
     
    -Button.contextTypes = {color: React.PropTypes.string};
    +Button.contextTypes = {color: PropTypes.string};
     

    Updating Context

    @@ -230,7 +239,9 @@ You can do this directly in React with the powerful "context" API.

    React has an API to update context, but it is fundamentally broken and you should not use it.

    The getChildContext function will be called when the state or props changes. In order to update data in the context, trigger a local state update with this.setState. This will trigger a new context and changes will be received by the children.

    -
    class MediaQuery extends React.Component {
    +
    const PropTypes = require('prop-types');
    +
    +class MediaQuery extends React.Component {
       constructor(props) {
         super(props);
         this.state = {type:'desktop'};
    @@ -258,7 +269,7 @@ You can do this directly in React with the powerful "context" API.

    } MediaQuery.childContextTypes = { - type: React.PropTypes.string + type: PropTypes.string };

    The problem is, if a context value provided by component changes, descendants that use that value won't update if an intermediate parent returns false from shouldComponentUpdate. This is totally out of control of the components using context, so there's basically no way to reliably update the context. This blog post has a good explanation of why this is a problem and how you might get around it.

    @@ -354,11 +365,6 @@ You can do this directly in React with the powerful "context" API.

    -
  • - Typechecking With PropTypes - -
  • -
  • Refs and the DOM @@ -444,47 +450,6 @@ You can do this directly in React with the powerful "context" API.

  • -
  • - Add-Ons - - - -
  • -
    diff --git a/docs/create-fragment.html b/docs/create-fragment.html index 9b2af99c03..a7c9ef5fc3 100644 --- a/docs/create-fragment.html +++ b/docs/create-fragment.html @@ -63,7 +63,7 @@
    @@ -79,9 +79,8 @@

    Importing

    -
    import createFragment from 'react-addons-create-fragment' // ES6
    -var createFragment = require('react-addons-create-fragment') // ES5 with npm
    -var createFragment = React.addons.createFragment; // ES5 with react-with-addons.js
    +
    import createFragment from 'react-addons-create-fragment'; // ES6
    +var createFragment = require('react-addons-create-fragment'); // ES5 with npm
     

    Overview

    @@ -105,7 +104,7 @@

    Array<ReactNode> createFragment(object children)

    Instead of creating arrays, we write:

    -
    import createFragment from 'react-addons-create-fragment'
    +
    import createFragment from 'react-addons-create-fragment';
     
     function Swapper(props) {
       let children;
    @@ -130,10 +129,6 @@
     
         
    - ← Prev - - - Next →
    @@ -222,11 +217,6 @@ -
  • - Typechecking With PropTypes - -
  • -
  • Refs and the DOM @@ -312,47 +302,6 @@
  • -
  • - Add-Ons - - - -
  • -
    diff --git a/docs/dom-elements.html b/docs/dom-elements.html index 92a82fde03..58c493c530 100644 --- a/docs/dom-elements.html +++ b/docs/dom-elements.html @@ -63,7 +63,7 @@
    @@ -311,11 +311,6 @@ xmlLang xmlSpace y y1 y2 yChannelSelector z zoomAndPan -
  • - Typechecking With PropTypes - -
  • -
  • Refs and the DOM @@ -401,47 +396,6 @@ xmlLang xmlSpace y y1 y2 yChannelSelector z zoomAndPan
  • -
  • - Add-Ons - - - -
  • -
    diff --git a/docs/error-decoder.html b/docs/error-decoder.html index cc65f7b816..8ed92c5560 100644 --- a/docs/error-decoder.html +++ b/docs/error-decoder.html @@ -63,7 +63,7 @@ @@ -179,11 +179,6 @@ -
  • - Typechecking With PropTypes - -
  • -
  • Refs and the DOM @@ -269,47 +264,6 @@
  • -
  • - Add-Ons - - - -
  • - diff --git a/docs/events.html b/docs/events.html index b159517334..458e080f28 100644 --- a/docs/events.html +++ b/docs/events.html @@ -63,7 +63,7 @@ @@ -428,11 +428,6 @@ onTimeUpdate onVolumeChange onWaiting -
  • - Typechecking With PropTypes - -
  • -
  • Refs and the DOM @@ -518,47 +513,6 @@ onTimeUpdate onVolumeChange onWaiting
  • -
  • - Add-Ons - - - -
  • - diff --git a/docs/forms.html b/docs/forms.html index 18b6f20abb..cf8fb13cc7 100644 --- a/docs/forms.html +++ b/docs/forms.html @@ -63,7 +63,7 @@ @@ -394,11 +394,6 @@ -
  • - Typechecking With PropTypes - -
  • -
  • Refs and the DOM @@ -484,47 +479,6 @@
  • -
  • - Add-Ons - - - -
  • - diff --git a/docs/handling-events.html b/docs/handling-events.html index acb9587a7c..6481338da9 100644 --- a/docs/handling-events.html +++ b/docs/handling-events.html @@ -63,7 +63,7 @@ @@ -286,11 +286,6 @@ -
  • - Typechecking With PropTypes - -
  • -
  • Refs and the DOM @@ -376,47 +371,6 @@
  • -
  • - Add-Ons - - - -
  • - diff --git a/docs/hello-world.html b/docs/hello-world.html index 15e14081dd..9342d13857 100644 --- a/docs/hello-world.html +++ b/docs/hello-world.html @@ -63,7 +63,7 @@ @@ -191,11 +191,6 @@ -
  • - Typechecking With PropTypes - -
  • -
  • Refs and the DOM @@ -281,47 +276,6 @@
  • -
  • - Add-Ons - - - -
  • - diff --git a/docs/higher-order-components.html b/docs/higher-order-components.html index 25f1240d74..0928a41d76 100644 --- a/docs/higher-order-components.html +++ b/docs/higher-order-components.html @@ -63,7 +63,7 @@ @@ -531,11 +531,6 @@ -
  • - Typechecking With PropTypes - -
  • -
  • Refs and the DOM @@ -621,47 +616,6 @@
  • -
  • - Add-Ons - - - -
  • - diff --git a/docs/installation.html b/docs/installation.html index daf03bb7bd..637f59614d 100644 --- a/docs/installation.html +++ b/docs/installation.html @@ -63,7 +63,7 @@ @@ -278,11 +278,6 @@ npm install --save react react-dom -
  • - Typechecking With PropTypes - -
  • -
  • Refs and the DOM @@ -368,47 +363,6 @@ npm install --save react react-dom
  • -
  • - Add-Ons - - - -
  • - diff --git a/docs/introducing-jsx.html b/docs/introducing-jsx.html index d392447f80..f61a5031cb 100644 --- a/docs/introducing-jsx.html +++ b/docs/introducing-jsx.html @@ -63,7 +63,7 @@ @@ -299,11 +299,6 @@ -
  • - Typechecking With PropTypes - -
  • -
  • Refs and the DOM @@ -389,47 +384,6 @@
  • -
  • - Add-Ons - - - -
  • - diff --git a/docs/jsx-in-depth.html b/docs/jsx-in-depth.html index 839d28a653..98c25b6c95 100644 --- a/docs/jsx-in-depth.html +++ b/docs/jsx-in-depth.html @@ -63,7 +63,7 @@ @@ -489,11 +489,6 @@ -
  • - Typechecking With PropTypes - -
  • -
  • Refs and the DOM @@ -579,47 +574,6 @@
  • -
  • - Add-Ons - - - -
  • - diff --git a/docs/lifting-state-up.html b/docs/lifting-state-up.html index c3fe6d2cfe..9b68362fad 100644 --- a/docs/lifting-state-up.html +++ b/docs/lifting-state-up.html @@ -63,7 +63,7 @@ @@ -449,11 +449,6 @@ -
  • - Typechecking With PropTypes - -
  • -
  • Refs and the DOM @@ -539,47 +534,6 @@
  • -
  • - Add-Ons - - - -
  • - diff --git a/docs/lists-and-keys.html b/docs/lists-and-keys.html index 39da39a23c..742b6180d2 100644 --- a/docs/lists-and-keys.html +++ b/docs/lists-and-keys.html @@ -63,7 +63,7 @@ @@ -423,11 +423,6 @@ -
  • - Typechecking With PropTypes - -
  • -
  • Refs and the DOM @@ -513,47 +508,6 @@
  • -
  • - Add-Ons - - - -
  • - diff --git a/docs/optimizing-performance.html b/docs/optimizing-performance.html index 5b8b3fc865..777abe06b4 100644 --- a/docs/optimizing-performance.html +++ b/docs/optimizing-performance.html @@ -63,7 +63,7 @@ @@ -289,14 +289,14 @@

    Immutability makes tracking changes cheap. A change will always result in a new object so we only need to check if the reference to the object has changed. For example, in this regular JavaScript code:

    -
    const x = { foo: "bar" };
    +
    const x = { foo: 'bar' };
     const y = x;
    -y.foo = "baz";
    +y.foo = 'baz';
     x === y; // true
     

    Although y was edited, since it's a reference to the same object as x, this comparison returns true. You can write similar code with immutable.js:

    const SomeRecord = Immutable.Record({ foo: null });
    -const x = new SomeRecord({ foo: 'bar'  });
    +const x = new SomeRecord({ foo: 'bar' });
     const y = x.set('foo', 'baz');
     x === y; // false
     
    @@ -397,11 +397,6 @@ -
  • - Typechecking With PropTypes - -
  • -
  • Refs and the DOM @@ -487,47 +482,6 @@
  • -
  • - Add-Ons - - - -
  • -
    diff --git a/docs/perf.html b/docs/perf.html index 4dbf82dc6e..41e3615db4 100644 --- a/docs/perf.html +++ b/docs/perf.html @@ -63,7 +63,7 @@ @@ -79,9 +79,8 @@

    Importing

    -
    import Perf from 'react-addons-perf' // ES6
    -var Perf = require('react-addons-perf') // ES5 with npm
    -var Perf = React.addons.Perf; // ES5 with react-with-addons.js
    +
    import Perf from 'react-addons-perf'; // ES6
    +var Perf = require('react-addons-perf'); // ES5 with npm
     

    Overview

    @@ -203,10 +202,6 @@
    - ← Prev - - - Next →
    @@ -295,11 +290,6 @@ -
  • - Typechecking With PropTypes - -
  • -
  • Refs and the DOM @@ -385,47 +375,6 @@
  • -
  • - Add-Ons - - - -
  • - diff --git a/docs/pure-render-mixin.html b/docs/pure-render-mixin.html index 5dcd57c3a5..1f07021226 100644 --- a/docs/pure-render-mixin.html +++ b/docs/pure-render-mixin.html @@ -63,7 +63,7 @@ @@ -88,7 +88,8 @@

    Example:

    var PureRenderMixin = require('react-addons-pure-render-mixin');
    -React.createClass({
    +var createReactClass = require('create-react-class');
    +createReactClass({
       mixins: [PureRenderMixin],
     
       render: function() {
    @@ -210,11 +211,6 @@
                 
               
             
    -          
  • - Typechecking With PropTypes - -
  • -
  • Refs and the DOM @@ -300,47 +296,6 @@
  • -
  • - Add-Ons - - - -
  • -
    diff --git a/docs/react-api.html b/docs/react-api.html index 1d2ee40f23..6be63aac89 100644 --- a/docs/react-api.html +++ b/docs/react-api.html @@ -63,7 +63,7 @@ @@ -91,11 +91,7 @@
  • React.PureComponent
  • -

    If you don't use ES6 classes, you may use this helper instead.

    - - +

    If you don't use ES6 classes, you may use the create-react-class module instead. See Using React without ES6 for more information.

    Creating React Elements

    @@ -118,44 +114,6 @@
  • React.Children
  • -

    Typechecking with PropTypes

    - -

    You can use React.PropTypes to run typechecking on the props for a component.

    - - - -

    Validators treat props as optional by default. You can use isRequired to make sure a warning is shown if the prop is not provided.

    - - - -

    Add-Ons

    - -

    If you're using react-with-addons.js, the React Add-Ons will be available via React.addons.

    - - -

    Reference

    @@ -189,20 +147,6 @@
    -

    createClass()

    -
    React.createClass(specification)
    -
    -

    If you don't use ES6 yet, you may use the React.createClass() helper instead to create a component class.

    -
    var Greeting = React.createClass({
    -  render: function() {
    -    return <h1>Hello, {this.props.name}</h1>;
    -  }
    -});
    -
    -

    See Using React without ES6 for more information.

    - -
    -

    createElement()

    React.createElement(
       type,
    @@ -289,134 +233,6 @@
     

    React.Children.toArray() changes keys to preserve the semantics of nested arrays when flattening lists of children. That is, toArray prefixes each key in the returned array so that each element's key is scoped to the input array containing it.

    -
    - -

    React.PropTypes

    - -

    React.PropTypes exports a range of validators that can be used with a component's propTypes object to validate props being passed to your components.

    - -

    For more information about PropTypes, see Typechecking with PropTypes.

    - -

    React.PropTypes.array

    -
    React.PropTypes.array
    -
    -

    Validates that a prop is a JavaScript array primitive.

    - -

    React.PropTypes.bool

    -
    React.PropTypes.bool
    -
    -

    Validates that a prop is a JavaScript bool primitive.

    - -

    React.PropTypes.func

    -
    React.PropTypes.func
    -
    -

    Validates that a prop is a JavaScript function.

    - -

    React.PropTypes.number

    -
    React.PropTypes.number
    -
    -

    Validates that a prop is a JavaScript number primitive.

    - -

    React.PropTypes.object

    -
    React.PropTypes.object
    -
    -

    Validates that a prop is a JavaScript object.

    - -

    React.PropTypes.string

    -
    React.PropTypes.string
    -
    -

    Validates that a prop is a JavaScript string primitive.

    - -

    React.PropTypes.symbol

    -
    React.PropTypes.symbol
    -
    -

    Validates that a prop is a JavaScript symbol.

    - -

    React.PropTypes.node

    -
    React.PropTypes.node
    -
    -

    Validates that a prop is anything that can be rendered: numbers, strings, elements or an array (or fragment) containing these types.

    - -

    React.PropTypes.element

    -
    React.PropTypes.element
    -
    -

    Validates that a prop is a React element.

    - -

    React.PropTypes.instanceOf()

    -
    React.PropTypes.instanceOf(class)
    -
    -

    Validates that a prop is an instance of a class. This uses JavaScript's instanceof operator.

    - -

    React.PropTypes.oneOf()

    -
    React.PropTypes.oneOf(arrayOfValues)
    -
    -

    Validates that a prop is limited to specific values by treating it as an enum.

    -
    MyComponent.propTypes = {
    -  optionalEnum: React.PropTypes.oneOf(['News', 'Photos']),
    -}
    -
    -

    React.PropTypes.oneOfType()

    -
    React.PropTypes.oneOfType(arrayOfPropTypes)
    -
    -

    Validates that a prop is an object that could be one of many types.

    -
    MyComponent.propTypes = {
    -  optionalUnion: React.PropTypes.oneOfType([
    -    React.PropTypes.string,
    -    React.PropTypes.number,
    -    React.PropTypes.instanceOf(Message)
    -  ]),
    -}
    -
    -

    React.PropTypes.arrayOf()

    -
    React.PropTypes.arrayOf(propType)
    -
    -

    Validates that a prop is an array of a certain type.

    -
    MyComponent.propTypes = {
    -  optionalArrayOf: React.PropTypes.arrayOf(React.PropTypes.number),
    -}
    -
    -

    React.PropTypes.objectOf()

    -
    React.PropTypes.objectOf(propType)
    -
    -

    Validates that a prop is an object with property values of a certain type.

    -
    MyComponent.propTypes = {
    -  optionalObjectOf: React.PropTypes.objectOf(React.PropTypes.number),
    -}
    -
    -

    React.PropTypes.shape()

    -
    React.PropTypes.shape(object)
    -
    -

    Validates that a prop is an object taking on a particular shape.

    -
    MyComponent.propTypes = {
    -  optionalObjectWithShape: React.PropTypes.shape({
    -    color: React.PropTypes.string,
    -    fontSize: React.PropTypes.number
    -  }),
    -}
    -
    -

    React.PropTypes.any

    -
    React.PropTypes.any
    -
    -

    Validates that a prop has a value of any data type. Usually followed by isRequired.

    -
    MyComponent.propTypes = {
    -  requiredAny: React.PropTypes.any.isRequired,
    -}
    -
    -

    isRequired

    -
    propType.isRequired
    -
    -

    You can chain any of the above validators with isRequired to make sure a warning is shown if the prop is not provided.

    -
    MyComponent.propTypes = {
    -  requiredFunc: React.PropTypes.func.isRequired,
    -}
    -
    -
    - -

    React.addons

    -
    React.addons
    -
    -

    React.addons exports a range of add-ons when using react-with-addons.js.

    -
    @@ -508,11 +324,6 @@ -
  • - Typechecking With PropTypes - -
  • -
  • Refs and the DOM @@ -598,47 +409,6 @@
  • -
  • - Add-Ons - - - -
  • -
    diff --git a/docs/react-api.html#typechecking-with-proptypes b/docs/react-api.html#typechecking-with-proptypes new file mode 100644 index 0000000000..7bda937244 --- /dev/null +++ b/docs/react-api.html#typechecking-with-proptypes @@ -0,0 +1,10 @@ + + + +Redirecting… + + +

    Redirecting…

    +Click here if you are not redirected. + + diff --git a/docs/react-component.html b/docs/react-component.html index d01893661f..59fa8c1fa9 100644 --- a/docs/react-component.html +++ b/docs/react-component.html @@ -63,7 +63,7 @@
    @@ -91,7 +91,7 @@ } } -

    If you don't use ES6 yet, you may use the React.createClass helper instead. Take a look at Using React without ES6 to learn more.

    +

    If you don't use ES6 yet, you may use the create-react-class module instead. Take a look at Using React without ES6 to learn more.

    The Component Lifecycle

    @@ -142,7 +142,6 @@

    Instance Properties

    @@ -188,7 +187,7 @@ this.state = { color: props.initialColor }; -} +}

    Beware of this pattern, as it effectively "forks" the props and can lead to bugs. Instead of syncing props to state, you often want to lift the state up.

    @@ -342,23 +341,6 @@
    -

    propTypes

    - -

    propTypes can be defined as a property on the component class itself, to define what types the props should be. It should be a map from prop names to types as defined in React.PropTypes. In development mode, when an invalid value is provided for a prop, a warning will be shown in the JavaScript console. In production mode, propTypes checks are skipped for efficiency.

    - -

    For example, this code ensures that the color prop is a string:

    -
    class CustomButton extends React.Component {
    -  // ...
    -}
    -
    -CustomButton.propTypes = {
    -  color: React.PropTypes.string
    -};
    -
    -

    We recommend using Flow when possible, to get compile-time typechecking instead of runtime typechecking. Flow has built-in support for React so it's easy to run static analysis on a React app.

    - -
    -

    Instance Properties

    props

    @@ -468,11 +450,6 @@ -
  • - Typechecking With PropTypes - -
  • -
  • Refs and the DOM @@ -558,47 +535,6 @@
  • -
  • - Add-Ons - - - -
  • - diff --git a/docs/react-dom-server.html b/docs/react-dom-server.html index 7e1d3aee52..f9f0913dc6 100644 --- a/docs/react-dom-server.html +++ b/docs/react-dom-server.html @@ -63,7 +63,7 @@ @@ -198,11 +198,6 @@ -
  • - Typechecking With PropTypes - -
  • -
  • Refs and the DOM @@ -288,47 +283,6 @@
  • -
  • - Add-Ons - - - -
  • - diff --git a/docs/react-dom.html b/docs/react-dom.html index 055b4687c2..cafb300438 100644 --- a/docs/react-dom.html +++ b/docs/react-dom.html @@ -63,7 +63,7 @@ @@ -244,11 +244,6 @@ and should be avoided because future versions of React may render components asy -
  • - Typechecking With PropTypes - -
  • -
  • Refs and the DOM @@ -334,47 +329,6 @@ and should be avoided because future versions of React may render components asy
  • -
  • - Add-Ons - - - -
  • - diff --git a/docs/react-without-es6.html b/docs/react-without-es6.html index d8fde0bc58..3b99d27c95 100644 --- a/docs/react-without-es6.html +++ b/docs/react-without-es6.html @@ -63,7 +63,7 @@ @@ -85,36 +85,29 @@ } }
    -

    If you don't use ES6 yet, you may use the React.createClass helper instead:

    -
    var Greeting = React.createClass({
    +

    If you don't use ES6 yet, you may use the create-react-class module instead:

    +
    var createReactClass = require('create-react-class');
    +var Greeting = createReactClass({
       render: function() {
         return <h1>Hello, {this.props.name}</h1>;
       }
     });
     
    -

    The API of ES6 classes is similar to React.createClass with a few exceptions.

    +

    The API of ES6 classes is similar to createReactClass() with a few exceptions.

    -

    Declaring Prop Types and Default Props

    +

    Declaring Default Props

    -

    With functions and ES6 classes, propTypes and defaultProps are defined as properties on the components themselves:

    +

    With functions and ES6 classes defaultProps is defined as a property on the component itself:

    class Greeting extends React.Component {
       // ...
     }
     
    -Greeting.propTypes = {
    -  name: React.PropTypes.string
    -};
    -
     Greeting.defaultProps = {
       name: 'Mary'
     };
     
    -

    With React.createClass(), you need to define propTypes as a property on the passed object, and getDefaultProps() as a function on it:

    -
    var Greeting = React.createClass({
    -  propTypes: {
    -    name: React.PropTypes.string
    -  },
    -
    +

    With createReactClass(), you need to define getDefaultProps() as a function on the passed object:

    +
    var Greeting = createReactClass({
       getDefaultProps: function() {
         return {
           name: 'Mary'
    @@ -136,8 +129,8 @@
       // ...
     }
     
    -

    With React.createClass(), you have to provide a separate getInitialState method that returns the initial state:

    -
    var Counter = React.createClass({
    +

    With createReactClass(), you have to provide a separate getInitialState method that returns the initial state:

    +
    var Counter = createReactClass({
       getInitialState: function() {
         return {count: this.props.initialCount};
       },
    @@ -169,8 +162,8 @@
       }
     }
     
    -

    With React.createClass(), this is not necessary because it binds all methods:

    -
    var SayHello = React.createClass({
    +

    With createReactClass(), this is not necessary because it binds all methods:

    +
    var SayHello = createReactClass({
       getInitialState: function() {
         return {message: 'Hello!'};
       },
    @@ -218,7 +211,7 @@
     
    • Bind methods in the constructor.
    • Use arrow functions, e.g. onClick={(e) => this.handleClick(e)}.
    • -
    • Keep using React.createClass().
    • +
    • Keep using createReactClass.

    Mixins

    @@ -233,7 +226,7 @@

    This section exists only for the reference.

    -

    Sometimes very different components may share some common functionality. These are sometimes called cross-cutting concerns. React.createClass lets you use a legacy mixins system for that.

    +

    Sometimes very different components may share some common functionality. These are sometimes called cross-cutting concerns. createReactClass lets you use a legacy mixins system for that.

    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 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.

    var SetIntervalMixin = {
    @@ -248,7 +241,9 @@
       }
     };
     
    -var TickTock = React.createClass({
    +var createReactClass = require('create-react-class');
    +
    +var TickTock = createReactClass({
       mixins: [SetIntervalMixin], // Use the mixin
       getInitialState: function() {
         return {seconds: 0};
    @@ -366,11 +361,6 @@
                 
               
             
    -          
  • - Typechecking With PropTypes - -
  • -
  • Refs and the DOM @@ -456,47 +446,6 @@
  • -
  • - Add-Ons - - - -
  • -
    diff --git a/docs/react-without-jsx.html b/docs/react-without-jsx.html index eec4e024a7..8d015fc597 100644 --- a/docs/react-without-jsx.html +++ b/docs/react-without-jsx.html @@ -63,7 +63,7 @@
    @@ -211,11 +211,6 @@ -
  • - Typechecking With PropTypes - -
  • -
  • Refs and the DOM @@ -301,47 +296,6 @@
  • -
  • - Add-Ons - - - -
  • -
    diff --git a/docs/reconciliation.html b/docs/reconciliation.html index a68feea6b9..7da6ebd29e 100644 --- a/docs/reconciliation.html +++ b/docs/reconciliation.html @@ -63,7 +63,7 @@
    @@ -299,11 +299,6 @@ -
  • - Typechecking With PropTypes - -
  • -
  • Refs and the DOM @@ -389,47 +384,6 @@
  • -
  • - Add-Ons - - - -
  • - diff --git a/docs/refs-and-the-dom.html b/docs/refs-and-the-dom.html index 96649ea47e..c89e52d968 100644 --- a/docs/refs-and-the-dom.html +++ b/docs/refs-and-the-dom.html @@ -63,7 +63,7 @@ @@ -298,11 +298,6 @@ -
  • - Typechecking With PropTypes - -
  • -
  • Refs and the DOM @@ -388,47 +383,6 @@
  • -
  • - Add-Ons - - - -
  • - diff --git a/docs/rendering-elements.html b/docs/rendering-elements.html index 5ef6218d9a..b9d26d7669 100644 --- a/docs/rendering-elements.html +++ b/docs/rendering-elements.html @@ -63,7 +63,7 @@ @@ -252,11 +252,6 @@ -
  • - Typechecking With PropTypes - -
  • -
  • Refs and the DOM @@ -342,47 +337,6 @@
  • -
  • - Add-Ons - - - -
  • - diff --git a/docs/shallow-compare.html b/docs/shallow-compare.html index ad0df3ac22..9e89767e65 100644 --- a/docs/shallow-compare.html +++ b/docs/shallow-compare.html @@ -63,7 +63,7 @@ @@ -84,9 +84,8 @@

    Importing

    -
    import shallowCompare from 'react-addons-shallow-compare' // ES6
    -var shallowCompare = require('react-addons-shallow-compare') // ES5 with npm
    -var shallowCompare = React.addons.shallowCompare; // ES5 with react-with-addons.js
    +
    import shallowCompare from 'react-addons-shallow-compare'; // ES6
    +var shallowCompare = require('react-addons-shallow-compare'); // ES5 with npm
     

    Overview

    @@ -202,11 +201,6 @@ It does this by iterating on the keys of the objects being compared and returnin -
  • - Typechecking With PropTypes - -
  • -
  • Refs and the DOM @@ -292,47 +286,6 @@ It does this by iterating on the keys of the objects being compared and returnin
  • -
  • - Add-Ons - - - -
  • -
    diff --git a/docs/shallow-renderer.html b/docs/shallow-renderer.html new file mode 100644 index 0000000000..946980f734 --- /dev/null +++ b/docs/shallow-renderer.html @@ -0,0 +1,410 @@ + + + + + + + + + Shallow Renderer - React + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + +
    +
    + Edit on GitHub +

    + Shallow Renderer +

    +
    + +

    Importing

    +
    import ReactShallowRenderer from 'react-test-renderer/shallow'; // ES6
    +var ReactShallowRenderer = require('react-test-renderer/shallow'); // ES5 with npm
    +
    +

    Shallow Rendering

    + +

    Shallow rendering lets you render a component "one level deep" and assert facts about what its render method returns, without worrying about the behavior of child components, which are not instantiated or rendered. This does not require a DOM.

    + + + +

    You can think of the shallowRenderer as a "place" to render the component you're testing, and from which you can extract the component's output.

    + +

    shallowRenderer.render() is similar to ReactDOM.render() but it doesn't require DOM and only renders a single level deep. This means you can test components isolated from how their children are implemented.

    + +

    After shallowRenderer.render() has been called, you can use shallowRenderer.getRenderOutput() to get the shallowly rendered output.

    + +

    You can then begin to assert facts about the output. For example, if you have the following component:

    +
    function MyComponent() {
    +  return (
    +    <div>
    +      <span className="heading">Title</span>
    +      <Subcomponent foo="bar" />
    +    </div>
    +  );
    +}
    +
    +

    Then you can assert:

    +
    const ReactShallowRenderer = require('react-test-renderer/shallow');
    +const shallowRenderer = new ReactShallowRenderer();
    +shallowRenderer.render(<MyComponent />);
    +const result = shallowRenderer.getRenderOutput();
    +
    +expect(result.type).toBe('div');
    +expect(result.props.children).toEqual([
    +  <span className="heading">Title</span>,
    +  <Subcomponent foo="bar" />
    +]);
    +
    +

    Shallow testing currently has some limitations, namely not supporting refs.

    + +

    We also recommend checking out Enzyme's Shallow Rendering API. It provides a nicer higher-level API over the same functionality.

    + +
    + + +
    + + +
    +
    + + + +
    + + + + +
    + +
    + + + + diff --git a/docs/state-and-lifecycle.html b/docs/state-and-lifecycle.html index 84f40a0c14..cc2f13a2b8 100644 --- a/docs/state-and-lifecycle.html +++ b/docs/state-and-lifecycle.html @@ -63,7 +63,7 @@ @@ -563,11 +563,6 @@ -
  • - Typechecking With PropTypes - -
  • -
  • Refs and the DOM @@ -653,47 +648,6 @@
  • -
  • - Add-Ons - - - -
  • - diff --git a/docs/test-utils.html b/docs/test-utils.html index 9d60e27f66..267854f325 100644 --- a/docs/test-utils.html +++ b/docs/test-utils.html @@ -63,7 +63,7 @@ @@ -79,9 +79,8 @@

    Importing

    -
    import ReactTestUtils from 'react-addons-test-utils' // ES6
    -var ReactTestUtils = require('react-addons-test-utils') // ES5 with npm
    -var ReactTestUtils = React.addons.TestUtils; // ES5 with react-with-addons.js
    +
    import ReactTestUtils from 'react-dom/test-utils'; // ES6
    +var ReactTestUtils = require('react-dom/test-utils'); // ES5 with npm
     

    Overview

    @@ -111,49 +110,6 @@
  • findRenderedComponentWithType()
  • -

    Shallow Rendering

    - -

    Shallow rendering lets you render a component "one level deep" and assert facts about what its render method returns, without worrying about the behavior of child components, which are not instantiated or rendered. This does not require a DOM.

    - - - -

    Call createRenderer() in your tests to create a shallow renderer. You can think of this as a "place" to render the component you're testing, and from which you can extract the component's output.

    - -

    shallowRenderer.render() is similar to ReactDOM.render() but it doesn't require DOM and only renders a single level deep. This means you can test components isolated from how their children are implemented.

    - -

    After shallowRenderer.render() has been called, you can use shallowRenderer.getRenderOutput() to get the shallowly rendered output.

    - -

    You can then begin to assert facts about the output. For example, if you have the following component:

    -
    function MyComponent() {
    -  return (
    -    <div>
    -      <span className="heading">Title</span>
    -      <Subcomponent foo="bar" />
    -    </div>
    -  );
    -}
    -
    -

    Then you can assert:

    -
    const renderer = ReactTestUtils.createRenderer();
    -renderer.render(<MyComponent />);
    -const result = renderer.getRenderOutput();
    -
    -expect(result.type).toBe('div');
    -expect(result.props.children).toEqual([
    -  <span className="heading">Title</span>,
    -  <Subcomponent foo="bar" />
    -]);
    -
    -

    Shallow testing currently has some limitations, namely not supporting refs.

    - -

    We also recommend checking out Enzyme's Shallow Rendering API. It provides a nicer higher-level API over the same functionality.

    - -
    -

    Reference

    Simulate

    @@ -346,8 +302,6 @@
    - ← Prev -
    @@ -436,11 +390,6 @@ -
  • - Typechecking With PropTypes - -
  • -
  • Refs and the DOM @@ -526,47 +475,6 @@
  • -
  • - Add-Ons - - - -
  • - diff --git a/docs/thinking-in-react.html b/docs/thinking-in-react.html index 304d009110..61bd3d262c 100644 --- a/docs/thinking-in-react.html +++ b/docs/thinking-in-react.html @@ -63,7 +63,7 @@ @@ -332,11 +332,6 @@ -
  • - Typechecking With PropTypes - -
  • -
  • Refs and the DOM @@ -422,47 +417,6 @@
  • -
  • - Add-Ons - - - -
  • - diff --git a/docs/two-way-binding-helpers.html b/docs/two-way-binding-helpers.html index 0250985840..8226d0ca58 100644 --- a/docs/two-way-binding-helpers.html +++ b/docs/two-way-binding-helpers.html @@ -63,7 +63,7 @@ @@ -84,9 +84,8 @@

    Importing

    -
    import LinkedStateMixin from 'react-addons-linked-state-mixin' // ES6
    -var LinkedStateMixin = require('react-addons-linked-state-mixin') // ES5 with npm
    -var LinkedStateMixin = React.addons.LinkedStateMixin; // ES5 with react-with-addons.js
    +
    import LinkedStateMixin from 'react-addons-linked-state-mixin'; // ES6
    +var LinkedStateMixin = require('react-addons-linked-state-mixin'); // ES5 with npm
     

    Overview

    @@ -109,7 +108,9 @@

    LinkedStateMixin: Before and After

    Here's a simple form example without using LinkedStateMixin:

    -
    var NoLink = React.createClass({
    +
    var createReactClass = require('create-react-class');
    +
    +var NoLink = createReactClass({
       getInitialState: function() {
         return {message: 'Hello!'};
       },
    @@ -123,16 +124,18 @@
     });
     

    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 LinkedStateMixin to save us some typing:

    -
    var WithLink = React.createClass({
    -  mixins: [LinkedStateMixin],
    -  getInitialState: function() {
    -    return {message: 'Hello!'};
    -  },
    +
    var createReactClass = require('create-react-class');
    +
    +var WithLink = createReactClass({
    +  mixins: [LinkedStateMixin],
    +  getInitialState: function() {
    +    return {message: 'Hello!'};
    +  },
       render: function() {
    -    return <input type="text" valueLink={this.linkState('message')} />;
    -  }
    -});
    -
    + return <input type="text" valueLink={this.linkState('message')} />; + } +}); +

    LinkedStateMixin adds a method to your React component called linkState(). linkState() returns a valueLink object which contains the current value of the React state and a callback to change it.

    valueLink 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.

    @@ -147,7 +150,9 @@

    There are two sides to LinkedStateMixin: the place where you create the valueLink instance and the place where you use it. To prove how simple LinkedStateMixin is, let's rewrite each side separately to be more explicit.

    valueLink Without LinkedStateMixin

    -
    var WithoutMixin = React.createClass({
    +
    var createReactClass = require('create-react-class');
    +
    +var WithoutMixin = createReactClass({
       getInitialState: function() {
         return {message: 'Hello!'};
       },
    @@ -167,8 +172,9 @@
     
     

    LinkedStateMixin Without valueLink

    var LinkedStateMixin = require('react-addons-linked-state-mixin');
    +var createReactClass = require('create-react-class');
     
    -var WithoutLink = React.createClass({
    +var WithoutLink = createReactClass({
       mixins: [LinkedStateMixin],
       getInitialState: function() {
         return {message: 'Hello!'};
    @@ -187,10 +193,6 @@
     
         
    - ← Prev - - - Next →
    @@ -279,11 +281,6 @@ -
  • - Typechecking With PropTypes - -
  • -
  • Refs and the DOM @@ -369,47 +366,6 @@
  • -
  • - Add-Ons - - - -
  • -
    diff --git a/docs/typechecking-with-proptypes.html b/docs/typechecking-with-proptypes.html index b0a48e1b49..124a4fb121 100644 --- a/docs/typechecking-with-proptypes.html +++ b/docs/typechecking-with-proptypes.html @@ -63,7 +63,7 @@
    @@ -78,7 +78,12 @@
    -

    As your app grows, you can catch a lot of bugs with typechecking. For some applications, you can use JavaScript extensions like Flow or TypeScript to typecheck your whole application. But even if you don't use those, React has some built-in typechecking abilities. To run typechecking on the props for a component, you can assign the special propTypes property:

    +
    +

    Note: +React.PropTypes is deprecated as of React v15.5. Please use the prop-types library instead.

    +
    + +

    As your app grows, you can catch a lot of bugs with typechecking. For some applications, you can use JavaScript extensions like Flow or TypeScript to typecheck your whole application. But even if you don't use those, React has some built-in typechecking abilities. To run typechecking on the props for a component, you can assign the special propTypes property:

    class Greeting extends React.Component {
       render() {
         return (
    @@ -309,11 +314,6 @@
                 
               
             
    -          
  • - Typechecking With PropTypes - -
  • -
  • Refs and the DOM @@ -399,47 +399,6 @@
  • -
  • - Add-Ons - - - -
  • -
    diff --git a/docs/uncontrolled-components.html b/docs/uncontrolled-components.html index 60725b2efb..989de2bc87 100644 --- a/docs/uncontrolled-components.html +++ b/docs/uncontrolled-components.html @@ -63,7 +63,7 @@
    @@ -131,7 +131,7 @@ ); } -

    Likewise, <input type="checkbox"> and <input type="radio"> support defaultChecked, and <select> supports defaultValue.

    +

    Likewise, <input type="checkbox"> and <input type="radio"> support defaultChecked, and <select> and <textarea> supports defaultValue.

    @@ -224,11 +224,6 @@ -
  • - Typechecking With PropTypes - -
  • -
  • Refs and the DOM @@ -314,47 +309,6 @@
  • -
  • - Add-Ons - - - -
  • -
    diff --git a/docs/update.html b/docs/update.html index adea9ddd1d..7b18cfde41 100644 --- a/docs/update.html +++ b/docs/update.html @@ -63,7 +63,7 @@ @@ -86,7 +86,6 @@

    Importing

    import update from 'react-addons-update'; // ES6
     var update = require('react-addons-update'); // ES5 with npm
    -var update = React.addons.update; // ES5 with react-with-addons.js
     

    Overview

    @@ -258,11 +257,6 @@ -
  • - Typechecking With PropTypes - -
  • -
  • Refs and the DOM @@ -348,47 +342,6 @@
  • -
  • - Add-Ons - - - -
  • - diff --git a/docs/videos-it-IT.html b/docs/videos-it-IT.html index 7e0dc10fdb..995b807d07 100644 --- a/docs/videos-it-IT.html +++ b/docs/videos-it-IT.html @@ -63,7 +63,7 @@ diff --git a/docs/videos-ko-KR.html b/docs/videos-ko-KR.html index dae9c85456..8db8e7602b 100644 --- a/docs/videos-ko-KR.html +++ b/docs/videos-ko-KR.html @@ -63,7 +63,7 @@ diff --git a/docs/videos-zh-CN.html b/docs/videos-zh-CN.html index 33b2f24852..8ea154f267 100644 --- a/docs/videos-zh-CN.html +++ b/docs/videos-zh-CN.html @@ -63,7 +63,7 @@ diff --git a/docs/web-components.html b/docs/web-components.html index 749c8fccd1..3c00dcb16e 100644 --- a/docs/web-components.html +++ b/docs/web-components.html @@ -63,7 +63,7 @@ @@ -123,8 +123,6 @@ You will need to manually attach event handlers to handle these events within yo }); document.registerElement('x-search', {prototype: proto});
    -

    You can also check out this complete Web Components example on GitHub.

    -
    @@ -216,11 +214,6 @@ You will need to manually attach event handlers to handle these events within yo -
  • - Typechecking With PropTypes - -
  • -
  • Refs and the DOM @@ -306,47 +299,6 @@ You will need to manually attach event handlers to handle these events within yo
  • -
  • - Add-Ons - - - -
  • -
    diff --git a/feed.xml b/feed.xml index 11c2c169f1..19936a7933 100644 --- a/feed.xml +++ b/feed.xml @@ -6,6 +6,225 @@ https://facebook.github.io/react + + React v15.5.0 + <p>It&#39;s been exactly one year since the last breaking change to React. Our next major release, React 16, will include some exciting improvements, including a <a href="https://www.youtube.com/watch?v=ZCuYPiUIONs">complete rewrite</a> of React&#39;s internals. <a href="/react/contributing/design-principles.html#stability">We take stability seriously</a>, and are committed to bringing those improvements to all of our users with minimal effort.</p> + +<p>To that end, today we&#39;re releasing React 15.5.0.</p> + +<h3>New Deprecation Warnings</h3> + +<p>The biggest change is that we&#39;ve extracted <code>React.PropTypes</code> and <code>React.createClass</code> into their own packages. Both are still accessible via the main <code>React</code> object, but using either will log a one-time deprecation warning to the console when in development mode. This will enable future code size optimizations.</p> + +<p>These warnings will not affect the behavior of your application. However, we realize they may cause some frustration, particularly if you use a testing framework that treats <code>console.error</code> as a failure.</p> + +<p><strong>Adding new warnings is not something we do lightly.</strong> Warnings in React are not mere suggestions — they are integral to our strategy of keeping as many people as possible on the latest version of React. We never add warnings without providing an incremental path forward.</p> + +<p>So while the warnings may cause frustration in the short-term, we believe <strong>prodding developers to migrate their codebases now prevents greater frustration in the future</strong>. Proactively fixing warnings ensures you are prepared for the next major release. If your app produces zero warnings in 15.5, it should continue to work in 16 without any changes.</p> + +<p>For each of these new deprecations, we&#39;ve provided a codemod to automatically migrate your code. They are available as part of the <a href="https://github.com/reactjs/react-codemod">react-codemod</a> project.</p> + +<h3>Migrating from React.PropTypes</h3> + +<p>Prop types are a feature for runtime validation of props during development. We&#39;ve extracted the built-in prop types to a separate package to reflect the fact that not everybody uses them.</p> + +<p>In 15.5, instead of accessing <code>PropTypes</code> from the main <code>React</code> object, install the <code>prop-types</code> package and import them from there:</p> +<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="c1">// Before (15.4 and below)</span> +<span class="kr">import</span> <span class="nx">React</span> <span class="nx">from</span> <span class="s1">&#39;react&#39;</span><span class="p">;</span> + +<span class="kr">class</span> <span class="nx">Component</span> <span class="kr">extends</span> <span class="nx">React</span><span class="p">.</span><span class="nx">Component</span> <span class="p">{</span> + <span class="nx">render</span><span class="p">()</span> <span class="p">{</span> + <span class="k">return</span> <span class="o">&lt;</span><span class="nx">div</span><span class="o">&gt;</span><span class="p">{</span><span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">text</span><span class="p">}</span><span class="o">&lt;</span><span class="err">/div&gt;;</span> + <span class="p">}</span> +<span class="p">}</span> + +<span class="nx">Component</span><span class="p">.</span><span class="nx">propTypes</span> <span class="o">=</span> <span class="p">{</span> +<span class="hll"> <span class="nx">text</span><span class="o">:</span> <span class="nx">React</span><span class="p">.</span><span class="nx">PropTypes</span><span class="p">.</span><span class="nx">string</span><span class="p">.</span><span class="nx">isRequired</span><span class="p">,</span> +</span><span class="p">}</span> + +<span class="c1">// After (15.5)</span> +<span class="kr">import</span> <span class="nx">React</span> <span class="nx">from</span> <span class="s1">&#39;react&#39;</span><span class="p">;</span> +<span class="hll"><span class="kr">import</span> <span class="nx">PropTypes</span> <span class="nx">from</span> <span class="s1">&#39;prop-types&#39;</span><span class="p">;</span> +</span> +<span class="kr">class</span> <span class="nx">Component</span> <span class="kr">extends</span> <span class="nx">React</span><span class="p">.</span><span class="nx">Component</span> <span class="p">{</span> + <span class="nx">render</span><span class="p">()</span> <span class="p">{</span> + <span class="k">return</span> <span class="o">&lt;</span><span class="nx">div</span><span class="o">&gt;</span><span class="p">{</span><span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">text</span><span class="p">}</span><span class="o">&lt;</span><span class="err">/div&gt;;</span> + <span class="p">}</span> +<span class="p">}</span> + +<span class="nx">Component</span><span class="p">.</span><span class="nx">propTypes</span> <span class="o">=</span> <span class="p">{</span> +<span class="hll"> <span class="nx">text</span><span class="o">:</span> <span class="nx">PropTypes</span><span class="p">.</span><span class="nx">string</span><span class="p">.</span><span class="nx">isRequired</span><span class="p">,</span> +</span><span class="p">};</span> +</code></pre></div> +<p>The <a href="https://github.com/reactjs/react-codemod#react-proptypes-to-prop-types">codemod</a> for this change performs this conversion automatically. Basic usage:</p> +<div class="highlight"><pre><code class="language-bash" data-lang="bash">jscodeshift -t react-codemod/transforms/React-PropTypes-to-prop-types.js &lt;path&gt; +</code></pre></div> +<p>The <code>propTypes</code>, <code>contextTypes</code>, and <code>childContextTypes</code> APIs will work exactly as before. The only change is that the built-in validators now live in a separate package.</p> + +<p>You may also consider using <a href="https://flow.org/">Flow</a> to statically type check your JavaScript code, including <a href="https://flow.org/en/docs/frameworks/react/#setup-flow-with-react-a-classtoc-idtoc-setup-flow-with-react-hreftoc-setup-flow-with-reacta">React components</a>.</p> + +<h3>Migrating from React.createClass</h3> + +<p>When React was initially released, there was no idiomatic way to create classes in JavaScript, so we provided our own: <code>React.createClass</code>.</p> + +<p>Later, classes were added to the language as part of ES2015, so we added the ability to create React components using JavaScript classes. <strong>Along with functional components, JavaScript classes are now the <a href="/react/docs/components-and-props.html#functional-and-class-components">preferred way to create components in React</a>.</strong></p> + +<p>For your existing <code>createClass</code> components, we recommend that you migrate them to JavaScript classes. However, if you have components that rely on mixins, converting to classes may not be immediately feasible. If so, <code>create-react-class</code> is available on npm as a drop-in replacement:</p> +<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="c1">// Before (15.4 and below)</span> +<span class="kd">var</span> <span class="nx">React</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;react&#39;</span><span class="p">);</span> + +<span class="hll"><span class="kd">var</span> <span class="nx">Component</span> <span class="o">=</span> <span class="nx">React</span><span class="p">.</span><span class="nx">createClass</span><span class="p">({</span> +</span> <span class="nx">mixins</span><span class="o">:</span> <span class="p">[</span><span class="nx">MixinA</span><span class="p">],</span> + <span class="nx">render</span><span class="p">()</span> <span class="p">{</span> + <span class="k">return</span> <span class="o">&lt;</span><span class="nx">Child</span> <span class="o">/&gt;</span><span class="p">;</span> + <span class="p">}</span> +<span class="p">});</span> + +<span class="c1">// After (15.5)</span> +<span class="kd">var</span> <span class="nx">React</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;react&#39;</span><span class="p">);</span> +<span class="hll"><span class="kd">var</span> <span class="nx">createReactClass</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;create-react-class&#39;</span><span class="p">);</span> +</span> +<span class="hll"><span class="kd">var</span> <span class="nx">Component</span> <span class="o">=</span> <span class="nx">createReactClass</span><span class="p">({</span> +</span> <span class="nx">mixins</span><span class="o">:</span> <span class="p">[</span><span class="nx">MixinA</span><span class="p">],</span> + <span class="nx">render</span><span class="p">()</span> <span class="p">{</span> + <span class="k">return</span> <span class="o">&lt;</span><span class="nx">Child</span> <span class="o">/&gt;</span><span class="p">;</span> + <span class="p">}</span> +<span class="p">});</span> +</code></pre></div> +<p>Your components will continue to work the same as they did before.</p> + +<p>The <a href="https://github.com/reactjs/react-codemod#explanation-of-the-new-es2015-class-transform-with-property-initializers">codemod</a> for this change attempts to convert a <code>createClass</code> component to a JavaScript class, with a fallback to <code>create-react-class</code> if necessary. It has converted thousands of components internally at Facebook.</p> + +<p>Basic usage:</p> +<div class="highlight"><pre><code class="language-bash" data-lang="bash">jscodeshift -t react-codemod/transforms/class.js path/to/components +</code></pre></div> +<h3>Discontinuing support for React Addons</h3> + +<p>We&#39;re discontinuing active maintenance of React Addons packages. In truth, most of these packages haven&#39;t been actively maintained in a long time. They will continue to work indefinitely, but we recommend migrating away as soon as you can to prevent future breakages.</p> + +<ul> +<li><strong>react-addons-create-fragment</strong> – React 16 will have first-class support for fragments, at which point this package won&#39;t be necessary. We recommend using arrays of keyed elements instead.</li> +<li><strong>react-addons-css-transition-group</strong> - Use <a href="https://github.com/reactjs/react-transition-group">react-transition-group/CSSTransitionGroup</a> instead. Version 1.1.1 provides a drop-in replacement.</li> +<li><strong>react-addons-linked-state-mixin</strong> - Explicitly set the <code>value</code> and <code>onChange</code> handler instead.</li> +<li><strong>react-addons-pure-render-mixin</strong> - Use <a href="/react/docs/react-api.html#react.purecomponent"><code>React.PureComponent</code></a> instead.</li> +<li><strong>react-addons-shallow-compare</strong> - Use <a href="/react/docs/react-api.html#react.purecomponent"><code>React.PureComponent</code></a> instead.</li> +<li><strong>react-addons-transition-group</strong> - Use <a href="https://github.com/reactjs/react-transition-group">react-transition-group/TransitionGroup</a> instead. Version 1.1.1 provides a drop-in replacement.</li> +<li><strong>react-addons-update</strong> - Use <a href="https://github.com/kolodny/immutability-helper">immutability-helper</a> instead, a drop-in replacement.</li> +<li><strong>react-linked-input</strong> - Explicitly set the <code>value</code> and <code>onChange</code> handler instead.</li> +</ul> + +<p>We&#39;re also discontinuing support for the <code>react-with-addons</code> UMD build. It will be removed in React 16.</p> + +<h3>React Test Utils</h3> + +<p>Currently, the React Test Utils live inside <code>react-addons-test-utils</code>. As of 15.5, we&#39;re deprecating that package and moving them to <code>react-dom/test-utils</code> instead:</p> +<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="c1">// Before (15.4 and below)</span> +<span class="kr">import</span> <span class="nx">TestUtils</span> <span class="nx">from</span> <span class="s1">&#39;react-addons-test-utils&#39;</span><span class="p">;</span> + +<span class="c1">// After (15.5)</span> +<span class="kr">import</span> <span class="nx">TestUtils</span> <span class="nx">from</span> <span class="s1">&#39;react-dom/test-utils&#39;</span><span class="p">;</span> +</code></pre></div> +<p>This reflects the fact that what we call the Test Utils are really a set of APIs that wrap the DOM renderer.</p> + +<p>The exception is shallow rendering, which is not DOM-specific. The shallow renderer has been moved to <code>react-test-renderer/shallow</code>.</p> +<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="c1">// Before (15.4 and below)</span> +<span class="hll"><span class="kr">import</span> <span class="p">{</span> <span class="nx">createRenderer</span> <span class="p">}</span> <span class="nx">from</span> <span class="s1">&#39;react-addons-test-utils&#39;</span><span class="p">;</span> +</span> +<span class="c1">// After (15.5)</span> +<span class="hll"><span class="kr">import</span> <span class="p">{</span> <span class="nx">createRenderer</span> <span class="p">}</span> <span class="nx">from</span> <span class="s1">&#39;react-test-renderer/shallow&#39;</span><span class="p">;</span> +</span></code></pre></div> +<hr> + +<h2>Acknowledgements</h2> + +<p>A special thank you to these folks for transferring ownership of npm package names:</p> + +<ul> +<li><a href="https://github.com/developit">Jason Miller</a></li> +<li><a href="https://github.com/aackerman">Aaron Ackerman</a></li> +<li><a href="https://github.com/viniciusmarson">Vinicius Marson</a></li> +</ul> + +<hr> + +<h2>Installation</h2> + +<p>We recommend using <a href="https://yarnpkg.com/">Yarn</a> or <a href="https://www.npmjs.com/">npm</a> for managing front-end dependencies. If you&#39;re new to package managers, the <a href="https://yarnpkg.com/en/docs/getting-started">Yarn documentation</a> is a good place to get started.</p> + +<p>To install React with Yarn, run:</p> +<div class="highlight"><pre><code class="language-bash" data-lang="bash">yarn add react@15.5.0 react-dom@15.5.0 +</code></pre></div> +<p>To install React with npm, run:</p> +<div class="highlight"><pre><code class="language-bash" data-lang="bash">npm install --save react@15.5.0 react-dom@15.5.0 +</code></pre></div> +<p>We recommend using a bundler like <a href="https://webpack.js.org/">webpack</a> or <a href="http://browserify.org/">Browserify</a> so you can write modular code and bundle it together into small packages to optimize load time.</p> + +<p>Remember that by default, React runs extra checks and provides helpful warnings in development mode. When deploying your app, make sure to <a href="/react/docs/installation.html#development-and-production-versions">compile it in production mode</a>.</p> + +<p>In case you don&#39;t use a bundler, we also provide pre-built bundles in the npm packages which you can <a href="/react/docs/installation.html#using-a-cdn">include as script tags</a> on your page:</p> + +<ul> +<li><strong>React</strong><br> +Dev build with warnings: <a href="https://unpkg.com/react@15.5.0/dist/react.js">react/dist/react.js</a><br> +Minified build for production: <a href="https://unpkg.com/react@15.5.0/dist/react.min.js">react/dist/react.min.js</a><br></li> +<li><strong>React with Add-Ons</strong><br> +Dev build with warnings: <a href="https://unpkg.com/react@15.5.0/dist/react-with-addons.js">react/dist/react-with-addons.js</a><br> +Minified build for production: <a href="https://unpkg.com/react@15.5.0/dist/react-with-addons.min.js">react/dist/react-with-addons.min.js</a><br></li> +<li><strong>React DOM</strong> (include React in the page before React DOM)<br> +Dev build with warnings: <a href="https://unpkg.com/react-dom@15.5.0/dist/react-dom.js">react-dom/dist/react-dom.js</a><br> +Minified build for production: <a href="https://unpkg.com/react-dom@15.5.0/dist/react-dom.min.js">react-dom/dist/react-dom.min.js</a><br></li> +<li><strong>React DOM Server</strong> (include React in the page before React DOM Server)<br> +Dev build with warnings: <a href="https://unpkg.com/react-dom@15.5.0/dist/react-dom-server.js">react-dom/dist/react-dom-server.js</a><br> +Minified build for production: <a href="https://unpkg.com/react-dom@15.5.0/dist/react-dom-server.min.js">react-dom/dist/react-dom-server.min.js</a></li> +</ul> + +<p>We&#39;ve also published version <code>15.5.0</code> of the <code>react</code>, <code>react-dom</code>, and addons packages on npm and the <code>react</code> package on bower.</p> + +<hr> + +<h2>Changelog</h2> + +<h2>15.5.0 (April 7, 2017)</h2> + +<h3>React</h3> + +<ul> +<li>Added a deprecation warning for <code>React.createClass</code>. Points users to create-react-class instead. (<a href="https://github.com/acdlite">@acdlite</a> in <a href="https://github.com/facebook/react/commit/d9a4fa4f51c6da895e1655f32255cf72c0fe620e">d9a4fa4</a>)</li> +<li>Added a deprecation warning for <code>React.PropTypes</code>. Points users to prop-types instead. (<a href="https://github.com/acdlite">@acdlite</a> in <a href="https://github.com/facebook/react/commit/043845ce75ea0812286bbbd9d34994bb7e01eb28">043845c</a>)</li> +<li>Fixed an issue when using <code>ReactDOM</code> together with <code>ReactDOMServer</code>. (<a href="https://github.com/wacii">@wacii</a> in <a href="https://github.com/facebook/react/pull/9005">#9005</a>)</li> +<li>Fixed issue with Closure Compiler. (<a href="https://github.com/anmonteiro">@anmonteiro</a> in <a href="https://github.com/facebook/react/pull/8895">#8895</a>)</li> +<li>Another fix for Closure Compiler. (<a href="https://github.com/Shastel">@Shastel</a> in <a href="https://github.com/facebook/react/pull/8882">#8882</a>)</li> +<li>Added component stack info to invalid element type warning. (<a href="https://github.com/n3tr">@n3tr</a> in <a href="https://github.com/facebook/react/pull/8495">#8495</a>)</li> +</ul> + +<h3>React DOM</h3> + +<ul> +<li>Fixed Chrome bug when backspacing in number inputs. (<a href="https://github.com/nhunzaker">@nhunzaker</a> in <a href="https://github.com/facebook/react/pull/7359">#7359</a>)</li> +<li>Added <code>react-dom/test-utils</code>, which exports the React Test Utils. (<a href="https://github.com/bvaughn">@bvaughn</a>)</li> +</ul> + +<h3>React Test Renderer</h3> + +<ul> +<li>Fixed bug where <code>componentWillUnmount</code> was not called for children. (<a href="https://github.com/gre">@gre</a> in <a href="https://github.com/facebook/react/pull/8512">#8512</a>)</li> +<li>Added <code>react-test-renderer/shallow</code>, which exports the shallow renderer. (<a href="https://github.com/bvaughn">@bvaughn</a>)</li> +</ul> + +<h3>React Addons</h3> + +<ul> +<li>Last release for addons; they will no longer be actively maintained.</li> +<li>Removed <code>peerDependencies</code> so that addons continue to work indefinitely. (<a href="https://github.com/acdlite">@acdlite</a> and <a href="https://github.com/bvaughn">@bvaughn</a> in <a href="https://github.com/facebook/react/commit/8a06cd7a786822fce229197cac8125a551e8abfa">8a06cd7</a> and <a href="https://github.com/facebook/react/commit/67a8db3650d724a51e70be130e9008806402678a">67a8db3</a>)</li> +<li>Updated to remove references to <code>React.createClass</code> and <code>React.PropTypes</code> (<a href="https://github.com/acdlite">@acdlite</a> in <a href="https://github.com/facebook/react/commit/12a96b94823d6b6de6b1ac13bd576864abd50175">12a96b9</a>)</li> +<li><code>react-addons-test-utils</code> is deprecated. Use <code>react-dom/test-utils</code> and <code>react-test-renderer/shallow</code> instead. (<a href="https://github.com/bvaughn">@bvaughn</a>)</li> +</ul> + + 2017-04-07T00:00:00-07:00 + https://facebook.github.io/react/blog/2017/04/07/react-v15.5.0.html + https://facebook.github.io/react/blog/2017/04/07/react-v15.5.0.html + + React v15.4.0 <p>Today we are releasing React 15.4.0.</p> @@ -1587,44 +1806,5 @@ Minified build for production: <a href="https://fb.me/react-dom-server-0 https://facebook.github.io/react/blog/2016/03/29/react-v0.14.8.html - - React v15.0 Release Candidate 2 - <p>Today we&#39;re releasing a second release candidate for version 15. Primarily this is to address 2 issues, but we also picked up a few small changes from new contributors, including some improvements to some of our new warnings.</p> - -<p>The most pressing change that was made is to fix a bug in our new code that removes <code>&lt;span&gt;</code>s, as discussed in the original RC1 post. Specifically we have some code that takes a different path in IE11 and Edge due to the speed of some DOM operations. There was a bug in this code which didn&#39;t break out of the optimization for <code>DocumentFragment</code>s, resulting in text not appearing at all. Thanks to the several people who <a href="https://github.com/facebook/react/issues/6246">reported this</a>.</p> - -<p>The other change is to our SVG code. In RC1 we had made the decision to pass through all attributes directly. This led to <a href="https://github.com/facebook/react/issues/6211">some confusion with <code>class</code> vs <code>className</code></a> and ultimately led us to reconsider our position on the approach. Passing through all attributes meant that we would have two different patterns for using React where things like hyphenated attributes would work for SVG but not HTML. In the future, we <em>might</em> change our approach to the problem for HTML as well but in the meantime, maintaining consistency is important. So we reverted the changes that allowed the attributes to be passed through and instead expanded the SVG property list to include all attributes that are in the spec. We believe we have everything now but definitely <a href="https://github.com/facebook/react/issues/1657#issuecomment-197031403">let us know</a> if we missed anything. It was and still is our intent to support the full range of SVG tags and attributes in this release.</p> - -<p>Thanks again to everybody who has tried the RC1 and reported issues. It has been extremely important and we wouldn&#39;t be able to do this without your help!</p> - -<h2>Installation</h2> - -<p>We recommend using React from <code>npm</code> and using a tool like browserify or webpack to build your code into a single bundle. To install the two packages:</p> - -<ul> -<li><code>npm install --save react@15.0.0-rc.2 react-dom@15.0.0-rc.2</code></li> -</ul> - -<p>Remember that by default, React runs extra checks and provides helpful warnings in development mode. When deploying your app, set the <code>NODE_ENV</code> environment variable to <code>production</code> to use the production build of React which does not include the development warnings and runs significantly faster.</p> - -<p>If you can’t use <code>npm</code> yet, we provide pre-built browser builds for your convenience, which are also available in the <code>react</code> package on bower.</p> - -<ul> -<li><strong>React</strong><br> -Dev build with warnings: <a href="https://fb.me/react-15.0.0-rc.2.js">https://fb.me/react-15.0.0-rc.2.js</a><br> -Minified build for production: <a href="https://fb.me/react-15.0.0-rc.2.min.js">https://fb.me/react-15.0.0-rc.2.min.js</a><br></li> -<li><strong>React with Add-Ons</strong><br> -Dev build with warnings: <a href="https://fb.me/react-with-addons-15.0.0-rc.2.js">https://fb.me/react-with-addons-15.0.0-rc.2.js</a><br> -Minified build for production: <a href="https://fb.me/react-with-addons-15.0.0-rc.2.min.js">https://fb.me/react-with-addons-15.0.0-rc.2.min.js</a><br></li> -<li><strong>React DOM</strong> (include React in the page before React DOM)<br> -Dev build with warnings: <a href="https://fb.me/react-dom-15.0.0-rc.2.js">https://fb.me/react-dom-15.0.0-rc.2.js</a><br> -Minified build for production: <a href="https://fb.me/react-dom-15.0.0-rc.2.min.js">https://fb.me/react-dom-15.0.0-rc.2.min.js</a><br></li> -</ul> - - 2016-03-16T00:00:00-07:00 - https://facebook.github.io/react/blog/2016/03/16/react-v15-rc2.html - https://facebook.github.io/react/blog/2016/03/16/react-v15-rc2.html - - diff --git a/index.html b/index.html index f370d8cd84..ebe44a41b2 100644 --- a/index.html +++ b/index.html @@ -63,7 +63,7 @@ diff --git a/js/react-dom.js b/js/react-dom.js index fbd29aea0d..48b2fd58c5 100644 --- a/js/react-dom.js +++ b/js/react-dom.js @@ -1,5 +1,5 @@ /** - * ReactDOM v15.4.2 + * ReactDOM v15.5.0 */ ;(function(f) { @@ -883,7 +883,7 @@ module.exports = CSSPropertyOperations; 'use strict'; -var _prodInvariant = _dereq_(125); +var _prodInvariant = _dereq_(124); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } @@ -988,7 +988,7 @@ var CallbackQueue = function () { }(); module.exports = PooledClass.addPoolingTo(CallbackQueue); -},{"125":125,"150":150,"25":25}],7:[function(_dereq_,module,exports){ +},{"124":124,"150":150,"25":25}],7:[function(_dereq_,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -1009,8 +1009,8 @@ var ReactUpdates = _dereq_(82); var SyntheticEvent = _dereq_(91); var getEventTarget = _dereq_(114); -var isEventSupported = _dereq_(122); -var isTextInputElement = _dereq_(123); +var isEventSupported = _dereq_(121); +var isTextInputElement = _dereq_(122); var eventTypes = { change: { @@ -1256,6 +1256,26 @@ function getTargetInstForClickEvent(topLevelType, targetInst) { } } +function handleControlledInputBlur(inst, node) { + // TODO: In IE, inst is occasionally null. Why? + if (inst == null) { + return; + } + + // Fiber and ReactDOM keep wrapper state in separate places + var state = inst._wrapperState || node._wrapperState; + + if (!state || !state.controlled || node.type !== 'number') { + return; + } + + // If controlled, assign the value attribute to the current value on blur + var value = '' + node.value; + if (node.getAttribute('value') !== value) { + node.setAttribute('value', value); + } +} + /** * This plugin creates an `onChange` event that normalizes change events * across form elements. This event fires at a time when it's possible to @@ -1304,12 +1324,17 @@ var ChangeEventPlugin = { if (handleEventFunc) { handleEventFunc(topLevelType, targetNode, targetInst); } + + // When blurring, set the value attribute for number inputs + if (topLevelType === 'topBlur') { + handleControlledInputBlur(targetInst, targetNode); + } } }; module.exports = ChangeEventPlugin; -},{"114":114,"122":122,"123":123,"136":136,"17":17,"20":20,"34":34,"82":82,"91":91}],8:[function(_dereq_,module,exports){ +},{"114":114,"121":121,"122":122,"136":136,"17":17,"20":20,"34":34,"82":82,"91":91}],8:[function(_dereq_,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -1328,8 +1353,8 @@ var ReactDOMComponentTree = _dereq_(34); var ReactInstrumentation = _dereq_(64); var createMicrosoftUnsafeLocalFunction = _dereq_(105); -var setInnerHTML = _dereq_(127); -var setTextContent = _dereq_(128); +var setInnerHTML = _dereq_(126); +var setTextContent = _dereq_(127); function getNodeAfter(parentNode, node) { // Special case for text components, which return [open, close] comments @@ -1534,7 +1559,7 @@ var DOMChildrenOperations = { }; module.exports = DOMChildrenOperations; -},{"105":105,"127":127,"128":128,"13":13,"34":34,"64":64,"9":9}],9:[function(_dereq_,module,exports){ +},{"105":105,"126":126,"127":127,"13":13,"34":34,"64":64,"9":9}],9:[function(_dereq_,module,exports){ /** * Copyright 2015-present, Facebook, Inc. * All rights reserved. @@ -1548,10 +1573,10 @@ module.exports = DOMChildrenOperations; 'use strict'; var DOMNamespaces = _dereq_(10); -var setInnerHTML = _dereq_(127); +var setInnerHTML = _dereq_(126); var createMicrosoftUnsafeLocalFunction = _dereq_(105); -var setTextContent = _dereq_(128); +var setTextContent = _dereq_(127); var ELEMENT_NODE_TYPE = 1; var DOCUMENT_FRAGMENT_NODE_TYPE = 11; @@ -1652,7 +1677,7 @@ DOMLazyTree.queueHTML = queueHTML; DOMLazyTree.queueText = queueText; module.exports = DOMLazyTree; -},{"10":10,"105":105,"127":127,"128":128}],10:[function(_dereq_,module,exports){ +},{"10":10,"105":105,"126":126,"127":127}],10:[function(_dereq_,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -1685,7 +1710,7 @@ module.exports = DOMNamespaces; 'use strict'; -var _prodInvariant = _dereq_(125); +var _prodInvariant = _dereq_(124); var invariant = _dereq_(150); @@ -1882,7 +1907,7 @@ var DOMProperty = { }; module.exports = DOMProperty; -},{"125":125,"150":150}],12:[function(_dereq_,module,exports){ +},{"124":124,"150":150}],12:[function(_dereq_,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -1899,7 +1924,7 @@ var DOMProperty = _dereq_(11); var ReactDOMComponentTree = _dereq_(34); var ReactInstrumentation = _dereq_(64); -var quoteAttributeValueForBrowser = _dereq_(124); +var quoteAttributeValueForBrowser = _dereq_(123); var warning = _dereq_(157); var VALID_ATTRIBUTE_NAME_REGEX = new RegExp('^[' + DOMProperty.ATTRIBUTE_NAME_START_CHAR + '][' + DOMProperty.ATTRIBUTE_NAME_CHAR + ']*$'); @@ -2119,7 +2144,7 @@ var DOMPropertyOperations = { }; module.exports = DOMPropertyOperations; -},{"11":11,"124":124,"157":157,"34":34,"64":64}],13:[function(_dereq_,module,exports){ +},{"11":11,"123":123,"157":157,"34":34,"64":64}],13:[function(_dereq_,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -2132,7 +2157,7 @@ module.exports = DOMPropertyOperations; 'use strict'; -var _prodInvariant = _dereq_(125); +var _prodInvariant = _dereq_(124); var DOMLazyTree = _dereq_(9); var ExecutionEnvironment = _dereq_(136); @@ -2167,7 +2192,7 @@ var Danger = { }; module.exports = Danger; -},{"125":125,"136":136,"141":141,"142":142,"150":150,"9":9}],14:[function(_dereq_,module,exports){ +},{"124":124,"136":136,"141":141,"142":142,"150":150,"9":9}],14:[function(_dereq_,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -2398,7 +2423,7 @@ module.exports = EventConstants; 'use strict'; -var _prodInvariant = _dereq_(125); +var _prodInvariant = _dereq_(124); var EventPluginRegistry = _dereq_(18); var EventPluginUtils = _dereq_(19); @@ -2663,7 +2688,7 @@ var EventPluginHub = { }; module.exports = EventPluginHub; -},{"102":102,"110":110,"125":125,"150":150,"18":18,"19":19,"55":55}],18:[function(_dereq_,module,exports){ +},{"102":102,"110":110,"124":124,"150":150,"18":18,"19":19,"55":55}],18:[function(_dereq_,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -2677,7 +2702,7 @@ module.exports = EventPluginHub; 'use strict'; -var _prodInvariant = _dereq_(125); +var _prodInvariant = _dereq_(124); var invariant = _dereq_(150); @@ -2918,7 +2943,7 @@ var EventPluginRegistry = { }; module.exports = EventPluginRegistry; -},{"125":125,"150":150}],19:[function(_dereq_,module,exports){ +},{"124":124,"150":150}],19:[function(_dereq_,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -2931,7 +2956,7 @@ module.exports = EventPluginRegistry; 'use strict'; -var _prodInvariant = _dereq_(125); +var _prodInvariant = _dereq_(124); var ReactErrorUtils = _dereq_(55); @@ -3144,7 +3169,7 @@ var EventPluginUtils = { }; module.exports = EventPluginUtils; -},{"125":125,"150":150,"157":157,"55":55}],20:[function(_dereq_,module,exports){ +},{"124":124,"150":150,"157":157,"55":55}],20:[function(_dereq_,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -3295,7 +3320,7 @@ var _assign = _dereq_(158); var PooledClass = _dereq_(25); -var getTextContentAccessor = _dereq_(119); +var getTextContentAccessor = _dereq_(118); /** * This helper class stores information about text content of a target node, @@ -3373,7 +3398,7 @@ _assign(FallbackCompositionState.prototype, { PooledClass.addPoolingTo(FallbackCompositionState); module.exports = FallbackCompositionState; -},{"119":119,"158":158,"25":25}],22:[function(_dereq_,module,exports){ +},{"118":118,"158":158,"25":25}],22:[function(_dereq_,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -3581,7 +3606,31 @@ var HTMLDOMPropertyConfig = { htmlFor: 'for', httpEquiv: 'http-equiv' }, - DOMPropertyNames: {} + DOMPropertyNames: {}, + DOMMutationMethods: { + value: function (node, value) { + if (value == null) { + return node.removeAttribute('value'); + } + + // Number inputs get special treatment due to some edge cases in + // Chrome. Let everything else assign the value attribute as normal. + // https://github.com/facebook/react/issues/7253#issuecomment-236074326 + if (node.type !== 'number' || node.hasAttribute('value') === false) { + node.setAttribute('value', '' + value); + } else if (node.validity && !node.validity.badInput && node.ownerDocument.activeElement !== node) { + // Don't assign an attribute if validation reports bad + // input. Chrome will clear the value. Additionally, don't + // operate on inputs that have focus, otherwise Chrome might + // strip off trailing decimal places and cause the user's + // cursor position to jump to the beginning of the input. + // + // In ReactDOMInput, we have an onBlur event that will trigger + // this function again when focus is lost. + node.setAttribute('value', '' + value); + } + } + } }; module.exports = HTMLDOMPropertyConfig; @@ -3657,10 +3706,13 @@ module.exports = KeyEscapeUtils; 'use strict'; -var _prodInvariant = _dereq_(125); +var _prodInvariant = _dereq_(124); -var React = _dereq_(134); var ReactPropTypesSecret = _dereq_(73); +var propTypesFactory = _dereq_(160); + +var React = _dereq_(133); +var PropTypes = propTypesFactory(React.isValidElement); var invariant = _dereq_(150); var warning = _dereq_(157); @@ -3701,7 +3753,7 @@ var propTypes = { } return new Error('You provided a `checked` prop to a form field without an ' + '`onChange` handler. This will render a read-only field. If ' + 'the field should be mutable use `defaultChecked`. Otherwise, ' + 'set either `onChange` or `readOnly`.'); }, - onChange: React.PropTypes.func + onChange: PropTypes.func }; var loggedTypeFailures = {}; @@ -3779,7 +3831,7 @@ var LinkedValueUtils = { }; module.exports = LinkedValueUtils; -},{"125":125,"134":134,"150":150,"157":157,"73":73}],25:[function(_dereq_,module,exports){ +},{"124":124,"133":133,"150":150,"157":157,"160":160,"73":73}],25:[function(_dereq_,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -3793,7 +3845,7 @@ module.exports = LinkedValueUtils; 'use strict'; -var _prodInvariant = _dereq_(125); +var _prodInvariant = _dereq_(124); var invariant = _dereq_(150); @@ -3891,7 +3943,7 @@ var PooledClass = { }; module.exports = PooledClass; -},{"125":125,"150":150}],26:[function(_dereq_,module,exports){ +},{"124":124,"150":150}],26:[function(_dereq_,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -3910,8 +3962,8 @@ var EventPluginRegistry = _dereq_(18); var ReactEventEmitterMixin = _dereq_(56); var ViewportMetrics = _dereq_(101); -var getVendorPrefixedEventName = _dereq_(120); -var isEventSupported = _dereq_(122); +var getVendorPrefixedEventName = _dereq_(119); +var isEventSupported = _dereq_(121); /** * Summary of `ReactBrowserEventEmitter` event handling: @@ -4219,7 +4271,7 @@ var ReactBrowserEventEmitter = _assign({}, ReactEventEmitterMixin, { }); module.exports = ReactBrowserEventEmitter; -},{"101":101,"120":120,"122":122,"158":158,"18":18,"56":56}],27:[function(_dereq_,module,exports){ +},{"101":101,"119":119,"121":121,"158":158,"18":18,"56":56}],27:[function(_dereq_,module,exports){ (function (process){ /** * Copyright 2014-present, Facebook, Inc. @@ -4235,10 +4287,10 @@ module.exports = ReactBrowserEventEmitter; var ReactReconciler = _dereq_(75); -var instantiateReactComponent = _dereq_(121); +var instantiateReactComponent = _dereq_(120); var KeyEscapeUtils = _dereq_(23); -var shouldUpdateReactComponent = _dereq_(129); -var traverseAllChildren = _dereq_(130); +var shouldUpdateReactComponent = _dereq_(128); +var traverseAllChildren = _dereq_(129); var warning = _dereq_(157); var ReactComponentTreeHook; @@ -4249,7 +4301,7 @@ if (typeof process !== 'undefined' && process.env && "development" === 'test') { // https://github.com/facebook/react/issues/7240 // Remove the inline requires when we don't need them anymore: // https://github.com/facebook/react/pull/7178 - ReactComponentTreeHook = _dereq_(132); + ReactComponentTreeHook = _dereq_(131); } function instantiateChild(childInstances, child, name, selfDebugID) { @@ -4257,7 +4309,7 @@ function instantiateChild(childInstances, child, name, selfDebugID) { var keyUnique = childInstances[name] === undefined; if ("development" !== 'production') { if (!ReactComponentTreeHook) { - ReactComponentTreeHook = _dereq_(132); + ReactComponentTreeHook = _dereq_(131); } if (!keyUnique) { "development" !== 'production' ? warning(false, 'flattenChildren(...): Encountered two children with the same key, ' + '`%s`. Child keys must be unique; when two children share a key, only ' + 'the first child will be used.%s', KeyEscapeUtils.unescape(name), ReactComponentTreeHook.getStackAddendumByID(selfDebugID)) : void 0; @@ -4375,7 +4427,7 @@ var ReactChildReconciler = { module.exports = ReactChildReconciler; }).call(this,undefined) -},{"121":121,"129":129,"130":130,"132":132,"157":157,"23":23,"75":75}],28:[function(_dereq_,module,exports){ +},{"120":120,"128":128,"129":129,"131":131,"157":157,"23":23,"75":75}],28:[function(_dereq_,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -4419,7 +4471,7 @@ module.exports = ReactComponentBrowserEnvironment; 'use strict'; -var _prodInvariant = _dereq_(125); +var _prodInvariant = _dereq_(124); var invariant = _dereq_(150); @@ -4451,7 +4503,7 @@ var ReactComponentEnvironment = { }; module.exports = ReactComponentEnvironment; -},{"125":125,"150":150}],30:[function(_dereq_,module,exports){ +},{"124":124,"150":150}],30:[function(_dereq_,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -4464,12 +4516,12 @@ module.exports = ReactComponentEnvironment; 'use strict'; -var _prodInvariant = _dereq_(125), +var _prodInvariant = _dereq_(124), _assign = _dereq_(158); -var React = _dereq_(134); +var React = _dereq_(133); var ReactComponentEnvironment = _dereq_(29); -var ReactCurrentOwner = _dereq_(133); +var ReactCurrentOwner = _dereq_(132); var ReactErrorUtils = _dereq_(55); var ReactInstanceMap = _dereq_(63); var ReactInstrumentation = _dereq_(64); @@ -4483,7 +4535,7 @@ if ("development" !== 'production') { var emptyObject = _dereq_(143); var invariant = _dereq_(150); var shallowEqual = _dereq_(156); -var shouldUpdateReactComponent = _dereq_(129); +var shouldUpdateReactComponent = _dereq_(128); var warning = _dereq_(157); var CompositeTypes = { @@ -4968,7 +5020,7 @@ var ReactCompositeComponent = { if (childContext) { !(typeof Component.childContextTypes === 'object') ? "development" !== 'production' ? invariant(false, '%s.getChildContext(): childContextTypes must be defined in order to use getChildContext().', this.getName() || 'ReactCompositeComponent') : _prodInvariant('107', this.getName() || 'ReactCompositeComponent') : void 0; if ("development" !== 'production') { - this._checkContextTypes(Component.childContextTypes, childContext, 'childContext'); + this._checkContextTypes(Component.childContextTypes, childContext, 'child context'); } for (var name in childContext) { !(name in Component.childContextTypes) ? "development" !== 'production' ? invariant(false, '%s.getChildContext(): key "%s" is not defined in childContextTypes.', this.getName() || 'ReactCompositeComponent', name) : _prodInvariant('108', this.getName() || 'ReactCompositeComponent', name) : void 0; @@ -5353,7 +5405,7 @@ var ReactCompositeComponent = { }; module.exports = ReactCompositeComponent; -},{"104":104,"125":125,"129":129,"133":133,"134":134,"143":143,"150":150,"156":156,"157":157,"158":158,"29":29,"55":55,"63":63,"64":64,"69":69,"75":75}],31:[function(_dereq_,module,exports){ +},{"104":104,"124":124,"128":128,"132":132,"133":133,"143":143,"150":150,"156":156,"157":157,"158":158,"29":29,"55":55,"63":63,"64":64,"69":69,"75":75}],31:[function(_dereq_,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -5377,7 +5429,7 @@ var ReactVersion = _dereq_(83); var findDOMNode = _dereq_(108); var getHostComponentFromComposite = _dereq_(115); -var renderSubtreeIntoContainer = _dereq_(126); +var renderSubtreeIntoContainer = _dereq_(125); var warning = _dereq_(157); ReactDefaultInjection.inject(); @@ -5464,7 +5516,7 @@ if ("development" !== 'production') { } module.exports = ReactDOM; -},{"108":108,"115":115,"126":126,"136":136,"157":157,"34":34,"40":40,"41":41,"49":49,"52":52,"64":64,"67":67,"75":75,"82":82,"83":83}],32:[function(_dereq_,module,exports){ +},{"108":108,"115":115,"125":125,"136":136,"157":157,"34":34,"40":40,"41":41,"49":49,"52":52,"64":64,"67":67,"75":75,"82":82,"83":83}],32:[function(_dereq_,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -5479,7 +5531,7 @@ module.exports = ReactDOM; 'use strict'; -var _prodInvariant = _dereq_(125), +var _prodInvariant = _dereq_(124), _assign = _dereq_(158); var AutoFocusUtils = _dereq_(2); @@ -5504,9 +5556,9 @@ var ReactServerRenderingTransaction = _dereq_(77); var emptyFunction = _dereq_(142); var escapeTextContentForBrowser = _dereq_(107); var invariant = _dereq_(150); -var isEventSupported = _dereq_(122); +var isEventSupported = _dereq_(121); var shallowEqual = _dereq_(156); -var validateDOMNesting = _dereq_(131); +var validateDOMNesting = _dereq_(130); var warning = _dereq_(157); var Flags = ReactDOMComponentFlags; @@ -6465,7 +6517,7 @@ ReactDOMComponent.Mixin = { _assign(ReactDOMComponent.prototype, ReactDOMComponent.Mixin, ReactMultiChild.Mixin); module.exports = ReactDOMComponent; -},{"10":10,"107":107,"11":11,"12":12,"122":122,"125":125,"131":131,"142":142,"150":150,"156":156,"157":157,"158":158,"17":17,"18":18,"2":2,"26":26,"33":33,"34":34,"39":39,"42":42,"43":43,"46":46,"5":5,"64":64,"68":68,"77":77,"9":9}],33:[function(_dereq_,module,exports){ +},{"10":10,"107":107,"11":11,"12":12,"121":121,"124":124,"130":130,"142":142,"150":150,"156":156,"157":157,"158":158,"17":17,"18":18,"2":2,"26":26,"33":33,"34":34,"39":39,"42":42,"43":43,"46":46,"5":5,"64":64,"68":68,"77":77,"9":9}],33:[function(_dereq_,module,exports){ /** * Copyright 2015-present, Facebook, Inc. * All rights reserved. @@ -6496,7 +6548,7 @@ module.exports = ReactDOMComponentFlags; 'use strict'; -var _prodInvariant = _dereq_(125); +var _prodInvariant = _dereq_(124); var DOMProperty = _dereq_(11); var ReactDOMComponentFlags = _dereq_(33); @@ -6678,7 +6730,7 @@ var ReactDOMComponentTree = { }; module.exports = ReactDOMComponentTree; -},{"11":11,"125":125,"150":150,"33":33}],35:[function(_dereq_,module,exports){ +},{"11":11,"124":124,"150":150,"33":33}],35:[function(_dereq_,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -6691,7 +6743,7 @@ module.exports = ReactDOMComponentTree; 'use strict'; -var validateDOMNesting = _dereq_(131); +var validateDOMNesting = _dereq_(130); var DOC_NODE_TYPE = 9; @@ -6711,7 +6763,7 @@ function ReactDOMContainerInfo(topLevelWrapper, node) { } module.exports = ReactDOMContainerInfo; -},{"131":131}],36:[function(_dereq_,module,exports){ +},{"130":130}],36:[function(_dereq_,module,exports){ /** * Copyright 2014-present, Facebook, Inc. * All rights reserved. @@ -6837,7 +6889,7 @@ module.exports = ReactDOMIDOperations; 'use strict'; -var _prodInvariant = _dereq_(125), +var _prodInvariant = _dereq_(124), _assign = _dereq_(158); var DOMPropertyOperations = _dereq_(12); @@ -6939,12 +6991,9 @@ var ReactDOMInput = { initialChecked: props.checked != null ? props.checked : props.defaultChecked, initialValue: props.value != null ? props.value : defaultValue, listeners: null, - onChange: _handleChange.bind(inst) + onChange: _handleChange.bind(inst), + controlled: isControlled(props) }; - - if ("development" !== 'production') { - inst._wrapperState.controlled = isControlled(props); - } }, updateWrapper: function (inst) { @@ -6973,14 +7022,24 @@ var ReactDOMInput = { var node = ReactDOMComponentTree.getNodeFromInstance(inst); var value = LinkedValueUtils.getValue(props); if (value != null) { + if (value === 0 && node.value === '') { + node.value = '0'; + // Note: IE9 reports a number inputs as 'text', so check props instead. + } else if (props.type === 'number') { + // Simulate `input.valueAsNumber`. IE9 does not support it + var valueAsNumber = parseFloat(node.value, 10) || 0; - // Cast `value` to a string to ensure the value is set correctly. While - // browsers typically do this as necessary, jsdom doesn't. - var newValue = '' + value; - - // To avoid side effects (such as losing text selection), only set value if changed - if (newValue !== node.value) { - node.value = newValue; + // eslint-disable-next-line + if (value != valueAsNumber) { + // Cast `value` to a string to ensure the value is set correctly. While + // browsers typically do this as necessary, jsdom doesn't. + node.value = '' + value; + } + // eslint-disable-next-line + } else if (value != node.value) { + // Cast `value` to a string to ensure the value is set correctly. While + // browsers typically do this as necessary, jsdom doesn't. + node.value = '' + value; } } else { if (props.value == null && props.defaultValue != null) { @@ -7102,7 +7161,7 @@ function _handleChange(event) { } module.exports = ReactDOMInput; -},{"12":12,"125":125,"150":150,"157":157,"158":158,"24":24,"34":34,"82":82}],40:[function(_dereq_,module,exports){ +},{"12":12,"124":124,"150":150,"157":157,"158":158,"24":24,"34":34,"82":82}],40:[function(_dereq_,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -7116,7 +7175,7 @@ module.exports = ReactDOMInput; 'use strict'; var DOMProperty = _dereq_(11); -var ReactComponentTreeHook = _dereq_(132); +var ReactComponentTreeHook = _dereq_(131); var warning = _dereq_(157); @@ -7195,7 +7254,7 @@ var ReactDOMInvalidARIAHook = { }; module.exports = ReactDOMInvalidARIAHook; -},{"11":11,"132":132,"157":157}],41:[function(_dereq_,module,exports){ +},{"11":11,"131":131,"157":157}],41:[function(_dereq_,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -7208,7 +7267,7 @@ module.exports = ReactDOMInvalidARIAHook; 'use strict'; -var ReactComponentTreeHook = _dereq_(132); +var ReactComponentTreeHook = _dereq_(131); var warning = _dereq_(157); @@ -7238,7 +7297,7 @@ var ReactDOMNullInputValuePropHook = { }; module.exports = ReactDOMNullInputValuePropHook; -},{"132":132,"157":157}],42:[function(_dereq_,module,exports){ +},{"131":131,"157":157}],42:[function(_dereq_,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -7253,7 +7312,7 @@ module.exports = ReactDOMNullInputValuePropHook; var _assign = _dereq_(158); -var React = _dereq_(134); +var React = _dereq_(133); var ReactDOMComponentTree = _dereq_(34); var ReactDOMSelect = _dereq_(43); @@ -7361,7 +7420,7 @@ var ReactDOMOption = { }; module.exports = ReactDOMOption; -},{"134":134,"157":157,"158":158,"34":34,"43":43}],43:[function(_dereq_,module,exports){ +},{"133":133,"157":157,"158":158,"34":34,"43":43}],43:[function(_dereq_,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -7576,8 +7635,8 @@ module.exports = ReactDOMSelect; var ExecutionEnvironment = _dereq_(136); -var getNodeForCharacterOffset = _dereq_(118); -var getTextContentAccessor = _dereq_(119); +var getNodeForCharacterOffset = _dereq_(117); +var getTextContentAccessor = _dereq_(118); /** * While `isCollapsed` is available on the Selection object and `collapsed` @@ -7773,7 +7832,7 @@ var ReactDOMSelection = { }; module.exports = ReactDOMSelection; -},{"118":118,"119":119,"136":136}],45:[function(_dereq_,module,exports){ +},{"117":117,"118":118,"136":136}],45:[function(_dereq_,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -7786,7 +7845,7 @@ module.exports = ReactDOMSelection; 'use strict'; -var _prodInvariant = _dereq_(125), +var _prodInvariant = _dereq_(124), _assign = _dereq_(158); var DOMChildrenOperations = _dereq_(8); @@ -7795,7 +7854,7 @@ var ReactDOMComponentTree = _dereq_(34); var escapeTextContentForBrowser = _dereq_(107); var invariant = _dereq_(150); -var validateDOMNesting = _dereq_(131); +var validateDOMNesting = _dereq_(130); /** * Text nodes violate a couple assumptions that React makes about components: @@ -7937,7 +7996,7 @@ _assign(ReactDOMTextComponent.prototype, { }); module.exports = ReactDOMTextComponent; -},{"107":107,"125":125,"131":131,"150":150,"158":158,"34":34,"8":8,"9":9}],46:[function(_dereq_,module,exports){ +},{"107":107,"124":124,"130":130,"150":150,"158":158,"34":34,"8":8,"9":9}],46:[function(_dereq_,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -7950,7 +8009,7 @@ module.exports = ReactDOMTextComponent; 'use strict'; -var _prodInvariant = _dereq_(125), +var _prodInvariant = _dereq_(124), _assign = _dereq_(158); var LinkedValueUtils = _dereq_(24); @@ -8097,7 +8156,7 @@ function _handleChange(event) { } module.exports = ReactDOMTextarea; -},{"125":125,"150":150,"157":157,"158":158,"24":24,"34":34,"82":82}],47:[function(_dereq_,module,exports){ +},{"124":124,"150":150,"157":157,"158":158,"24":24,"34":34,"82":82}],47:[function(_dereq_,module,exports){ /** * Copyright 2015-present, Facebook, Inc. * All rights reserved. @@ -8110,7 +8169,7 @@ module.exports = ReactDOMTextarea; 'use strict'; -var _prodInvariant = _dereq_(125); +var _prodInvariant = _dereq_(124); var invariant = _dereq_(150); @@ -8233,7 +8292,7 @@ module.exports = { traverseTwoPhase: traverseTwoPhase, traverseEnterLeave: traverseEnterLeave }; -},{"125":125,"150":150}],48:[function(_dereq_,module,exports){ +},{"124":124,"150":150}],48:[function(_dereq_,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -8246,7 +8305,7 @@ module.exports = { 'use strict'; -var React = _dereq_(134); +var React = _dereq_(133); var ReactDOM = _dereq_(31); var ReactDOMUMDEntry = ReactDOM; @@ -8267,7 +8326,7 @@ if (React.addons) { } module.exports = ReactDOMUMDEntry; -},{"134":134,"31":31,"71":71,"80":80}],49:[function(_dereq_,module,exports){ +},{"133":133,"31":31,"71":71,"80":80}],49:[function(_dereq_,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -8282,7 +8341,7 @@ module.exports = ReactDOMUMDEntry; var DOMProperty = _dereq_(11); var EventPluginRegistry = _dereq_(18); -var ReactComponentTreeHook = _dereq_(132); +var ReactComponentTreeHook = _dereq_(131); var warning = _dereq_(157); @@ -8379,7 +8438,7 @@ var ReactDOMUnknownPropertyHook = { }; module.exports = ReactDOMUnknownPropertyHook; -},{"11":11,"132":132,"157":157,"18":18}],50:[function(_dereq_,module,exports){ +},{"11":11,"131":131,"157":157,"18":18}],50:[function(_dereq_,module,exports){ /** * Copyright 2016-present, Facebook, Inc. * All rights reserved. @@ -8395,7 +8454,7 @@ module.exports = ReactDOMUnknownPropertyHook; var ReactInvalidSetStateWarningHook = _dereq_(65); var ReactHostOperationHistoryHook = _dereq_(60); -var ReactComponentTreeHook = _dereq_(132); +var ReactComponentTreeHook = _dereq_(131); var ExecutionEnvironment = _dereq_(136); var performanceNow = _dereq_(155); @@ -8560,9 +8619,7 @@ function resumeCurrentLifeCycleTimer() { } var lastMarkTimeStamp = 0; -var canUsePerformanceMeasure = -// $FlowFixMe https://github.com/facebook/flow/issues/2345 -typeof performance !== 'undefined' && typeof performance.mark === 'function' && typeof performance.clearMarks === 'function' && typeof performance.measure === 'function' && typeof performance.clearMeasures === 'function'; +var canUsePerformanceMeasure = typeof performance !== 'undefined' && typeof performance.mark === 'function' && typeof performance.clearMarks === 'function' && typeof performance.measure === 'function' && typeof performance.clearMeasures === 'function'; function shouldMark(debugID) { if (!isProfiling || !canUsePerformanceMeasure) { @@ -8740,7 +8797,7 @@ if (/[?&]react_perf\b/.test(url)) { } module.exports = ReactDebugTool; -},{"132":132,"136":136,"155":155,"157":157,"60":60,"65":65}],51:[function(_dereq_,module,exports){ +},{"131":131,"136":136,"155":155,"157":157,"60":60,"65":65}],51:[function(_dereq_,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -9012,7 +9069,6 @@ if ("development" !== 'production') { var evtType = 'react-' + name; fakeNode.addEventListener(evtType, boundFunc, false); var evt = document.createEvent('Event'); - // $FlowFixMe https://github.com/facebook/flow/issues/2336 evt.initEvent(evtType, false, false); fakeNode.dispatchEvent(evt); fakeNode.removeEventListener(evtType, boundFunc, false); @@ -9244,7 +9300,7 @@ module.exports = ReactFeatureFlags; 'use strict'; -var _prodInvariant = _dereq_(125); +var _prodInvariant = _dereq_(124); var invariant = _dereq_(150); @@ -9299,7 +9355,7 @@ var ReactHostComponent = { }; module.exports = ReactHostComponent; -},{"125":125,"150":150}],60:[function(_dereq_,module,exports){ +},{"124":124,"150":150}],60:[function(_dereq_,module,exports){ /** * Copyright 2016-present, Facebook, Inc. * All rights reserved. @@ -9663,13 +9719,13 @@ module.exports = ReactMarkupChecksum; 'use strict'; -var _prodInvariant = _dereq_(125); +var _prodInvariant = _dereq_(124); var DOMLazyTree = _dereq_(9); var DOMProperty = _dereq_(11); -var React = _dereq_(134); +var React = _dereq_(133); var ReactBrowserEventEmitter = _dereq_(26); -var ReactCurrentOwner = _dereq_(133); +var ReactCurrentOwner = _dereq_(132); var ReactDOMComponentTree = _dereq_(34); var ReactDOMContainerInfo = _dereq_(35); var ReactDOMFeatureFlags = _dereq_(37); @@ -9682,10 +9738,10 @@ var ReactUpdateQueue = _dereq_(81); var ReactUpdates = _dereq_(82); var emptyObject = _dereq_(143); -var instantiateReactComponent = _dereq_(121); +var instantiateReactComponent = _dereq_(120); var invariant = _dereq_(150); -var setInnerHTML = _dereq_(127); -var shouldUpdateReactComponent = _dereq_(129); +var setInnerHTML = _dereq_(126); +var shouldUpdateReactComponent = _dereq_(128); var warning = _dereq_(157); var ATTR_NAME = DOMProperty.ID_ATTRIBUTE_NAME; @@ -10188,7 +10244,7 @@ var ReactMount = { }; module.exports = ReactMount; -},{"11":11,"121":121,"125":125,"127":127,"129":129,"133":133,"134":134,"143":143,"150":150,"157":157,"26":26,"34":34,"35":35,"37":37,"58":58,"63":63,"64":64,"66":66,"75":75,"81":81,"82":82,"9":9}],68:[function(_dereq_,module,exports){ +},{"11":11,"120":120,"124":124,"126":126,"128":128,"132":132,"133":133,"143":143,"150":150,"157":157,"26":26,"34":34,"35":35,"37":37,"58":58,"63":63,"64":64,"66":66,"75":75,"81":81,"82":82,"9":9}],68:[function(_dereq_,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -10201,13 +10257,13 @@ module.exports = ReactMount; 'use strict'; -var _prodInvariant = _dereq_(125); +var _prodInvariant = _dereq_(124); var ReactComponentEnvironment = _dereq_(29); var ReactInstanceMap = _dereq_(63); var ReactInstrumentation = _dereq_(64); -var ReactCurrentOwner = _dereq_(133); +var ReactCurrentOwner = _dereq_(132); var ReactReconciler = _dereq_(75); var ReactChildReconciler = _dereq_(27); @@ -10638,7 +10694,7 @@ var ReactMultiChild = { }; module.exports = ReactMultiChild; -},{"109":109,"125":125,"133":133,"142":142,"150":150,"27":27,"29":29,"63":63,"64":64,"75":75}],69:[function(_dereq_,module,exports){ +},{"109":109,"124":124,"132":132,"142":142,"150":150,"27":27,"29":29,"63":63,"64":64,"75":75}],69:[function(_dereq_,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -10652,9 +10708,9 @@ module.exports = ReactMultiChild; 'use strict'; -var _prodInvariant = _dereq_(125); +var _prodInvariant = _dereq_(124); -var React = _dereq_(134); +var React = _dereq_(133); var invariant = _dereq_(150); @@ -10678,7 +10734,7 @@ var ReactNodeTypes = { }; module.exports = ReactNodeTypes; -},{"125":125,"134":134,"150":150}],70:[function(_dereq_,module,exports){ +},{"124":124,"133":133,"150":150}],70:[function(_dereq_,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -10692,7 +10748,7 @@ module.exports = ReactNodeTypes; 'use strict'; -var _prodInvariant = _dereq_(125); +var _prodInvariant = _dereq_(124); var invariant = _dereq_(150); @@ -10772,7 +10828,7 @@ var ReactOwner = { }; module.exports = ReactOwner; -},{"125":125,"150":150}],71:[function(_dereq_,module,exports){ +},{"124":124,"150":150}],71:[function(_dereq_,module,exports){ /** * Copyright 2016-present, Facebook, Inc. * All rights reserved. @@ -11992,21 +12048,27 @@ module.exports = ReactServerUpdateQueue; 'use strict'; -var _prodInvariant = _dereq_(125), +var _prodInvariant = _dereq_(124), _assign = _dereq_(158); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } -var React = _dereq_(134); -var ReactDefaultInjection = _dereq_(52); +var React = _dereq_(133); var ReactCompositeComponent = _dereq_(30); +var ReactDefaultBatchingStrategy = _dereq_(51); var ReactReconciler = _dereq_(75); +var ReactReconcileTransaction = _dereq_(74); var ReactUpdates = _dereq_(82); var emptyObject = _dereq_(143); -var getNextDebugID = _dereq_(117); +var getNextDebugID = _dereq_(134); var invariant = _dereq_(150); +function injectDefaults() { + ReactUpdates.injection.injectReconcileTransaction(ReactReconcileTransaction); + ReactUpdates.injection.injectBatchingStrategy(ReactDefaultBatchingStrategy); +} + var NoopInternalComponent = function () { function NoopInternalComponent(element) { _classCallCheck(this, NoopInternalComponent); @@ -12077,7 +12139,7 @@ var ReactShallowRenderer = function () { // Ensure we've done the default injections. This might not be true in the // case of a simple test that only requires React and the TestUtils in // conjunction with an inline-requires transform. - ReactDefaultInjection.inject(); + injectDefaults(); !React.isValidElement(element) ? "development" !== 'production' ? invariant(false, 'ReactShallowRenderer render(): Invalid component element.%s', typeof element === 'function' ? ' Instead of passing a component class, make sure to instantiate ' + 'it by passing it to React.createElement.' : '') : _prodInvariant('12', typeof element === 'function' ? ' Instead of passing a component class, make sure to instantiate ' + 'it by passing it to React.createElement.' : '') : void 0; !(typeof element.type !== 'string') ? "development" !== 'production' ? invariant(false, 'ReactShallowRenderer render(): Shallow rendering works only with custom components, not primitives (%s). Instead of calling `.render(el)` and inspecting the rendered output, look at `el.props` directly instead.', element.type) : _prodInvariant('13', element.type) : void 0; @@ -12113,8 +12175,12 @@ var ReactShallowRenderer = function () { return ReactShallowRenderer; }(); +ReactShallowRenderer.createRenderer = function () { + return new ReactShallowRenderer(); +}; + module.exports = ReactShallowRenderer; -},{"117":117,"125":125,"134":134,"143":143,"150":150,"158":158,"30":30,"52":52,"75":75,"82":82}],80:[function(_dereq_,module,exports){ +},{"124":124,"133":133,"134":134,"143":143,"150":150,"158":158,"30":30,"51":51,"74":74,"75":75,"82":82}],80:[function(_dereq_,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -12127,14 +12193,14 @@ module.exports = ReactShallowRenderer; 'use strict'; -var _prodInvariant = _dereq_(125), +var _prodInvariant = _dereq_(124), _assign = _dereq_(158); var EventConstants = _dereq_(16); var EventPluginHub = _dereq_(17); var EventPluginRegistry = _dereq_(18); var EventPropagators = _dereq_(20); -var React = _dereq_(134); +var React = _dereq_(133); var ReactDOM = _dereq_(31); var ReactDOMComponentTree = _dereq_(34); var ReactBrowserEventEmitter = _dereq_(26); @@ -12145,11 +12211,23 @@ var ReactShallowRenderer = _dereq_(79); var findDOMNode = _dereq_(108); var invariant = _dereq_(150); +var warning = _dereq_(157); var topLevelTypes = EventConstants.topLevelTypes; function Event(suffix) {} +// In react 16+ shallowRenderer will not be accessible via ReactTestUtils.createRenderer() +// Instead it will be available via react-test-renderer/shallow +// Maintain backwards compat for 15.5.0 release, but warn about using the deprecated method +var hasWarnedAboutCreateRenderer = false; +function createRendererWithWarning() { + "development" !== 'production' ? warning(hasWarnedAboutCreateRenderer, 'Shallow renderer has been moved to react-test-renderer/shallow. ' + 'Update references to remove this warning.') : void 0; + hasWarnedAboutCreateRenderer = true; + + return new ReactShallowRenderer(); +} + /** * @class ReactTestUtils */ @@ -12406,9 +12484,7 @@ var ReactTestUtils = { }; }, - createRenderer: function () { - return new ReactShallowRenderer(); - }, + createRenderer: createRendererWithWarning, Simulate: null, SimulateNative: {} @@ -12526,7 +12602,7 @@ Object.keys(topLevelTypes).forEach(function (eventType) { }); module.exports = ReactTestUtils; -},{"108":108,"125":125,"134":134,"150":150,"158":158,"16":16,"17":17,"18":18,"20":20,"26":26,"31":31,"34":34,"63":63,"79":79,"82":82,"91":91}],81:[function(_dereq_,module,exports){ +},{"108":108,"124":124,"133":133,"150":150,"157":157,"158":158,"16":16,"17":17,"18":18,"20":20,"26":26,"31":31,"34":34,"63":63,"79":79,"82":82,"91":91}],81:[function(_dereq_,module,exports){ /** * Copyright 2015-present, Facebook, Inc. * All rights reserved. @@ -12539,9 +12615,9 @@ module.exports = ReactTestUtils; 'use strict'; -var _prodInvariant = _dereq_(125); +var _prodInvariant = _dereq_(124); -var ReactCurrentOwner = _dereq_(133); +var ReactCurrentOwner = _dereq_(132); var ReactInstanceMap = _dereq_(63); var ReactInstrumentation = _dereq_(64); var ReactUpdates = _dereq_(82); @@ -12697,7 +12773,7 @@ var ReactUpdateQueue = { * @param {object} completeState Next state. * @internal */ - enqueueReplaceState: function (publicInstance, completeState) { + enqueueReplaceState: function (publicInstance, completeState, callback) { var internalInstance = getInternalInstanceReadyForUpdate(publicInstance, 'replaceState'); if (!internalInstance) { @@ -12707,6 +12783,16 @@ var ReactUpdateQueue = { internalInstance._pendingStateQueue = [completeState]; internalInstance._pendingReplaceState = true; + // Future-proof 15.5 + if (callback !== undefined && callback !== null) { + ReactUpdateQueue.validateCallback(callback, 'replaceState'); + if (internalInstance._pendingCallbacks) { + internalInstance._pendingCallbacks.push(callback); + } else { + internalInstance._pendingCallbacks = [callback]; + } + } + enqueueUpdate(internalInstance); }, @@ -12752,7 +12838,7 @@ var ReactUpdateQueue = { }; module.exports = ReactUpdateQueue; -},{"125":125,"133":133,"150":150,"157":157,"63":63,"64":64,"82":82}],82:[function(_dereq_,module,exports){ +},{"124":124,"132":132,"150":150,"157":157,"63":63,"64":64,"82":82}],82:[function(_dereq_,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -12765,7 +12851,7 @@ module.exports = ReactUpdateQueue; 'use strict'; -var _prodInvariant = _dereq_(125), +var _prodInvariant = _dereq_(124), _assign = _dereq_(158); var CallbackQueue = _dereq_(6); @@ -13003,7 +13089,7 @@ var ReactUpdates = { }; module.exports = ReactUpdates; -},{"100":100,"125":125,"150":150,"158":158,"25":25,"58":58,"6":6,"75":75}],83:[function(_dereq_,module,exports){ +},{"100":100,"124":124,"150":150,"158":158,"25":25,"58":58,"6":6,"75":75}],83:[function(_dereq_,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -13016,7 +13102,7 @@ module.exports = ReactUpdates; 'use strict'; -module.exports = '15.4.2'; +module.exports = '15.5.0'; },{}],84:[function(_dereq_,module,exports){ /** * Copyright 2013-present, Facebook, Inc. @@ -13339,7 +13425,7 @@ var ReactInputSelection = _dereq_(62); var SyntheticEvent = _dereq_(91); var getActiveElement = _dereq_(145); -var isTextInputElement = _dereq_(123); +var isTextInputElement = _dereq_(122); var shallowEqual = _dereq_(156); var skipSelectionChangeEvent = ExecutionEnvironment.canUseDOM && 'documentMode' in document && document.documentMode <= 11; @@ -13510,7 +13596,7 @@ var SelectEventPlugin = { }; module.exports = SelectEventPlugin; -},{"123":123,"136":136,"145":145,"156":156,"20":20,"34":34,"62":62,"91":91}],86:[function(_dereq_,module,exports){ +},{"122":122,"136":136,"145":145,"156":156,"20":20,"34":34,"62":62,"91":91}],86:[function(_dereq_,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -13524,7 +13610,7 @@ module.exports = SelectEventPlugin; 'use strict'; -var _prodInvariant = _dereq_(125); +var _prodInvariant = _dereq_(124); var EventListener = _dereq_(135); var EventPropagators = _dereq_(20); @@ -13738,7 +13824,7 @@ var SimpleEventPlugin = { }; module.exports = SimpleEventPlugin; -},{"111":111,"125":125,"135":135,"142":142,"150":150,"20":20,"34":34,"87":87,"88":88,"90":90,"91":91,"92":92,"94":94,"95":95,"96":96,"97":97,"98":98,"99":99}],87:[function(_dereq_,module,exports){ +},{"111":111,"124":124,"135":135,"142":142,"150":150,"20":20,"34":34,"87":87,"88":88,"90":90,"91":91,"92":92,"94":94,"95":95,"96":96,"97":97,"98":98,"99":99}],87:[function(_dereq_,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -14595,7 +14681,7 @@ module.exports = SyntheticWheelEvent; 'use strict'; -var _prodInvariant = _dereq_(125); +var _prodInvariant = _dereq_(124); var invariant = _dereq_(150); @@ -14806,7 +14892,7 @@ var TransactionImpl = { }; module.exports = TransactionImpl; -},{"125":125,"150":150}],101:[function(_dereq_,module,exports){ +},{"124":124,"150":150}],101:[function(_dereq_,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -14847,7 +14933,7 @@ module.exports = ViewportMetrics; 'use strict'; -var _prodInvariant = _dereq_(125); +var _prodInvariant = _dereq_(124); var invariant = _dereq_(150); @@ -14891,7 +14977,7 @@ function accumulateInto(current, next) { } module.exports = accumulateInto; -},{"125":125,"150":150}],103:[function(_dereq_,module,exports){ +},{"124":124,"150":150}],103:[function(_dereq_,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -14949,7 +15035,7 @@ module.exports = adler32; 'use strict'; -var _prodInvariant = _dereq_(125); +var _prodInvariant = _dereq_(124); var ReactPropTypeLocationNames = _dereq_(72); var ReactPropTypesSecret = _dereq_(73); @@ -14965,7 +15051,7 @@ if (typeof process !== 'undefined' && process.env && "development" === 'test') { // https://github.com/facebook/react/issues/7240 // Remove the inline requires when we don't need them anymore: // https://github.com/facebook/react/pull/7178 - ReactComponentTreeHook = _dereq_(132); + ReactComponentTreeHook = _dereq_(131); } var loggedTypeFailures = {}; @@ -15007,7 +15093,7 @@ function checkReactTypeSpec(typeSpecs, values, location, componentName, element, if ("development" !== 'production') { if (!ReactComponentTreeHook) { - ReactComponentTreeHook = _dereq_(132); + ReactComponentTreeHook = _dereq_(131); } if (debugID !== null) { componentStackInfo = ReactComponentTreeHook.getStackAddendumByID(debugID); @@ -15024,7 +15110,7 @@ function checkReactTypeSpec(typeSpecs, values, location, componentName, element, module.exports = checkReactTypeSpec; }).call(this,undefined) -},{"125":125,"132":132,"150":150,"157":157,"72":72,"73":73}],105:[function(_dereq_,module,exports){ +},{"124":124,"131":131,"150":150,"157":157,"72":72,"73":73}],105:[function(_dereq_,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -15271,9 +15357,9 @@ module.exports = escapeTextContentForBrowser; 'use strict'; -var _prodInvariant = _dereq_(125); +var _prodInvariant = _dereq_(124); -var ReactCurrentOwner = _dereq_(133); +var ReactCurrentOwner = _dereq_(132); var ReactDOMComponentTree = _dereq_(34); var ReactInstanceMap = _dereq_(63); @@ -15318,7 +15404,7 @@ function findDOMNode(componentOrElement) { } module.exports = findDOMNode; -},{"115":115,"125":125,"133":133,"150":150,"157":157,"34":34,"63":63}],109:[function(_dereq_,module,exports){ +},{"115":115,"124":124,"132":132,"150":150,"157":157,"34":34,"63":63}],109:[function(_dereq_,module,exports){ (function (process){ /** * Copyright 2013-present, Facebook, Inc. @@ -15334,7 +15420,7 @@ module.exports = findDOMNode; 'use strict'; var KeyEscapeUtils = _dereq_(23); -var traverseAllChildren = _dereq_(130); +var traverseAllChildren = _dereq_(129); var warning = _dereq_(157); var ReactComponentTreeHook; @@ -15345,7 +15431,7 @@ if (typeof process !== 'undefined' && process.env && "development" === 'test') { // https://github.com/facebook/react/issues/7240 // Remove the inline requires when we don't need them anymore: // https://github.com/facebook/react/pull/7178 - ReactComponentTreeHook = _dereq_(132); + ReactComponentTreeHook = _dereq_(131); } /** @@ -15361,7 +15447,7 @@ function flattenSingleChildIntoContext(traverseContext, child, name, selfDebugID var keyUnique = result[name] === undefined; if ("development" !== 'production') { if (!ReactComponentTreeHook) { - ReactComponentTreeHook = _dereq_(132); + ReactComponentTreeHook = _dereq_(131); } if (!keyUnique) { "development" !== 'production' ? warning(false, 'flattenChildren(...): Encountered two children with the same key, ' + '`%s`. Child keys must be unique; when two children share a key, only ' + 'the first child will be used.%s', KeyEscapeUtils.unescape(name), ReactComponentTreeHook.getStackAddendumByID(selfDebugID)) : void 0; @@ -15396,7 +15482,7 @@ function flattenChildren(children, selfDebugID) { module.exports = flattenChildren; }).call(this,undefined) -},{"130":130,"132":132,"157":157,"23":23}],110:[function(_dereq_,module,exports){ +},{"129":129,"131":131,"157":157,"23":23}],110:[function(_dereq_,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -15729,27 +15815,6 @@ function getIteratorFn(maybeIterable) { module.exports = getIteratorFn; },{}],117:[function(_dereq_,module,exports){ -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * - */ - -'use strict'; - -var nextDebugID = 1; - -function getNextDebugID() { - return nextDebugID++; -} - -module.exports = getNextDebugID; -},{}],118:[function(_dereq_,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -15823,7 +15888,7 @@ function getNodeForCharacterOffset(root, offset) { } module.exports = getNodeForCharacterOffset; -},{}],119:[function(_dereq_,module,exports){ +},{}],118:[function(_dereq_,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -15856,7 +15921,7 @@ function getTextContentAccessor() { } module.exports = getTextContentAccessor; -},{"136":136}],120:[function(_dereq_,module,exports){ +},{"136":136}],119:[function(_dereq_,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -15957,7 +16022,7 @@ function getVendorPrefixedEventName(eventName) { } module.exports = getVendorPrefixedEventName; -},{"136":136}],121:[function(_dereq_,module,exports){ +},{"136":136}],120:[function(_dereq_,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -15970,14 +16035,14 @@ module.exports = getVendorPrefixedEventName; 'use strict'; -var _prodInvariant = _dereq_(125), +var _prodInvariant = _dereq_(124), _assign = _dereq_(158); var ReactCompositeComponent = _dereq_(30); var ReactEmptyComponent = _dereq_(54); var ReactHostComponent = _dereq_(59); -var getNextDebugID = _dereq_(117); +var getNextDebugID = _dereq_(134); var invariant = _dereq_(150); var warning = _dereq_(157); @@ -15985,9 +16050,6 @@ var warning = _dereq_(157); var ReactCompositeComponentWrapper = function (element) { this.construct(element); }; -_assign(ReactCompositeComponentWrapper.prototype, ReactCompositeComponent, { - _instantiateReactComponent: instantiateReactComponent -}); function getDeclarationErrorAddendum(owner) { if (owner) { @@ -16084,8 +16146,12 @@ function instantiateReactComponent(node, shouldHaveDebugID) { return instance; } +_assign(ReactCompositeComponentWrapper.prototype, ReactCompositeComponent, { + _instantiateReactComponent: instantiateReactComponent +}); + module.exports = instantiateReactComponent; -},{"117":117,"125":125,"150":150,"157":157,"158":158,"30":30,"54":54,"59":59}],122:[function(_dereq_,module,exports){ +},{"124":124,"134":134,"150":150,"157":157,"158":158,"30":30,"54":54,"59":59}],121:[function(_dereq_,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -16145,7 +16211,7 @@ function isEventSupported(eventNameSuffix, capture) { } module.exports = isEventSupported; -},{"136":136}],123:[function(_dereq_,module,exports){ +},{"136":136}],122:[function(_dereq_,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -16196,7 +16262,7 @@ function isTextInputElement(elem) { } module.exports = isTextInputElement; -},{}],124:[function(_dereq_,module,exports){ +},{}],123:[function(_dereq_,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -16222,7 +16288,7 @@ function quoteAttributeValueForBrowser(value) { } module.exports = quoteAttributeValueForBrowser; -},{"107":107}],125:[function(_dereq_,module,exports){ +},{"107":107}],124:[function(_dereq_,module,exports){ /** * Copyright (c) 2013-present, Facebook, Inc. * All rights reserved. @@ -16261,7 +16327,7 @@ function reactProdInvariant(code) { } module.exports = reactProdInvariant; -},{}],126:[function(_dereq_,module,exports){ +},{}],125:[function(_dereq_,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -16277,7 +16343,7 @@ module.exports = reactProdInvariant; var ReactMount = _dereq_(67); module.exports = ReactMount.renderSubtreeIntoContainer; -},{"67":67}],127:[function(_dereq_,module,exports){ +},{"67":67}],126:[function(_dereq_,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -16375,7 +16441,7 @@ if (ExecutionEnvironment.canUseDOM) { } module.exports = setInnerHTML; -},{"10":10,"105":105,"136":136}],128:[function(_dereq_,module,exports){ +},{"10":10,"105":105,"136":136}],127:[function(_dereq_,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -16390,7 +16456,7 @@ module.exports = setInnerHTML; var ExecutionEnvironment = _dereq_(136); var escapeTextContentForBrowser = _dereq_(107); -var setInnerHTML = _dereq_(127); +var setInnerHTML = _dereq_(126); /** * Set the textContent property of a node, ensuring that whitespace is preserved @@ -16427,7 +16493,7 @@ if (ExecutionEnvironment.canUseDOM) { } module.exports = setTextContent; -},{"107":107,"127":127,"136":136}],129:[function(_dereq_,module,exports){ +},{"107":107,"126":126,"136":136}],128:[function(_dereq_,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -16469,7 +16535,7 @@ function shouldUpdateReactComponent(prevElement, nextElement) { } module.exports = shouldUpdateReactComponent; -},{}],130:[function(_dereq_,module,exports){ +},{}],129:[function(_dereq_,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -16482,9 +16548,9 @@ module.exports = shouldUpdateReactComponent; 'use strict'; -var _prodInvariant = _dereq_(125); +var _prodInvariant = _dereq_(124); -var ReactCurrentOwner = _dereq_(133); +var ReactCurrentOwner = _dereq_(132); var REACT_ELEMENT_TYPE = _dereq_(53); var getIteratorFn = _dereq_(116); @@ -16645,7 +16711,7 @@ function traverseAllChildren(children, callback, traverseContext) { } module.exports = traverseAllChildren; -},{"116":116,"125":125,"133":133,"150":150,"157":157,"23":23,"53":53}],131:[function(_dereq_,module,exports){ +},{"116":116,"124":124,"132":132,"150":150,"157":157,"23":23,"53":53}],130:[function(_dereq_,module,exports){ /** * Copyright 2015-present, Facebook, Inc. * All rights reserved. @@ -16872,16 +16938,11 @@ if ("development" !== 'production') { case 'section': case 'summary': case 'ul': - case 'pre': case 'listing': - case 'table': - case 'hr': - case 'xmp': - case 'h1': case 'h2': case 'h3': @@ -17027,7 +17088,7 @@ if ("development" !== 'production') { } module.exports = validateDOMNesting; -},{"142":142,"157":157,"158":158}],132:[function(_dereq_,module,exports){ +},{"142":142,"157":157,"158":158}],131:[function(_dereq_,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -17045,7 +17106,7 @@ module.exports = validateDOMNesting; var ReactInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; module.exports = ReactInternals.ReactComponentTreeHook; -},{}],133:[function(_dereq_,module,exports){ +},{}],132:[function(_dereq_,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -17063,7 +17124,7 @@ module.exports = ReactInternals.ReactComponentTreeHook; var ReactInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; module.exports = ReactInternals.ReactCurrentOwner; -},{}],134:[function(_dereq_,module,exports){ +},{}],133:[function(_dereq_,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -17079,6 +17140,24 @@ module.exports = ReactInternals.ReactCurrentOwner; 'use strict'; module.exports = React; +},{}],134:[function(_dereq_,module,exports){ +/** + * Copyright 2013-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + */ + +/* globals React */ + +'use strict'; + +var ReactInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; + +module.exports = ReactInternals.getNextDebugID; },{}],135:[function(_dereq_,module,exports){ 'use strict'; @@ -17630,15 +17709,19 @@ module.exports = focusNode; * * The activeElement will be null only if the document or document body is not * yet defined. + * + * @param {?DOMDocument} doc Defaults to current document. + * @return {?DOMElement} */ -function getActiveElement() /*?DOMElement*/{ - if (typeof document === 'undefined') { +function getActiveElement(doc) /*?DOMElement*/{ + doc = doc || (typeof document !== 'undefined' ? document : undefined); + if (typeof doc === 'undefined') { return null; } try { - return document.activeElement || document.body; + return doc.activeElement || doc.body; } catch (e) { - return document.body; + return doc.body; } } @@ -17764,10 +17847,10 @@ module.exports = getMarkupWrap; */ function getUnboundedScrollPosition(scrollable) { - if (scrollable === window) { + if (scrollable.Window && scrollable instanceof scrollable.Window) { return { - x: window.pageXOffset || document.documentElement.scrollLeft, - y: window.pageYOffset || document.documentElement.scrollTop + x: scrollable.pageXOffset || scrollable.document.documentElement.scrollLeft, + y: scrollable.pageYOffset || scrollable.document.documentElement.scrollTop }; } return { @@ -17924,7 +18007,9 @@ module.exports = invariant; * @return {boolean} Whether or not the object is a DOM node. */ function isNode(object) { - return !!(object && (typeof Node === 'function' ? object instanceof Node : typeof object === 'object' && typeof object.nodeType === 'number' && typeof object.nodeName === 'string')); + var doc = object ? object.ownerDocument || object : document; + var defaultView = doc.defaultView || window; + return !!(object && (typeof defaultView.Node === 'function' ? object instanceof defaultView.Node : typeof object === 'object' && typeof object.nodeType === 'number' && typeof object.nodeName === 'string')); } module.exports = isNode; @@ -18176,8 +18261,15 @@ if ("development" !== 'production') { module.exports = warning; },{"142":142}],158:[function(_dereq_,module,exports){ +/* +object-assign +(c) Sindre Sorhus +@license MIT +*/ + 'use strict'; /* eslint-disable no-unused-vars */ +var getOwnPropertySymbols = Object.getOwnPropertySymbols; var hasOwnProperty = Object.prototype.hasOwnProperty; var propIsEnumerable = Object.prototype.propertyIsEnumerable; @@ -18198,7 +18290,7 @@ function shouldUseNative() { // Detect buggy property enumeration order in older V8 versions. // https://bugs.chromium.org/p/v8/issues/detail?id=4118 - var test1 = new String('abc'); // eslint-disable-line + var test1 = new String('abc'); // eslint-disable-line no-new-wrappers test1[5] = 'de'; if (Object.getOwnPropertyNames(test1)[0] === '5') { return false; @@ -18227,7 +18319,7 @@ function shouldUseNative() { } return true; - } catch (e) { + } catch (err) { // We don't expect any of the above to throw, but better to be safe. return false; } @@ -18247,8 +18339,8 @@ module.exports = shouldUseNative() ? Object.assign : function (target, source) { } } - if (Object.getOwnPropertySymbols) { - symbols = Object.getOwnPropertySymbols(from); + if (getOwnPropertySymbols) { + symbols = getOwnPropertySymbols(from); for (var i = 0; i < symbols.length; i++) { if (propIsEnumerable.call(from, symbols[i])) { to[symbols[i]] = from[symbols[i]]; @@ -18260,6 +18352,571 @@ module.exports = shouldUseNative() ? Object.assign : function (target, source) { return to; }; +},{}],159:[function(_dereq_,module,exports){ +/** + * Copyright 2013-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +'use strict'; + +var invariant = _dereq_(150); +var warning = _dereq_(157); + +var ReactPropTypesSecret = _dereq_(161); + +var loggedTypeFailures = {}; + +/** + * Assert that the values match with the type specs. + * Error messages are memorized and will only be shown once. + * + * @param {object} typeSpecs Map of name to a ReactPropType + * @param {object} values Runtime values that need to be type-checked + * @param {string} location e.g. "prop", "context", "child context" + * @param {string} componentName Name of the component for error messages. + * @param {?Function} getStack Returns the component stack. + * @private + */ +function checkPropTypes(typeSpecs, values, location, componentName, getStack) { + if ("development" !== 'production') { + for (var typeSpecName in typeSpecs) { + if (typeSpecs.hasOwnProperty(typeSpecName)) { + var error; + // Prop type validation may throw. In case they do, we don't want to + // fail the render phase where it didn't fail before. So we log it. + // After these have been cleaned up, we'll let them throw. + try { + // This is intentionally an invariant that gets caught. It's the same + // behavior as without this statement except with a better message. + invariant(typeof typeSpecs[typeSpecName] === 'function', '%s: %s type `%s` is invalid; it must be a function, usually from ' + 'React.PropTypes.', componentName || 'React class', location, typeSpecName); + error = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, ReactPropTypesSecret); + } catch (ex) { + error = ex; + } + "development" !== 'production' ? warning(!error || error instanceof Error, '%s: type specification of %s `%s` is invalid; the type checker ' + 'function must return `null` or an `Error` but returned a %s. ' + 'You may have forgotten to pass an argument to the type checker ' + 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' + 'shape all require an argument).', componentName || 'React class', location, typeSpecName, typeof error) : void 0; + if (error instanceof Error && !(error.message in loggedTypeFailures)) { + // Only monitor this failure once because there tends to be a lot of the + // same error. + loggedTypeFailures[error.message] = true; + + var stack = getStack ? getStack() : ''; + + "development" !== 'production' ? warning(false, 'Failed %s type: %s%s', location, error.message, stack != null ? stack : '') : void 0; + } + } + } + } +} + +module.exports = checkPropTypes; + +},{"150":150,"157":157,"161":161}],160:[function(_dereq_,module,exports){ +/** + * Copyright 2013-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +'use strict'; + +var emptyFunction = _dereq_(142); +var invariant = _dereq_(150); +var warning = _dereq_(157); + +var ReactPropTypesSecret = _dereq_(161); +var checkPropTypes = _dereq_(159); + +module.exports = function (isValidElement) { + /* global Symbol */ + var ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator; + var FAUX_ITERATOR_SYMBOL = '@@iterator'; // Before Symbol spec. + + /** + * Returns the iterator method function contained on the iterable object. + * + * Be sure to invoke the function with the iterable as context: + * + * var iteratorFn = getIteratorFn(myIterable); + * if (iteratorFn) { + * var iterator = iteratorFn.call(myIterable); + * ... + * } + * + * @param {?object} maybeIterable + * @return {?function} + */ + function getIteratorFn(maybeIterable) { + var iteratorFn = maybeIterable && (ITERATOR_SYMBOL && maybeIterable[ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL]); + if (typeof iteratorFn === 'function') { + return iteratorFn; + } + } + + /** + * Collection of methods that allow declaration and validation of props that are + * supplied to React components. Example usage: + * + * var Props = require('ReactPropTypes'); + * var MyArticle = React.createClass({ + * propTypes: { + * // An optional string prop named "description". + * description: Props.string, + * + * // A required enum prop named "category". + * category: Props.oneOf(['News','Photos']).isRequired, + * + * // A prop named "dialog" that requires an instance of Dialog. + * dialog: Props.instanceOf(Dialog).isRequired + * }, + * render: function() { ... } + * }); + * + * A more formal specification of how these methods are used: + * + * type := array|bool|func|object|number|string|oneOf([...])|instanceOf(...) + * decl := ReactPropTypes.{type}(.isRequired)? + * + * Each and every declaration produces a function with the same signature. This + * allows the creation of custom validation functions. For example: + * + * var MyLink = React.createClass({ + * propTypes: { + * // An optional string or URI prop named "href". + * href: function(props, propName, componentName) { + * var propValue = props[propName]; + * if (propValue != null && typeof propValue !== 'string' && + * !(propValue instanceof URI)) { + * return new Error( + * 'Expected a string or an URI for ' + propName + ' in ' + + * componentName + * ); + * } + * } + * }, + * render: function() {...} + * }); + * + * @internal + */ + + var ANONYMOUS = '<>'; + + var ReactPropTypes; + + if ("development" !== 'production') { + // Keep in sync with production version below + ReactPropTypes = { + array: createPrimitiveTypeChecker('array'), + bool: createPrimitiveTypeChecker('boolean'), + func: createPrimitiveTypeChecker('function'), + number: createPrimitiveTypeChecker('number'), + object: createPrimitiveTypeChecker('object'), + string: createPrimitiveTypeChecker('string'), + symbol: createPrimitiveTypeChecker('symbol'), + + any: createAnyTypeChecker(), + arrayOf: createArrayOfTypeChecker, + element: createElementTypeChecker(), + instanceOf: createInstanceTypeChecker, + node: createNodeChecker(), + objectOf: createObjectOfTypeChecker, + oneOf: createEnumTypeChecker, + oneOfType: createUnionTypeChecker, + shape: createShapeTypeChecker + }; + } else { + var productionTypeChecker = function () { + invariant(false, 'React.PropTypes type checking code is stripped in production.'); + }; + productionTypeChecker.isRequired = productionTypeChecker; + var getProductionTypeChecker = function () { + return productionTypeChecker; + }; + // Keep in sync with development version above + ReactPropTypes = { + array: productionTypeChecker, + bool: productionTypeChecker, + func: productionTypeChecker, + number: productionTypeChecker, + object: productionTypeChecker, + string: productionTypeChecker, + symbol: productionTypeChecker, + + any: productionTypeChecker, + arrayOf: getProductionTypeChecker, + element: productionTypeChecker, + instanceOf: getProductionTypeChecker, + node: productionTypeChecker, + objectOf: getProductionTypeChecker, + oneOf: getProductionTypeChecker, + oneOfType: getProductionTypeChecker, + shape: getProductionTypeChecker + }; + } + + /** + * inlined Object.is polyfill to avoid requiring consumers ship their own + * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is + */ + /*eslint-disable no-self-compare*/ + function is(x, y) { + // SameValue algorithm + if (x === y) { + // Steps 1-5, 7-10 + // Steps 6.b-6.e: +0 != -0 + return x !== 0 || 1 / x === 1 / y; + } else { + // Step 6.a: NaN == NaN + return x !== x && y !== y; + } + } + /*eslint-enable no-self-compare*/ + + /** + * We use an Error-like object for backward compatibility as people may call + * PropTypes directly and inspect their output. However, we don't use real + * Errors anymore. We don't inspect their stack anyway, and creating them + * is prohibitively expensive if they are created too often, such as what + * happens in oneOfType() for any type before the one that matched. + */ + function PropTypeError(message) { + this.message = message; + this.stack = ''; + } + // Make `instanceof Error` still work for returned errors. + PropTypeError.prototype = Error.prototype; + + function createChainableTypeChecker(validate) { + if ("development" !== 'production') { + var manualPropTypeCallCache = {}; + } + function checkType(isRequired, props, propName, componentName, location, propFullName, secret) { + componentName = componentName || ANONYMOUS; + propFullName = propFullName || propName; + if ("development" !== 'production') { + if (secret !== ReactPropTypesSecret && typeof console !== 'undefined') { + var cacheKey = componentName + ':' + propName; + if (!manualPropTypeCallCache[cacheKey]) { + "development" !== 'production' ? warning(false, 'You are manually calling a React.PropTypes validation ' + 'function for the `%s` prop on `%s`. This is deprecated ' + 'and will not work in production with the next major version. ' + 'You may be seeing this warning due to a third-party PropTypes ' + 'library. See https://fb.me/react-warning-dont-call-proptypes ' + 'for details.', propFullName, componentName) : void 0; + manualPropTypeCallCache[cacheKey] = true; + } + } + } + if (props[propName] == null) { + if (isRequired) { + if (props[propName] === null) { + return new PropTypeError('The ' + location + ' `' + propFullName + '` is marked as required ' + ('in `' + componentName + '`, but its value is `null`.')); + } + return new PropTypeError('The ' + location + ' `' + propFullName + '` is marked as required in ' + ('`' + componentName + '`, but its value is `undefined`.')); + } + return null; + } else { + return validate(props, propName, componentName, location, propFullName); + } + } + + var chainedCheckType = checkType.bind(null, false); + chainedCheckType.isRequired = checkType.bind(null, true); + + return chainedCheckType; + } + + function createPrimitiveTypeChecker(expectedType) { + function validate(props, propName, componentName, location, propFullName, secret) { + var propValue = props[propName]; + var propType = getPropType(propValue); + if (propType !== expectedType) { + // `propValue` being instance of, say, date/regexp, pass the 'object' + // check, but we can offer a more precise error message here rather than + // 'of type `object`'. + var preciseType = getPreciseType(propValue); + + return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + preciseType + '` supplied to `' + componentName + '`, expected ') + ('`' + expectedType + '`.')); + } + return null; + } + return createChainableTypeChecker(validate); + } + + function createAnyTypeChecker() { + return createChainableTypeChecker(emptyFunction.thatReturnsNull); + } + + function createArrayOfTypeChecker(typeChecker) { + function validate(props, propName, componentName, location, propFullName) { + if (typeof typeChecker !== 'function') { + return new PropTypeError('Property `' + propFullName + '` of component `' + componentName + '` has invalid PropType notation inside arrayOf.'); + } + var propValue = props[propName]; + if (!Array.isArray(propValue)) { + var propType = getPropType(propValue); + return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected an array.')); + } + for (var i = 0; i < propValue.length; i++) { + var error = typeChecker(propValue, i, componentName, location, propFullName + '[' + i + ']', ReactPropTypesSecret); + if (error instanceof Error) { + return error; + } + } + return null; + } + return createChainableTypeChecker(validate); + } + + function createElementTypeChecker() { + function validate(props, propName, componentName, location, propFullName) { + var propValue = props[propName]; + if (!isValidElement(propValue)) { + var propType = getPropType(propValue); + return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected a single ReactElement.')); + } + return null; + } + return createChainableTypeChecker(validate); + } + + function createInstanceTypeChecker(expectedClass) { + function validate(props, propName, componentName, location, propFullName) { + if (!(props[propName] instanceof expectedClass)) { + var expectedClassName = expectedClass.name || ANONYMOUS; + var actualClassName = getClassName(props[propName]); + return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + actualClassName + '` supplied to `' + componentName + '`, expected ') + ('instance of `' + expectedClassName + '`.')); + } + return null; + } + return createChainableTypeChecker(validate); + } + + function createEnumTypeChecker(expectedValues) { + if (!Array.isArray(expectedValues)) { + "development" !== 'production' ? warning(false, 'Invalid argument supplied to oneOf, expected an instance of array.') : void 0; + return emptyFunction.thatReturnsNull; + } + + function validate(props, propName, componentName, location, propFullName) { + var propValue = props[propName]; + for (var i = 0; i < expectedValues.length; i++) { + if (is(propValue, expectedValues[i])) { + return null; + } + } + + var valuesString = JSON.stringify(expectedValues); + return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of value `' + propValue + '` ' + ('supplied to `' + componentName + '`, expected one of ' + valuesString + '.')); + } + return createChainableTypeChecker(validate); + } + + function createObjectOfTypeChecker(typeChecker) { + function validate(props, propName, componentName, location, propFullName) { + if (typeof typeChecker !== 'function') { + return new PropTypeError('Property `' + propFullName + '` of component `' + componentName + '` has invalid PropType notation inside objectOf.'); + } + var propValue = props[propName]; + var propType = getPropType(propValue); + if (propType !== 'object') { + return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected an object.')); + } + for (var key in propValue) { + if (propValue.hasOwnProperty(key)) { + var error = typeChecker(propValue, key, componentName, location, propFullName + '.' + key, ReactPropTypesSecret); + if (error instanceof Error) { + return error; + } + } + } + return null; + } + return createChainableTypeChecker(validate); + } + + function createUnionTypeChecker(arrayOfTypeCheckers) { + if (!Array.isArray(arrayOfTypeCheckers)) { + "development" !== 'production' ? warning(false, 'Invalid argument supplied to oneOfType, expected an instance of array.') : void 0; + return emptyFunction.thatReturnsNull; + } + + function validate(props, propName, componentName, location, propFullName) { + for (var i = 0; i < arrayOfTypeCheckers.length; i++) { + var checker = arrayOfTypeCheckers[i]; + if (checker(props, propName, componentName, location, propFullName, ReactPropTypesSecret) == null) { + return null; + } + } + + return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` supplied to ' + ('`' + componentName + '`.')); + } + return createChainableTypeChecker(validate); + } + + function createNodeChecker() { + function validate(props, propName, componentName, location, propFullName) { + if (!isNode(props[propName])) { + return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` supplied to ' + ('`' + componentName + '`, expected a ReactNode.')); + } + return null; + } + return createChainableTypeChecker(validate); + } + + function createShapeTypeChecker(shapeTypes) { + function validate(props, propName, componentName, location, propFullName) { + var propValue = props[propName]; + var propType = getPropType(propValue); + if (propType !== 'object') { + return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type `' + propType + '` ' + ('supplied to `' + componentName + '`, expected `object`.')); + } + for (var key in shapeTypes) { + var checker = shapeTypes[key]; + if (!checker) { + continue; + } + var error = checker(propValue, key, componentName, location, propFullName + '.' + key, ReactPropTypesSecret); + if (error) { + return error; + } + } + return null; + } + return createChainableTypeChecker(validate); + } + + function isNode(propValue) { + switch (typeof propValue) { + case 'number': + case 'string': + case 'undefined': + return true; + case 'boolean': + return !propValue; + case 'object': + if (Array.isArray(propValue)) { + return propValue.every(isNode); + } + if (propValue === null || isValidElement(propValue)) { + return true; + } + + var iteratorFn = getIteratorFn(propValue); + if (iteratorFn) { + var iterator = iteratorFn.call(propValue); + var step; + if (iteratorFn !== propValue.entries) { + while (!(step = iterator.next()).done) { + if (!isNode(step.value)) { + return false; + } + } + } else { + // Iterator will provide entry [k,v] tuples rather than values. + while (!(step = iterator.next()).done) { + var entry = step.value; + if (entry) { + if (!isNode(entry[1])) { + return false; + } + } + } + } + } else { + return false; + } + + return true; + default: + return false; + } + } + + function isSymbol(propType, propValue) { + // Native Symbol. + if (propType === 'symbol') { + return true; + } + + // 19.4.3.5 Symbol.prototype[@@toStringTag] === 'Symbol' + if (propValue['@@toStringTag'] === 'Symbol') { + return true; + } + + // Fallback for non-spec compliant Symbols which are polyfilled. + if (typeof Symbol === 'function' && propValue instanceof Symbol) { + return true; + } + + return false; + } + + // Equivalent of `typeof` but with special handling for array and regexp. + function getPropType(propValue) { + var propType = typeof propValue; + if (Array.isArray(propValue)) { + return 'array'; + } + if (propValue instanceof RegExp) { + // Old webkits (at least until Android 4.0) return 'function' rather than + // 'object' for typeof a RegExp. We'll normalize this here so that /bla/ + // passes PropTypes.object. + return 'object'; + } + if (isSymbol(propType, propValue)) { + return 'symbol'; + } + return propType; + } + + // This handles more types than `getPropType`. Only used for error messages. + // See `createPrimitiveTypeChecker`. + function getPreciseType(propValue) { + var propType = getPropType(propValue); + if (propType === 'object') { + if (propValue instanceof Date) { + return 'date'; + } else if (propValue instanceof RegExp) { + return 'regexp'; + } + } + return propType; + } + + // Returns class name of the object, if any. + function getClassName(propValue) { + if (!propValue.constructor || !propValue.constructor.name) { + return ANONYMOUS; + } + return propValue.constructor.name; + } + + ReactPropTypes.checkPropTypes = checkPropTypes; + ReactPropTypes.PropTypes = ReactPropTypes; + + return ReactPropTypes; +}; + +},{"142":142,"150":150,"157":157,"159":159,"161":161}],161:[function(_dereq_,module,exports){ +/** + * Copyright 2013-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +'use strict'; + +const ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED'; + +module.exports = ReactPropTypesSecret; + },{}]},{},[48])(48) }); }); diff --git a/js/react.js b/js/react.js index b03ccb72a2..0696cac71f 100644 --- a/js/react.js +++ b/js/react.js @@ -1,5 +1,5 @@ /** - * React v15.4.2 + * React v15.5.0 */ (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.React = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o diff --git a/tutorial/tutorial.html b/tutorial/tutorial.html index 42063a37d3..4d8e05a5cb 100644 --- a/tutorial/tutorial.html +++ b/tutorial/tutorial.html @@ -63,7 +63,7 @@ diff --git a/warnings/dont-call-proptypes.html b/warnings/dont-call-proptypes.html index b68ca661a2..080a26b367 100644 --- a/warnings/dont-call-proptypes.html +++ b/warnings/dont-call-proptypes.html @@ -63,7 +63,7 @@ @@ -74,7 +74,12 @@

    Don't Call PropTypes Warning

    -

    In a future major release of React, the code that implements PropType validation functions will be stripped in production. Once this happens, any code that calls these functions manually (that isn't stripped in production) will throw an error.

    +
    +

    Note: +React.PropTypes is deprecated as of React v15.5. Please use the prop-types library instead.

    +
    + +

    In a future major release of React, the code that implements PropType validation functions will be stripped in production. Once this happens, any code that calls these functions manually (that isn't stripped in production) will throw an error.

    Declaring PropTypes is still fine

    diff --git a/warnings/invalid-aria-prop.html b/warnings/invalid-aria-prop.html index ef7d5a8efe..f29e2c1db8 100644 --- a/warnings/invalid-aria-prop.html +++ b/warnings/invalid-aria-prop.html @@ -63,7 +63,7 @@
    diff --git a/warnings/legacy-factories.html b/warnings/legacy-factories.html index cc23fa2c6d..8bf415858b 100644 --- a/warnings/legacy-factories.html +++ b/warnings/legacy-factories.html @@ -63,7 +63,7 @@ diff --git a/warnings/refs-must-have-owner.html b/warnings/refs-must-have-owner.html index b63e16db9e..22ae41864a 100644 --- a/warnings/refs-must-have-owner.html +++ b/warnings/refs-must-have-owner.html @@ -63,7 +63,7 @@ diff --git a/warnings/special-props.html b/warnings/special-props.html index dcbc203a06..0d470fcaa1 100644 --- a/warnings/special-props.html +++ b/warnings/special-props.html @@ -63,7 +63,7 @@ diff --git a/warnings/unknown-prop.html b/warnings/unknown-prop.html index 714b1ed532..12640ac000 100644 --- a/warnings/unknown-prop.html +++ b/warnings/unknown-prop.html @@ -63,7 +63,7 @@