Files
react/blog/index.html
T
2017-04-26 17:34:36 +01:00

1189 lines
89 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<!--[if IE]><![endif]-->
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Blog - React</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta property="og:title" content="Blog - React">
<meta property="og:type" content="website">
<meta property="og:url" content="https://facebook.github.io/react/blog/">
<meta property="og:image" content="https://facebook.github.io/react/img/logo_og.png">
<meta property="og:description" content="A JavaScript library for building user interfaces">
<meta property="fb:app_id" content="623268441017527">
<link rel="shortcut icon" href="/react/favicon.ico">
<link rel="alternate" type="application/rss+xml" title="React" href="https://facebook.github.io/react/feed.xml">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css" />
<link rel="stylesheet" href="/react/css/syntax.css">
<link rel="stylesheet" href="/react/css/codemirror.css">
<link rel="stylesheet" href="/react/css/react.css">
<script src="//use.typekit.net/vqa1hcx.js"></script>
<script>try{Typekit.load();}catch(e){}</script>
<!--[if lte IE 8]>
<script src="https://unpkg.com/html5shiv@3.7.3/dist/html5shiv.min.js"></script>
<script src="https://unpkg.com/es5-shim@4.5.9/es5-shim.min.js"></script>
<script src="https://unpkg.com/es5-shim@4.5.9/es5-sham.min.js"></script>
<![endif]-->
<script src="https://unpkg.com/docsearch.js@1.5.0/dist/cdn/docsearch.min.js"></script>
<script src="https://unpkg.com/codemirror@5.15.2"></script>
<script src="https://unpkg.com/codemirror@5.15.2/mode/javascript/javascript.js"></script>
<script src="https://unpkg.com/codemirror@5.15.2/mode/xml/xml.js"></script>
<script src="https://unpkg.com/codemirror@5.15.2/mode/jsx/jsx.js"></script>
<script src="https://unpkg.com/react/dist/react.min.js"></script>
<script src="https://unpkg.com/react-dom/dist/react-dom.min.js"></script>
<script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
<script src="/react/js/live_editor.js"></script>
</head>
<body>
<div class="container">
<div class="nav-main">
<div class="wrap">
<a class="nav-home" href="/react/">
<img class="nav-logo" src="/react/img/logo.svg" width="36" height="36">
React
</a>
<div class="nav-lists">
<ul class="nav-site nav-site-internal">
<li><a href="/react/docs/hello-world.html">Docs</a></li>
<li><a href="/react/tutorial/tutorial.html">Tutorial</a></li>
<li><a href="/react/community/support.html">Community</a></li>
<li><a href="/react/blog/" class="active">Blog</a></li>
<li class="nav-site-search">
<input id="algolia-doc-search" type="text" placeholder="Search docs..." />
</li>
</ul>
<ul class="nav-site nav-site-external">
<li><a href="https://github.com/facebook/react">GitHub</a></li>
<li><a href="https://github.com/facebook/react/releases">v15.5.0</a></li>
</ul>
</div>
</div>
</div>
<section class="content wrap blogContent">
<div class="nav-docs nav-blog">
<div class="nav-docs-section">
<h3>Recent posts</h3>
<ul>
<li><a href="/react/blog/2017/04/07/react-v15.5.0.html">React v15.5.0</a></li>
<li><a href="/react/blog/2016/11/16/react-v15.4.0.html">React v15.4.0</a></li>
<li><a href="/react/blog/2016/09/28/our-first-50000-stars.html">Our First 50,000 Stars</a></li>
<li><a href="/react/blog/2016/08/05/relay-state-of-the-state.html">Relay: State of the State</a></li>
<li><a href="/react/blog/2016/07/22/create-apps-with-no-configuration.html">Create Apps with No Configuration</a></li>
<li><a href="/react/blog/2016/07/13/mixins-considered-harmful.html">Mixins Considered Harmful</a></li>
<li><a href="/react/blog/2016/07/11/introducing-reacts-error-code-system.html">Introducing React's Error Code System</a></li>
<li><a href="/react/blog/2016/04/08/react-v15.0.1.html">React v15.0.1</a></li>
<li><a href="/react/blog/2016/04/07/react-v15.html">React v15.0</a></li>
<li><a href="/react/blog/2016/03/29/react-v0.14.8.html">React v0.14.8</a></li>
<li><a href="/react/blog/all.html">All posts ...</a></li>
</ul>
</div>
</div>
<div class="inner-content">
<div class="post-list-item">
<h1>
<a href="/react/blog/2017/04/07/react-v15.5.0.html">React v15.5.0</a>
</h1>
<p class="meta">
April 7, 2017
by
<a href="https://twitter.com/acdlite">Andrew Clark</a>
</p>
<hr>
<div class="post">
<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>
</div>
</div>
<div class="post-list-item">
<h1>
<a href="/react/blog/2016/11/16/react-v15.4.0.html">React v15.4.0</a>
</h1>
<p class="meta">
November 16, 2016
by
<a href="https://twitter.com/dan_abramov">Dan Abramov</a>
</p>
<hr>
<div class="post">
<p>Today we are releasing React 15.4.0.</p>
<p>We didn&#39;t announce the <a href="https://github.com/facebook/react/blob/master/CHANGELOG.md#1510-may-20-2016">previous</a> <a href="https://github.com/facebook/react/blob/master/CHANGELOG.md#1520-july-1-2016">minor</a> <a href="https://github.com/facebook/react/blob/master/CHANGELOG.md#1530-july-29-2016">releases</a> on the blog because most of the changes were bug fixes. However, 15.4.0 is a special release, and we would like to highlight a few notable changes in it.</p>
<h3>Separating React and React DOM</h3>
<p><a href="/react/blog/2015/09/10/react-v0.14-rc1.html#two-packages-react-and-react-dom">More than a year ago</a>, we started separating React and React DOM into separate packages. We deprecated <code>React.render()</code> in favor of <code>ReactDOM.render()</code> in React 0.14, and removed DOM-specific APIs from <code>React</code> completely in React 15. However, the React DOM implementation still <a href="https://www.reddit.com/r/javascript/comments/3m6wyu/found_this_line_in_the_react_codebase_made_me/cvcyo4a/">secretly lived inside the React package</a>.</p>
<p>In React 15.4.0, we are finally moving React DOM implementation to the React DOM package. The React package will now contain only the renderer-agnostic code such as <code>React.Component</code> and <code>React.createElement()</code>.</p>
<p>This solves a few long-standing issues, such as <a href="https://github.com/facebook/react/issues/7386">errors</a> when you import React DOM in the same file as the <a href="https://facebook.github.io/jest/blog/2016/07/27/jest-14.html">snapshot testing</a> renderer.</p>
<p><strong>If you only use the official and documented React APIs you won&#39;t need to change anything in your application.</strong></p>
<p>However, there is a possibility that you imported private APIs from <code>react/lib/*</code>, or that a package you rely on might use them. We would like to remind you that this was never supported, and that your apps should not rely on internal APIs. The React internals will keep changing as we work to make React better.</p>
<p>Another thing to watch out for is that React DOM Server is now about the same size as React DOM since it contains its own copy of the React reconciler. We don&#39;t recommend using React DOM Server on the client in most cases.</p>
<h3>Profiling Components with Chrome Timeline</h3>
<p>You can now visualize React components in the Chrome Timeline. This lets you see which components exactly get mounted, updated, and unmounted, how much time they take relative to each other.</p>
<p><center><img src="/react/img/blog/react-perf-chrome-timeline.png" width="651" height="228" alt="React components in Chrome timeline" /></center></p>
<p>To use it:</p>
<ol>
<li><p>Load your app with <code>?react_perf</code> in the query string (for example, <code>http://localhost:3000/?react_perf</code>).</p></li>
<li><p>Open the Chrome DevTools <strong>Timeline</strong> tab and press <strong>Record</strong>.</p></li>
<li><p>Perform the actions you want to profile. Don&#39;t record more than 20 seconds or Chrome might hang.</p></li>
<li><p>Stop recording.</p></li>
<li><p>React events will be grouped under the <strong>User Timing</strong> label.</p></li>
</ol>
<p>Note that the numbers are relative so components will render faster in production. Still, this should help you realize when unrelated UI gets updated by mistake, and how deep and how often your UI updates occur.</p>
<p>Currently Chrome, Edge, and IE are the only browsers supporting this feature, but we use the standard <a href="https://developer.mozilla.org/en-US/docs/Web/API/User_Timing_API">User Timing API</a> so we expect more browsers to add support for it.</p>
<h3>Mocking Refs for Snapshot Testing</h3>
<p>If you&#39;re using Jest <a href="https://facebook.github.io/jest/blog/2016/07/27/jest-14.html">snapshot testing</a>, you might have had <a href="https://github.com/facebook/react/issues/7371">issues</a> with components that rely on refs. With React 15.4.0, we introduce a way to provide mock refs to the test renderer. For example, consider this component using a ref in <code>componentDidMount</code>:</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><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">export</span> <span class="k">default</span> <span class="kr">class</span> <span class="nx">MyInput</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">componentDidMount</span><span class="p">()</span> <span class="p">{</span>
<span class="hll"> <span class="k">this</span><span class="p">.</span><span class="nx">input</span><span class="p">.</span><span class="nx">focus</span><span class="p">();</span>
</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="p">(</span>
<span class="o">&lt;</span><span class="nx">input</span>
<span class="hll"> <span class="nx">ref</span><span class="o">=</span><span class="p">{</span><span class="nx">node</span> <span class="o">=&gt;</span> <span class="k">this</span><span class="p">.</span><span class="nx">input</span> <span class="o">=</span> <span class="nx">node</span><span class="p">}</span>
</span> <span class="o">/&gt;</span>
<span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div>
<p>With snapshot renderer, <code>this.input</code> will be <code>null</code> because there is no DOM. React 15.4.0 lets us avoid such crashes by passing a custom <code>createNodeMock</code> function to the snapshot renderer in an <code>options</code> argument:</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><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">import</span> <span class="nx">MyInput</span> <span class="nx">from</span> <span class="s1">&#39;./MyInput&#39;</span><span class="p">;</span>
<span class="kr">import</span> <span class="nx">renderer</span> <span class="nx">from</span> <span class="s1">&#39;react-test-renderer&#39;</span><span class="p">;</span>
<span class="hll"><span class="kd">function</span> <span class="nx">createNodeMock</span><span class="p">(</span><span class="nx">element</span><span class="p">)</span> <span class="p">{</span>
</span><span class="hll"> <span class="k">if</span> <span class="p">(</span><span class="nx">element</span><span class="p">.</span><span class="nx">type</span> <span class="o">===</span> <span class="s1">&#39;input&#39;</span><span class="p">)</span> <span class="p">{</span>
</span><span class="hll"> <span class="k">return</span> <span class="p">{</span>
</span><span class="hll"> <span class="nx">focus</span><span class="p">()</span> <span class="p">{},</span>
</span><span class="hll"> <span class="p">};</span>
</span><span class="hll"> <span class="p">}</span>
</span><span class="hll"> <span class="k">return</span> <span class="kc">null</span><span class="p">;</span>
</span><span class="hll"><span class="p">}</span>
</span>
<span class="nx">it</span><span class="p">(</span><span class="s1">&#39;renders correctly&#39;</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
<span class="kr">const</span> <span class="nx">options</span> <span class="o">=</span> <span class="p">{</span><span class="nx">createNodeMock</span><span class="p">};</span>
<span class="hll"> <span class="kr">const</span> <span class="nx">tree</span> <span class="o">=</span> <span class="nx">renderer</span><span class="p">.</span><span class="nx">create</span><span class="p">(</span><span class="o">&lt;</span><span class="nx">MyInput</span> <span class="o">/&gt;</span><span class="p">,</span> <span class="nx">options</span><span class="p">);</span>
</span> <span class="nx">expect</span><span class="p">(</span><span class="nx">tree</span><span class="p">).</span><span class="nx">toMatchSnapshot</span><span class="p">();</span>
<span class="p">});</span>
</code></pre></div>
<p>We would like to thank <a href="https://github.com/Aweary">Brandon Dail</a> for implementing this feature.</p>
<p>You can learn more about snapshot testing in <a href="https://facebook.github.io/jest/blog/2016/07/27/jest-14.html">this Jest blog post</a>.</p>
<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.4.0 react-dom@15.4.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.4.0 react-dom@15.4.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.4.0/dist/react.js">react/dist/react.js</a><br>
Minified build for production: <a href="https://unpkg.com/react@15.4.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.4.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.4.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.4.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.4.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.4.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.4.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.4.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>
<h3>React</h3>
<ul>
<li>React package and browser build no longer &quot;secretly&quot; includes React DOM.<br>
<small>(<a href="https://github.com/sebmarkbage">@sebmarkbage</a> in <a href="https://github.com/facebook/react/pull/7164">#7164</a> and <a href="https://github.com/facebook/react/pull/7168">#7168</a>)</small></li>
<li>Required PropTypes now fail with specific messages for null and undefined.<br>
<small>(<a href="https://github.com/chenglou">@chenglou</a> in <a href="https://github.com/facebook/react/pull/7291">#7291</a>)</small></li>
<li>Improved development performance by freezing children instead of copying.<br>
<small>(<a href="https://github.com/keyanzhang">@keyanzhang</a> in <a href="https://github.com/facebook/react/pull/7455">#7455</a>)</small></li>
</ul>
<h3>React DOM</h3>
<ul>
<li>Fixed occasional test failures when React DOM is used together with shallow renderer.<br>
<small>(<a href="https://github.com/goatslacker">@goatslacker</a> in <a href="https://github.com/facebook/react/pull/8097">#8097</a>)</small></li>
<li>Added a warning for invalid <code>aria-</code> attributes.<br>
<small>(<a href="https://github.com/jessebeach">@jessebeach</a> in <a href="https://github.com/facebook/react/pull/7744">#7744</a>)</small></li>
<li>Added a warning for using <code>autofocus</code> rather than <code>autoFocus</code>.<br>
<small>(<a href="https://github.com/hkal">@hkal</a> in <a href="https://github.com/facebook/react/pull/7694">#7694</a>)</small></li>
<li>Removed an unnecessary warning about polyfilling <code>String.prototype.split</code>.<br>
<small>(<a href="https://github.com/nhunzaker">@nhunzaker</a> in <a href="https://github.com/facebook/react/pull/7629">#7629</a>)</small></li>
<li>Clarified the warning about not calling PropTypes manually.<br>
<small>(<a href="https://github.com/jedwards1211">@jedwards1211</a> in <a href="https://github.com/facebook/react/pull/7777">#7777</a>)</small></li>
<li>The unstable <code>batchedUpdates</code> API now passes the wrapped function&#39;s return value through.<br>
<small>(<a href="https://github.com/bgnorlov">@bgnorlov</a> in <a href="https://github.com/facebook/react/pull/7444">#7444</a>)</small></li>
<li>Fixed a bug with updating text in IE 8.<br>
<small>(<a href="https://github.com/mnpenner">@mnpenner</a> in <a href="https://github.com/facebook/react/pull/7832">#7832</a>)</small></li>
</ul>
<h3>React Perf</h3>
<ul>
<li>When ReactPerf is started, you can now view the relative time spent in components as a chart in Chrome Timeline.<br>
<small>(<a href="https://github.com/gaearon">@gaearon</a> in <a href="https://github.com/facebook/react/pull/7549">#7549</a>)</small></li>
</ul>
<h3>React Test Utils</h3>
<ul>
<li>If you call <code>Simulate.click()</code> on a <code>&lt;input disabled onClick={foo} /&gt;</code> then <code>foo</code> will get called whereas it didn&#39;t before.<br>
<small>(<a href="https://github.com/nhunzaker">@nhunzaker</a> in <a href="https://github.com/facebook/react/pull/7642">#7642</a>)</small></li>
</ul>
<h3>React Test Renderer</h3>
<ul>
<li>Due to packaging changes, it no longer crashes when imported together with React DOM in the same file.<br>
<small>(<a href="https://github.com/sebmarkbage">@sebmarkbage</a> in <a href="https://github.com/facebook/react/pull/7164">#7164</a> and <a href="https://github.com/facebook/react/pull/7168">#7168</a>)</small></li>
<li><code>ReactTestRenderer.create()</code> now accepts <code>{createNodeMock: element =&gt; mock}</code> as an optional argument so you can mock refs with snapshot testing.<br>
<small>(<a href="https://github.com/Aweary">@Aweary</a> in <a href="https://github.com/facebook/react/pull/7649">#7649</a> and <a href="https://github.com/facebook/react/pull/8261">#8261</a>)</small></li>
</ul>
</div>
</div>
<div class="post-list-item">
<h1>
<a href="/react/blog/2016/09/28/our-first-50000-stars.html">Our First 50,000 Stars</a>
</h1>
<p class="meta">
September 28, 2016
by
<a href="https://twitter.com/vjeux">Vjeux</a>
</p>
<hr>
<div class="post">
<p>Just three and a half years ago we open sourced a little JavaScript library called React. The journey since that day has been incredibly exciting.</p>
<h2>Commemorative T-Shirt</h2>
<p>In order to celebrate 50,000 GitHub stars, <a href="http://www.maggieappleton.com/">Maggie Appleton</a> from <a href="http://egghead.io/">egghead.io</a> has designed us a special T-shirt, which will be available for purchase from Teespring <strong>only for a week</strong> through Thursday, October 6. Maggie also wrote <a href="https://www.behance.net/gallery/43269677/Reacts-50000-Stars-Shirt">a blog post</a> showing all the different concepts she came up with before settling on the final design.</p>
<p><a target="_blank" href="https://teespring.com/react-50000-stars"><img src="/react/img/blog/react-50k-tshirt.jpg" width="650" height="340" alt="React 50k Tshirt" /></a></p>
<p>The T-shirts are super soft using American Apparel&#39;s tri-blend fabric; we also have kids and toddler T-shirts and baby onesies available.</p>
<ul>
<li><a href="https://teespring.com/react-50000-stars">Adult T-shirts (straight-cut and fitted)</a></li>
<li><a href="https://teespring.com/react-50000-stars-kids">Kids T-shirts</a></li>
<li><a href="https://teespring.com/react-50000-stars-toddler">Toddler T-Shirts</a></li>
<li><a href="https://teespring.com/react-50000-stars-baby">Baby Onesies</a></li>
</ul>
<p>Proceeds from the shirts will be donated to <a href="http://www.code2040.org/">CODE2040</a>, a nonprofit that creates access, awareness, and opportunities in technology for underrepresented minorities with a specific focus on Black and Latinx talent.</p>
<h2>Archeology</h2>
<p>We&#39;ve spent a lot of time trying to explain the concepts behind React and the problems it attempts to solve, but we haven&#39;t talked much about how React evolved before being open sourced. This milestone seemed like as good a time as any to dig through the earliest commits and share some of the more important moments and fun facts.</p>
<p>The story begins in our ads org, where we were building incredibly sophisticated client side web apps using an internal MVC framework called <a href="http://web.archive.org/web/20130608154901/http://shaneosullivan.github.io/boltjs/intro.html">BoltJS</a>. Here&#39;s a sample of what some Bolt code looked like:</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="kd">var</span> <span class="nx">CarView</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;javelin/core&#39;</span><span class="p">).</span><span class="nx">createClass</span><span class="p">({</span>
<span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;CarView&#39;</span><span class="p">,</span>
<span class="nx">extend</span><span class="o">:</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;container&#39;</span><span class="p">).</span><span class="nx">Container</span><span class="p">,</span>
<span class="nx">properties</span><span class="o">:</span> <span class="p">{</span>
<span class="nx">wheels</span><span class="o">:</span> <span class="mi">4</span><span class="p">,</span>
<span class="p">},</span>
<span class="nx">declare</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="k">return</span> <span class="p">{</span>
<span class="nx">childViews</span><span class="o">:</span> <span class="p">[</span>
<span class="p">{</span> <span class="nx">content</span><span class="o">:</span> <span class="s1">&#39;I have &#39;</span> <span class="p">},</span>
<span class="p">{</span> <span class="nx">ref</span><span class="o">:</span> <span class="s1">&#39;wheelView&#39;</span> <span class="p">},</span>
<span class="p">{</span> <span class="nx">content</span><span class="o">:</span> <span class="s1">&#39; wheels&#39;</span> <span class="p">}</span>
<span class="p">]</span>
<span class="p">};</span>
<span class="p">},</span>
<span class="nx">setWheels</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">wheels</span><span class="p">)</span> <span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="nx">findRef</span><span class="p">(</span><span class="s1">&#39;wheelView&#39;</span><span class="p">).</span><span class="nx">setContent</span><span class="p">(</span><span class="nx">wheels</span><span class="p">);</span>
<span class="p">},</span>
<span class="nx">getWheels</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">findRef</span><span class="p">(</span><span class="s1">&#39;wheelView&#39;</span><span class="p">).</span><span class="nx">getContent</span><span class="p">();</span>
<span class="p">},</span>
<span class="p">});</span>
<span class="kd">var</span> <span class="nx">car</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">CarView</span><span class="p">();</span>
<span class="nx">car</span><span class="p">.</span><span class="nx">setWheels</span><span class="p">(</span><span class="mi">3</span><span class="p">);</span>
<span class="nx">car</span><span class="p">.</span><span class="nx">placeIn</span><span class="p">(</span><span class="nb">document</span><span class="p">.</span><span class="nx">body</span><span class="p">);</span>
<span class="c1">//&lt;div&gt;</span>
<span class="c1">// &lt;div&gt;I have &lt;/div&gt;</span>
<span class="c1">// &lt;div&gt;3&lt;/div&gt;</span>
<span class="c1">// &lt;div&gt; wheels&lt;/div&gt;</span>
<span class="c1">//&lt;/div&gt;</span>
</code></pre></div>
<p>Bolt introduced a number of APIs and features that would eventually make their way into React including <code>render</code>, <code>createClass</code>, and <code>refs</code>. Bolt introduced the concept of <code>refs</code> as a way to create references to nodes that can be used imperatively. This was relevant for legacy interoperability and incremental adoption, and while React would eventually strive to be a lot more functional, <code>refs</code> proved to be a very useful way to break out of the functional paradigm when the need arose.</p>
<p>But as our applications grew more and more sophisticated, our Bolt codebases got pretty complicated. Recognizing some of the framework&#39;s shortcomings, <a href="https://twitter.com/jordwalke">Jordan Walke</a> started experimenting with a side-project called <a href="https://github.com/jordwalke/FaxJs">FaxJS</a>. His goal was to solve many of the same problems as Bolt, but in a very different way. This is actually where most of React&#39;s fundamentals were born, including props, state, re-evaluating large portions of the tree to “diff” the UI, server-side rendering, and a basic concept of components.</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="nx">TestProject</span><span class="p">.</span><span class="nx">PersonDisplayer</span> <span class="o">=</span> <span class="p">{</span>
<span class="nx">structure</span> <span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">Div</span><span class="p">({</span>
<span class="nx">classSet</span><span class="o">:</span> <span class="p">{</span> <span class="nx">personDisplayerContainer</span><span class="o">:</span> <span class="kc">true</span> <span class="p">},</span>
<span class="nx">titleDiv</span><span class="o">:</span> <span class="nx">Div</span><span class="p">({</span>
<span class="nx">classSet</span><span class="o">:</span> <span class="p">{</span> <span class="nx">personNameTitle</span><span class="o">:</span> <span class="kc">true</span> <span class="p">},</span>
<span class="nx">content</span><span class="o">:</span> <span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">name</span>
<span class="p">}),</span>
<span class="nx">nestedAgeDiv</span><span class="o">:</span> <span class="nx">Div</span><span class="p">({</span>
<span class="nx">content</span><span class="o">:</span> <span class="s1">&#39;Interests: &#39;</span> <span class="o">+</span> <span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">interests</span>
<span class="p">})</span>
<span class="p">});</span>
<span class="p">}</span>
<span class="p">};</span>
</code></pre></div>
<h2>FBolt is Born</h2>
<p>Through his FaxJS experiment, Jordan became convinced that functional APIs — which discouraged mutation — offered a better, more scalable way to build user interfaces. He imported his library into Facebook&#39;s codebase in March of 2012 and renamed it “FBolt”, signifying an extension of Bolt where components are written in a functional programming style. Or maybe “FBolt” was a nod to FaxJS he didn&#39;t tell us! ;)</p>
<p>The interoperability between FBolt and Bolt allowed us to experiment with replacing just one component at a time with more functional component APIs. We could test the waters of this new functional paradigm, without having to go all in. We started with the components that were clearly best expressed functionally and then we would later continue to push the boundaries of what we could express as functions.</p>
<p>Realizing that FBolt wouldn&#39;t be a great name for the library when used on its own, Jordan Walke and <a href="https://twitter.com/tomocchino">Tom Occhino</a> decided on a new name: “React.” After Tom sent out the diff to rename everything to React, Jordan commented:</p>
<blockquote>
<p>Jordan Walke:
I might add for the sake of discussion, that many systems advertise some kind of reactivity, but they usually require that you set up some kind of point-to-point listeners and won&#39;t work on structured data. This API reacts to any state or property changes, and works with data of any form (as deeply structured as the graph itself) so I think the name is fitting.</p>
</blockquote>
<p>Most of Tom&#39;s other commits at the time were on the first version of <a href="https://github.com/graphql/graphiql">GraphiQL</a>, a project which was recently open sourced.</p>
<h2>Adding JSX</h2>
<p>Since about 2010 Facebook has been using an extension of PHP called <a href="https://www.facebook.com/notes/facebook-engineering/xhp-a-new-way-to-write-php/294003943919/">XHP</a>, which enables engineers to create UIs using XML literals right inside their PHP code. It was first introduced to help prevent XSS holes but ended up being an excellent way to structure applications with custom components.</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="kr">final</span> <span class="kr">class</span> <span class="o">:</span><span class="nx">a</span><span class="o">:</span><span class="nx">post</span> <span class="kr">extends</span> <span class="o">:</span><span class="nx">x</span><span class="o">:</span><span class="nx">element</span> <span class="p">{</span>
<span class="nx">attribute</span> <span class="o">:</span><span class="nx">a</span><span class="p">;</span>
<span class="kr">protected</span> <span class="kd">function</span> <span class="nx">render</span><span class="p">()</span><span class="o">:</span> <span class="nx">XHPRoot</span> <span class="p">{</span>
<span class="nx">$anchor</span> <span class="o">=</span> <span class="o">&lt;</span><span class="nx">a</span><span class="o">&gt;</span><span class="p">{</span><span class="nx">$this</span><span class="o">-&gt;</span><span class="nx">getChildren</span><span class="p">()}</span><span class="o">&lt;</span><span class="err">/a&gt;;</span>
<span class="nx">$form</span> <span class="o">=</span> <span class="p">(</span>
<span class="o">&lt;</span><span class="nx">form</span>
<span class="nx">method</span><span class="o">=</span><span class="s2">&quot;post&quot;</span>
<span class="nx">action</span><span class="o">=</span><span class="p">{</span><span class="nx">$this</span><span class="o">-&gt;:</span><span class="nx">href</span><span class="p">}</span>
<span class="nx">target</span><span class="o">=</span><span class="p">{</span><span class="nx">$this</span><span class="o">-&gt;:</span><span class="nx">target</span><span class="p">}</span>
<span class="kr">class</span><span class="o">=</span><span class="s2">&quot;postLink&quot;</span>
<span class="o">&gt;</span><span class="p">{</span><span class="nx">$anchor</span><span class="p">}</span><span class="o">&lt;</span><span class="err">/form&gt;</span>
<span class="p">);</span>
<span class="nx">$this</span><span class="o">-&gt;</span><span class="nx">transferAllAttributes</span><span class="p">(</span><span class="nx">$anchor</span><span class="p">);</span>
<span class="k">return</span> <span class="nx">$form</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div>
<p>Before Jordan&#39;s work had even made its way into the Facebook codebase, Adam Hupp implemented an XHP-like concept for JavaScript, written in Haskell. This system enabled you to write the following inside a JavaScript file:</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="kd">function</span> <span class="o">:</span><span class="nx">example</span><span class="o">:</span><span class="nx">hello</span><span class="p">(</span><span class="nx">attrib</span><span class="p">,</span> <span class="nx">children</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="p">(</span>
<span class="o">&lt;</span><span class="nx">div</span> <span class="kr">class</span><span class="o">=</span><span class="s2">&quot;special&quot;</span><span class="o">&gt;</span>
<span class="o">&lt;</span><span class="nx">h1</span><span class="o">&gt;</span><span class="nx">Hello</span><span class="p">,</span> <span class="nx">World</span><span class="o">!&lt;</span><span class="err">/h1&gt;</span>
<span class="p">{</span><span class="nx">children</span><span class="p">}</span>
<span class="o">&lt;</span><span class="err">/div&gt;</span>
<span class="p">);</span>
<span class="p">}</span>
</code></pre></div>
<p>It would compile the above into the following normal ES3-compatible JavaScript:</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="kd">function</span> <span class="nx">jsx_example_hello</span><span class="p">(</span><span class="nx">attrib</span><span class="p">,</span> <span class="nx">children</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="p">(</span>
<span class="nx">S</span><span class="p">.</span><span class="nx">create</span><span class="p">(</span><span class="s2">&quot;div&quot;</span><span class="p">,</span> <span class="p">{</span><span class="s2">&quot;class&quot;</span><span class="o">:</span> <span class="s2">&quot;special&quot;</span><span class="p">},</span> <span class="p">[</span>
<span class="nx">S</span><span class="p">.</span><span class="nx">create</span><span class="p">(</span><span class="s2">&quot;h1&quot;</span><span class="p">,</span> <span class="p">{},</span> <span class="p">[</span><span class="s2">&quot;Hello, World!&quot;</span><span class="p">]),</span>
<span class="nx">children</span>
<span class="p">]</span>
<span class="p">);</span>
<span class="p">}</span>
</code></pre></div>
<p>In this prototype, <code>S.create</code> would immediately create and return a DOM node. Most of the conversations on this prototype revolved around the performance characteristics of <code>innerHTML</code> versus creating DOM nodes directly. At the time, it would have been less than ideal to push developers universally in the direction of creating DOM nodes directly since it did not perform as well, especially in Firefox and IE. Facebook&#39;s then-CTO <a href="https://twitter.com/btaylor">Bret Taylor</a> chimed in on the discussion at the time in favor of <code>innerHTML</code> over <code>document.createElement</code>:</p>
<blockquote>
<p>Bret Taylor:
If you are not convinced about innerHTML, here is a small microbenchmark. It is about the same in Chrome. innerHTML is about 30% faster in the latest version of Firefox (much more in previous versions), and about 90% faster in IE8.</p>
</blockquote>
<p>This work was eventually abandoned but was revived after React made its way into the codebase. Jordan sidelined the previous performance discussions by introducing the concept of a “Virtual DOM,” though its eventual name didn&#39;t exist yet.</p>
<blockquote>
<p>Jordan Walke:
For the first step, I propose that we do the easiest, yet most general transformation possible. My suggestion is to simply map xml expressions to function call expressions.</p>
<ul>
<li><code>&lt;x&gt;&lt;/x&gt;</code> becomes <code>x( )</code></li>
<li><code>&lt;x height=12&gt;&lt;/x&gt;</code> becomes <code>x( {height:12} )</code></li>
<li><code>&lt;x&gt; &lt;y&gt; &lt;/y&gt; &lt;/x&gt;</code> becomes <code>x({ childList: [y( )] })</code></li>
</ul>
<p>At this point, JSX doesn&#39;t need to know about React - it&#39;s just a convenient way to write function calls. Coincidentally, React&#39;s primary abstraction is the function. Okay maybe it&#39;s not so coincidental ;)</p>
</blockquote>
<p>Adam made a very insightful comment, which is now the default way we write lists in React with JSX.</p>
<blockquote>
<p>Adam Hupp:
I think we should just treat arrays of elements as a frag. This is useful for constructs like:</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="o">&lt;</span><span class="nx">ul</span><span class="o">&gt;</span><span class="p">{</span><span class="nx">foo</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">i</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="o">&lt;</span><span class="nx">li</span><span class="o">&gt;</span><span class="p">{</span><span class="nx">i</span><span class="p">.</span><span class="nx">data</span><span class="p">}</span><span class="o">&lt;</span><span class="err">/li&gt;; })}&lt;/ul&gt;</span>
</code></pre></div>
<p>In this case the ul(..) will get a childList with a single child, which is itself a list.</p>
</blockquote>
<p>React didn&#39;t end up using Adam&#39;s implementation directly. Instead, we created JSX by forking <a href="https://github.com/laverdet/js-xml-literal">js-xml-literal</a>, a side project by XHP creator Marcel Laverdet. JSX took its name from js-xml-literal, which Jordan modified to just be syntactic sugar for deeply nested function calls.</p>
<h2>API Churn</h2>
<p>During the first year of React, internal adoption was growing quickly but there was quite a lot of churn in the component APIs and naming conventions:</p>
<ul>
<li><code>project</code> was renamed to <code>declare</code> then to <code>structure</code> and finally to <code>render</code>.</li>
<li><code>Componentize</code> was renamed to <code>createComponent</code> and finally to <code>createClass</code>.</li>
</ul>
<p>As the project was about to be open sourced, <a href="https://twitter.com/leeb">Lee Byron</a> sat down with Jordan Walke, Tom Occhino and Sebastian Markbåge in order to refactor, reimplement, and rename one of React&#39;s most beloved features the lifecycle API. Lee <a href="https://gist.github.com/vjeux/f2b015d230cc1ab18ed1df30550495ed">came up with a well-designed API</a> that is still in place today.</p>
<ul>
<li>Concepts
<ul>
<li>component - a ReactComponent instance</li>
<li>state - internal state to a component</li>
<li>props - external state to a component</li>
<li>markup - the stringy HTML-ish stuff components generate</li>
<li>DOM - the document and elements within the document</li>
</ul></li>
<li>Actions
<ul>
<li>mount - to put a component into a DOM</li>
<li>initialize - to prepare a component for rendering</li>
<li>update - a transition of state (and props) resulting a render.</li>
<li>render - a side-effect-free process to get the representation (markup) of a component.</li>
<li>validate - make assertions about something created and provided</li>
<li>destroy - opposite of initialize</li>
</ul></li>
<li>Operands
<ul>
<li>create - make a new thing</li>
<li>get - get an existing thing</li>
<li>set - merge into existing</li>
<li>replace - replace existing</li>
<li>receive - respond to new data</li>
<li>force - skip checks to do action</li>
</ul></li>
<li>Notifications
<ul>
<li>shouldObjectAction</li>
<li>objectWillAction</li>
<li>objectDidAction</li>
</ul></li>
</ul>
<h2>Instagram</h2>
<p>In 2012, Instagram got acquired by Facebook. <a href="https://twitter.com/floydophone">Pete Hunt</a>, who was working on Facebook photos and videos at the time, joined their newly formed web team. He wanted to build their website completely in React, which was in stark contrast with the incremental adoption model that had been used at Facebook.</p>
<p>To make this happen, React had to be decoupled from Facebook&#39;s infrastructure, since Instagram didn&#39;t use any of it. This project acted as a forcing function to do the work needed to open source React. In the process, Pete also discovered and promoted a little project called Webpack. He also implemented the <code>renderToString</code> primitive which was needed to do server-side rendering.</p>
<p>As we started to prepare for the open source launch, <a href="https://twitter.com/miekd">Maykel Loomans</a>, a designer on Instagram, made a mock of what the website could look like. The header ended up defining the visual identity of React: its logo and the electric blue color!</p>
<p><center><a target="_blank" href="/react/img/blog/react-50k-mock-full.jpg"><img src="/react/img/blog/react-50k-mock.jpg" width="400" height="410" alt="React website mock" /></a></center></p>
<p>In its earliest days, React benefited tremendously from feedback, ideas, and technical contributions of early adopters and collaborators all over the company. While it might look like an overnight success in hindsight, the story of React is actually a great example of how new ideas often need to go through several rounds of refinement, iteration, and course correction over a long period of time before reaching their full potential.</p>
<p>React&#39;s approach to building user interfaces with functional programming principles has changed the way we do things in just a few short years. It goes without saying, but React would be nothing without the amazing open source community that&#39;s built up around it!</p>
</div>
</div>
<div class="post-list-item">
<h1>
<a href="/react/blog/2016/08/05/relay-state-of-the-state.html">Relay: State of the State</a>
</h1>
<p class="meta">
August 5, 2016
by
<a href="https://twitter.com/en_JS">Joseph Savona</a>
</p>
<hr>
<div class="post">
<p>This month marks a year since we released Relay and we&#39;d like to share an update on the project and what&#39;s next.</p>
<h2>A Year In Review</h2>
<p>A year after launch, we&#39;re incredibly excited to see an active community forming around Relay and that companies such as Twitter are <a href="https://fabric.io/blog/building-fabric-mission-control-with-graphql-and-relay">using Relay in production</a>:</p>
<blockquote>
<p>For a project like mission control, GraphQL and Relay were a near-perfect solution, and the cost of building it any other way justified the investment.</p>
<p>-- <cite>Fin Hopkins</cite></p>
</blockquote>
<p>This kind of positive feedback is really encouraging (I&#39;ll admit to re-reading that post far too many times), and great motivation for us to keep going and make Relay even better.</p>
<p>With the community&#39;s help we&#39;ve already come a long way since the technical preview. Here are some highlights:</p>
<ul>
<li>In March we added support for server-side rendering and for creating multiple instances of Relay on a single page. This was a coordinated effort over the course of several months by community members <a href="https://github.com/denvned">Denis Nedelyaev</a> and <a href="https://github.com/devknoll">Gerald Monaco</a> (now at Facebook).</li>
<li>Also in March we added support for React Native. While we use Relay and React Native together internally, they didn&#39;t quite work together in open-source out of the box. We owe a big thanks to <a href="https://github.com/skevy">Adam Miskiewicz</a>, <a href="https://github.com/boourns">Tom Burns</a>, <a href="https://github.com/gre">Gaëtan Renaudeau</a>, <a href="https://github.com/davidaurelio">David Aurelio</a>, <a href="https://github.com/martinbigio">Martín Bigio</a>, <a href="https://github.com/zpao">Paul OShannessy</a>, <a href="https://github.com/spicyj">Ben Alpert</a>, and many others who helped track down and resolve issues. Finally, thanks to <a href="https://github.com/steveluscher">Steven Luscher</a> for coordinating this effort and building the first Relay/ReactNative example app.</li>
</ul>
<p>We&#39;ve also seen some great open-source projects spring up around Relay:</p>
<ul>
<li><a href="https://github.com/denvned">Denis Nedelyaev</a> created <a href="https://github.com/denvned/isomorphic-relay/">isomorphic-relay</a>, a package that helps developers build server-rendered Relay apps where data is prepared on the server and then used to bootstrap the app on the client.</li>
<li><a href="https://github.com/taion">Jimmy Jia</a> created <a href="https://github.com/relay-tools/react-router-relay">react-router-relay</a> to integrate Relay data-fetching into React Router.</li>
<li><a href="https://github.com/nodkz">Pavel Chertorogov</a> released <a href="https://github.com/nodkz/react-relay-network-layer">relay-network-layer</a>, which adds features such as batching query requests, middleware, authentication, logging, and more.</li>
</ul>
<p>This is just a small sampling of the community&#39;s contributions. So far we&#39;ve merged over 300 PRs - about 25% of our commits - from over 80 of you. These PRs have improved everything from the website and docs down the very core of the framework. We&#39;re humbled by these outstanding contributions and excited to keep working with each of you!</p>
<h1>Retrospective &amp; Roadmap</h1>
<p>Earlier this year we paused to reflect on the state of the project. What was working well? What could be improved? What features should we add, and what could we remove? A few themes emerged: performance on mobile, developer experience, and empowering the community.</p>
<h2>Mobile Perf</h2>
<p>First, Relay was built to serve the needs of product developers at Facebook. In 2016, that means helping developers to build apps that work well on <a href="https://newsroom.fb.com/news/2015/10/news-feed-fyi-building-for-all-connectivity/">mobile devices connecting on slower networks</a>. For example, people in developing markets commonly use <a href="https://code.facebook.com/posts/307478339448736/year-class-a-classification-system-for-android/">2011 year-class phones</a> and connect via <a href="https://code.facebook.com/posts/952628711437136/classes-performance-and-network-segmentation-on-android/">2G class networks</a>. These scenarios present their own challenges.</p>
<p>Therefore, one of our primary goals this year is to optimize Relay for performance on low-end mobile devices <em>first</em>, knowing that this can translate to improved performance on high-end devices as well. In addition to standard approaches such as benchmarking, profiling, and optimizations, we&#39;re also working on big-picture changes.</p>
<p>For example, in today&#39;s Relay, here&#39;s what happens when an app is opened. First, React Native starts initializing the JavaScript context (loading and parsing your code and then running it). When this finishes, the app executes and Relay sees that you need data. It constructs and prints the query, uploads the query text to the server, processes the response, and renders your app. (Note that this process applies on the web, except that the code has to be <em>downloaded</em> instead of loaded from the device.)</p>
<p>Ideally, though, we could begin fetching data as soon as the native code had loaded - in parallel with the JS context initialization. By the time your JS code was ready to run, the data-fetching would already be under way. To do this we would need a way to determine <em>statically</em> - at build time - what query an application would send.</p>
<p>The key is that GraphQL is already static - we just need to fully embrace this fact. More on this later.</p>
<h2>Developer Experience</h2>
<p>Next, we&#39;ve paid attention to the community&#39;s feedback and know that, to put it simply, Relay could be &quot;easier&quot; to use (and &quot;simpler&quot; too). This isn&#39;t entirely surprising to us - Relay was originally designed as a routing library and gradually morphed into a data-fetching library. Concepts like Relay &quot;routes&quot;, for example, no longer serve as critical a role and are just one more concept that developers have to learn about. Another example is mutations: while writes <em>are</em> inherently more complex than reads, our API doesn&#39;t make the simple things simple enough.</p>
<p>Alongside our focus on mobile performance, we&#39;ve also kept the developer experience in mind as we evolve Relay core.</p>
<h2>Empowering the Community</h2>
<p>Finally, we want to make it easier for people in the community to develop useful libraries that work with Relay. By comparison, React&#39;s small surface area - components - allows developers to build cool things like routing, higher-order components, or reusable text editors. For Relay, this would mean having the framework provide core primitives that users can build upon. We want it to be possible for the community to integrate Relay with view libraries other than React, or to build real-time subscriptions as a complementary library.</p>
<h1>What&#39;s Next</h1>
<p>These were big goals, and also a bit scary; we knew that incremental improvements would only allow us to move so fast. So in April we started a project to build a new implementation of Relay core targeting low-end mobile devices from the start.</p>
<p>As you can guess since we&#39;re writing this, the experiment was a success. The result is a new core that retains the best parts of Relay today - colocated components &amp; data-dependencies, automatic data/view consistency, declarative data-fetching - while improving performance on mobile devices and addressing several common areas of confusion.</p>
<p>We&#39;re currently focused on shipping the first applications using the new core: ironing out bugs, refining the API changes and developer experience, and adding any missing features. We&#39;re excited to bring these changes to open source, and will do so once we&#39;ve proven them in production. We&#39;ll go into more detail in some upcoming talks - links below - but for now here&#39;s an overview:</p>
<ul>
<li><strong>Static Queries</strong>: By adding a couple of Relay-specific directives, we&#39;ve been able to retain the expressivity of current Relay queries using static syntax (concretely: you know what query an app will execute just by looking at the source text, without having to run that code). For starters this will allow Relay apps to start fetching data in parallel with JavaScript initialization. But it also unlocks other possibilities: knowing the query ahead of time means that we can generate optimized code for handling query responses, for example, or for reading query data from an offline cache.</li>
<li><strong>Expressive Mutations</strong>: We&#39;ll continue to support a higher-level mutation API for common cases, but will also provide a lower-level API that allows &quot;raw&quot; data access where necessary. If you need to order a list of cached elements, for example, there will be a way to <code>sort()</code> it.</li>
<li><strong>Route-less Relay</strong>: Routes will be gone in open source. Instead of a route with multiple query definitions, you&#39;ll just provide a single query with as many root fields as you want.</li>
<li><strong>Cache Eviction/Garbage Collection</strong>: The API and architecture is designed from the start to allow removing cached data that is no longer referenced by a mounted view.</li>
</ul>
<p>Stepping back, we recognize that any API changes will require an investment on your part. To make the transition easier, though, <em>we will continue to support the current API for the foreseeable future</em> (we&#39;re still using it too). And as much as possible we will open-source the tools that we use to migrate our own code. Ideas that we&#39;re exploring include codemods, an interoperability layer for the old/new APIs, and tutorials &amp; guides to ease migration.</p>
<p>Ultimately, we&#39;re making these changes because we believe they make Relay better all around: simpler for developers building apps and faster for the people using them.</p>
<h1>Conclusion</h1>
<p>If you made it this far, congrats and thanks for reading! We&#39;ll be sharing more information about these changes in some upcoming talks:</p>
<ul>
<li><a href="https://github.com/wincent">Greg Hurrell</a> will presenting a Relay &quot;Deep Dive&quot; at the <a href="http://www.meetup.com/Silicon-Valley-ReactJS-Meetup/events/232236845/">Silicon Valley ReactJS Meetup</a> on August 17th.</li>
<li>I (<a href="https://github.com/josephsavona">@josephsavona</a>) will be speaking about Relay at <a href="http://www.reactrally.com">React Rally</a> on August 25th.</li>
</ul>
<p>We can&#39;t wait to share the new code with you and are working as fast as we can to do so!</p>
</div>
</div>
<div class="post-list-item">
<h1>
<a href="/react/blog/2016/07/22/create-apps-with-no-configuration.html">Create Apps with No Configuration</a>
</h1>
<p class="meta">
July 22, 2016
by
<a href="https://twitter.com/dan_abramov">Dan Abramov</a>
</p>
<hr>
<div class="post">
<p><strong><a href="https://github.com/facebookincubator/create-react-app">Create React App</a></strong> is a new officially supported way to create single-page React applications. It offers a modern build setup with no configuration.</p>
<h2>Getting Started</h2>
<h3>Installation</h3>
<p>First, install the global package:</p>
<div class="highlight"><pre><code class="language-sh" data-lang="sh">npm install -g create-react-app
</code></pre></div>
<p>Node.js 4.x or higher is required.</p>
<h3>Creating an App</h3>
<p>Now you can use it to create a new app:</p>
<div class="highlight"><pre><code class="language-sh" data-lang="sh">create-react-app hello-world
</code></pre></div>
<p>This will take a while as npm installs the transitive dependencies, but once its done, you will see a list of commands you can run in the created folder:</p>
<p><img src="/react/img/blog/create-apps-with-no-configuration/created-folder.png" alt="created folder"></p>
<h3>Starting the Server</h3>
<p>Run <code>npm start</code> to launch the development server. The browser will open automatically with the created apps URL.</p>
<p><img src="/react/img/blog/create-apps-with-no-configuration/compiled-successfully.png" alt="compiled successfully"></p>
<p>Create React App uses both Webpack and Babel under the hood.<br>
The console output is tuned to be minimal to help you focus on the problems:</p>
<p><img src="/react/img/blog/create-apps-with-no-configuration/failed-to-compile.png" alt="failed to compile"></p>
<p>ESLint is also integrated so lint warnings are displayed right in the console:</p>
<p><img src="/react/img/blog/create-apps-with-no-configuration/compiled-with-warnings.png" alt="compiled with warnings"></p>
<p>We only picked a small subset of lint rules that often lead to bugs.</p>
<h3>Building for Production</h3>
<p>To build an optimized bundle, run <code>npm run build</code>:</p>
<p><img src="/react/img/blog/create-apps-with-no-configuration/npm-run-build.png" alt="npm run build"></p>
<p>It is minified, correctly envified, and the assets include content hashes for caching.</p>
<h3>One Dependency</h3>
<p>Your <code>package.json</code> contains only a single build dependency and a few scripts:</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="p">{</span>
<span class="s2">&quot;name&quot;</span><span class="o">:</span> <span class="s2">&quot;hello-world&quot;</span><span class="p">,</span>
<span class="s2">&quot;dependencies&quot;</span><span class="o">:</span> <span class="p">{</span>
<span class="s2">&quot;react&quot;</span><span class="o">:</span> <span class="s2">&quot;^15.2.1&quot;</span><span class="p">,</span>
<span class="s2">&quot;react-dom&quot;</span><span class="o">:</span> <span class="s2">&quot;^15.2.1&quot;</span>
<span class="p">},</span>
<span class="s2">&quot;devDependencies&quot;</span><span class="o">:</span> <span class="p">{</span>
<span class="s2">&quot;react-scripts&quot;</span><span class="o">:</span> <span class="s2">&quot;0.1.0&quot;</span>
<span class="p">},</span>
<span class="s2">&quot;scripts&quot;</span><span class="o">:</span> <span class="p">{</span>
<span class="s2">&quot;start&quot;</span><span class="o">:</span> <span class="s2">&quot;react-scripts start&quot;</span><span class="p">,</span>
<span class="s2">&quot;build&quot;</span><span class="o">:</span> <span class="s2">&quot;react-scripts build&quot;</span><span class="p">,</span>
<span class="s2">&quot;eject&quot;</span><span class="o">:</span> <span class="s2">&quot;react-scripts eject&quot;</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div>
<p>We take care of updating Babel, ESLint, and Webpack to stable compatible versions so you can update a single dependency to get them all.</p>
<h3>Zero Configuration</h3>
<p>It is worth repeating: there are no configuration files or complicated folder structures. The tool only generates the files you need to build your app.</p>
<div class="highlight"><pre><code class="language-text" data-lang="text">hello-world/
README.md
index.html
favicon.ico
node_modules/
package.json
src/
App.css
App.js
index.css
index.js
logo.svg
</code></pre></div>
<p>All the build settings are preconfigured and cant be changed. Some features, such as testing, are currently missing. This is an intentional limitation, and we recognize it might not work for everybody. And this brings us to the last point.</p>
<h3>No Lock-In</h3>
<p>We first saw this feature in <a href="https://github.com/eanplatter/enclave">Enclave</a>, and we loved it. We talked to <a href="https://twitter.com/EanPlatter">Ean</a>, and he was excited to collaborate with us. He already sent a few pull requests!</p>
<p>“Ejecting” lets you leave the comfort of Create React App setup at any time. You run a single command, and all the build dependencies, configs, and scripts are moved right into your project. At this point you can customize everything you want, but effectively you are forking our configuration and going your own way. If youre experienced with build tooling and prefer to fine-tune everything to your taste, this lets you use Create React App as a boilerplate generator.</p>
<p>We expect that at early stages, many people will “eject” for one reason or another, but as we learn from them, we will make the default setup more and more compelling while still providing no configuration.</p>
<h2>Try It Out!</h2>
<p>You can find <a href="https://github.com/facebookincubator/create-react-app"><strong>Create React App</strong></a> with additional instructions on GitHub.</p>
<p>This is an experiment, and only time will tell if it becomes a popular way of creating and building React apps, or fades into obscurity.</p>
<p>We welcome you to participate in this experiment. Help us build the React tooling that more people can use. We are always <a href="https://github.com/facebookincubator/create-react-app/issues/11">open to feedback</a>.</p>
<h2>The Backstory</h2>
<p>React was one of the first libraries to embrace transpiling JavaScript. As a result, even though you can <a href="https://github.com/facebook/react/blob/3fd582643ef3d222a00a0c756292c15b88f9f83c/examples/basic-jsx/index.html">learn React without any tooling</a>, the React ecosystem has commonly become associated with an overwhelming explosion of tools.</p>
<p>Eric Clemmons called this phenomenon the “<a href="https://medium.com/@ericclemmons/javascript-fatigue-48d4011b6fc4">JavaScript Fatigue</a>”:</p>
<blockquote>
<p>Ultimately, the problem is that by choosing React (and inherently JSX), youve unwittingly opted into a confusing nest of build tools, boilerplate, linters, &amp; time-sinks to deal with before you ever get to create anything.</p>
</blockquote>
<p>It is tempting to write code in ES2015 and JSX. It is sensible to use a bundler to keep the codebase modular, and a linter to catch the common mistakes. It is nice to have a development server with fast rebuilds, and a command to produce optimized bundles for production.</p>
<p>Combining these tools requires some experience with each of them. Even so, it is far too easy to get dragged into fighting small incompatibilities, unsatisfied peerDependencies, and illegible configuration files.</p>
<p>Many of those tools are plugin platforms and dont directly acknowledge each others existence. They leave it up to the users to wire them together. The tools mature and change independently, and tutorials quickly get out of date.</p>
<blockquote class="twitter-tweet" data-lang="en"><p lang="en" dir="ltr">Marc was almost ready to implement his &quot;hello world&quot; React app <a href="https://t.co/ptdg4yteF1">pic.twitter.com/ptdg4yteF1</a></p>&mdash; Thomas Fuchs (@thomasfuchs) <a href="https://twitter.com/thomasfuchs/status/708675139253174273">March 12, 2016</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
<p>This doesnt mean those tools arent great. To many of us, they have become indispensable, and we very much appreciate the effort of their maintainers. They already have too much on their plates to worry about the state of the React ecosystem.</p>
<p>Still, we knew it was frustrating to spend days setting up a project when all you wanted was to learn React. We wanted to fix this.</p>
<h2>Could We Fix This?</h2>
<p>We found ourselves in an unusual dilemma.</p>
<p>So far, <a href="/react/contributing/design-principles.html#dogfooding">our strategy</a> has been to only release the code that we are using at Facebook. This helped us ensure that every project is battle-tested and has clearly defined scope and priorities.</p>
<p>However, tooling at Facebook is different than at many smaller companies. Linting, transpilation, and packaging are all handled by powerful remote development servers, and product engineers dont need to configure them. While we wish we could give a dedicated server to every user of React, even Facebook cannot scale that well!</p>
<p>The React community is very important to us. We knew that we couldnt fix the problem within the limits of our open source philosophy. This is why we decided to make an exception, and to ship something that we didnt use ourselves, but that we thought would be useful to the community.</p>
<h2>The Quest for a React <abbr title="Command Line Interface">CLI</abbr></h2>
<p>Having just attended <a href="http://embercamp.com/">EmberCamp</a> a week ago, I was excited about <a href="https://ember-cli.com/">Ember CLI</a>. Ember users have a great “getting started” experience thanks to a curated set of tools united under a single command-line interface. I have heard similar feedback about <a href="https://github.com/elm-lang/elm-reactor">Elm Reactor</a>.</p>
<p>Providing a cohesive curated experience is valuable by itself, even if the user could in theory assemble those parts themselves. Kathy Sierra <a href="http://seriouspony.com/blog/2013/7/24/your-app-makes-me-fat">explains it best</a>:</p>
<blockquote>
<p>If your UX asks the user to make <em>choices</em>, for example, even if those choices are both clear and useful, the act of <em>deciding</em> is a cognitive drain. And not just <em>while</em> theyre deciding... even <em>after</em> we choose, an unconscious cognitive background thread is slowly consuming/leaking resources, “Was <em>that</em> the right choice?”</p>
</blockquote>
<p>I never tried to write a command-line tool for React apps, and neither has <a href="https://twitter.com/vjeux">Christopher</a>. We were chatting on Messenger about this idea, and we decided to work together on it for a week as a hackathon project.</p>
<p>We knew that such projects traditionally havent been very successful in the React ecosystem. Christopher told me that multiple “React CLI” projects have started and failed at Facebook. The community tools with similar goals also exist, but so far they have not yet gained enough traction.</p>
<p>Still, we decided it was worth another shot. Christopher and I created a very rough proof of concept on the weekend, and <a href="https://twitter.com/lacker">Kevin</a> soon joined us.</p>
<p>We invited some of the community members to collaborate with us, and we have spent this week working on this tool. We hope that youll enjoy using it! <a href="https://github.com/facebookincubator/create-react-app/issues/11">Let us know what you think.</a></p>
<p>We would like to express our gratitude to <a href="https://twitter.com/mxstbr">Max Stoiber</a>, <a href="https://twitter.com/jbscript">Jonny Buchanan</a>, <a href="https://twitter.com/eanplatter">Ean Platter</a>, <a href="https://github.com/tylermcginnis">Tyler McGinnis</a>, <a href="https://github.com/kentcdodds">Kent C. Dodds</a>, and <a href="https://twitter.com/ericclemmons">Eric Clemmons</a> for their early feedback, ideas, and contributions.</p>
</div>
</div>
<div class="pagination">
<a href="/react/blog/page2/" class="next">
Next Page &raquo;
</a>
</div>
</div>
</section>
<footer class="nav-footer">
<section class="sitemap">
<a href="/react/" class="nav-home">
</a>
<div>
<h5><a href="/react/docs/">Docs</a></h5>
<a href="/react/docs/hello-world.html">Quick Start</a>
<a href="/react/docs/thinking-in-react.html">Thinking in React</a>
<a href="/react/tutorial/tutorial.html">Tutorial</a>
<a href="/react/docs/jsx-in-depth.html">Advanced Guides</a>
</div>
<div>
<h5><a href="/react/community/support.html">Community</a></h5>
<a href="http://stackoverflow.com/questions/tagged/reactjs" target="_blank">Stack Overflow</a>
<a href="https://discuss.reactjs.org/" target="_blank">Discussion Forum</a>
<a href="https://discord.gg/0ZcbPKXt5bZjGY5n" target="_blank">Reactiflux Chat</a>
<a href="https://www.facebook.com/react" target="_blank">Facebook</a>
<a href="https://twitter.com/reactjs" target="_blank">Twitter</a>
</div>
<div>
<h5><a href="/react/community/support.html">Resources</a></h5>
<a href="/react/community/conferences.html">Conferences</a>
<a href="/react/community/videos.html">Videos</a>
<a href="https://github.com/facebook/react/wiki/Examples" target="_blank">Examples</a>
<a href="https://github.com/facebook/react/wiki/Complementary-Tools" target="_blank">Complementary Tools</a>
</div>
<div>
<h5>More</h5>
<a href="/react/blog/">Blog</a>
<a href="https://github.com/facebook/react" target="_blank">GitHub</a>
<a href="http://facebook.github.io/react-native/" target="_blank">React Native</a>
<a href="/react/acknowledgements.html">Acknowledgements</a>
</div>
</section>
<a href="https://code.facebook.com/projects/" target="_blank" class="fbOpenSource">
<img src="/react/img/oss_logo.png" alt="Facebook Open Source" width="170" height="45"/>
</a>
<section class="copyright">
Copyright © 2017 Facebook Inc.
</section>
</footer>
</div>
<div id="fb-root"></div>
<script src="/react/js/anchor-links.js"></script>
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-41298772-1', 'facebook.github.io');
ga('send', 'pageview');
!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="https://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");
(function(d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return;
js = d.createElement(s); js.id = id;
js.src = "//connect.facebook.net/en_US/sdk.js#xfbml=1&version=v2.6&appId=623268441017527";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
docsearch({
apiKey: '36221914cce388c46d0420343e0bb32e',
indexName: 'react',
inputSelector: '#algolia-doc-search'
});
</script>
</body>
</html>