mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Rebuild website
This commit is contained in:
@@ -474,7 +474,7 @@
|
||||
<h4><a class="anchor" name="solution"></a>Solution <a class="hash-link" href="#solution">#</a></h4>
|
||||
<p>If you see rendering logic inside a mixin, it’s time to extract a component!</p>
|
||||
|
||||
<p>Instead of <code>RowMixin</code>, we will define a <code><Row></code> component. We will also replace the convention of defining a <code>getHeaderText()</code> method with the standard mechanism of top-data flow in React: passing props.</p>
|
||||
<p>Instead of <code>RowMixin</code>, we will define a <code><RowHeader></code> component. We will also replace the convention of defining a <code>getHeaderText()</code> method with the standard mechanism of top-data flow in React: passing props.</p>
|
||||
|
||||
<p>Finally, since neither of those components currently need lifecycle hooks or state, we can declare them as simple functions:</p>
|
||||
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="kd">function</span> <span class="nx">RowHeader</span><span class="p">(</span><span class="nx">props</span><span class="p">)</span> <span class="p">{</span>
|
||||
|
||||
+1
-1
@@ -1191,7 +1191,7 @@ The console output is tuned to be minimal to help you focus on the problems:</p>
|
||||
<h4><a class="anchor" name="solution"></a>Solution <a class="hash-link" href="#solution">#</a></h4>
|
||||
<p>If you see rendering logic inside a mixin, it’s time to extract a component!</p>
|
||||
|
||||
<p>Instead of <code>RowMixin</code>, we will define a <code><Row></code> component. We will also replace the convention of defining a <code>getHeaderText()</code> method with the standard mechanism of top-data flow in React: passing props.</p>
|
||||
<p>Instead of <code>RowMixin</code>, we will define a <code><RowHeader></code> component. We will also replace the convention of defining a <code>getHeaderText()</code> method with the standard mechanism of top-data flow in React: passing props.</p>
|
||||
|
||||
<p>Finally, since neither of those components currently need lifecycle hooks or state, we can declare them as simple functions:</p>
|
||||
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="kd">function</span> <span class="nx">RowHeader</span><span class="p">(</span><span class="nx">props</span><span class="p">)</span> <span class="p">{</span>
|
||||
|
||||
@@ -128,6 +128,7 @@
|
||||
<li>Ensure the test suite passes (<code>npm test</code>).</li>
|
||||
<li>Make sure your code lints (<code>npm run lint</code>).</li>
|
||||
<li>Run the <a href="https://flowtype.org/">Flow</a> typechecks (<code>npm run flow</code>).</li>
|
||||
<li>If you added or removed any tests, run <code>./scripts/fiber/record-tests</code> before submitting the pull request, and commit the resulting changes.</li>
|
||||
<li>If you haven't already, complete the CLA.</li>
|
||||
</ol>
|
||||
<h3><a class="anchor" name="contributor-license-agreement-cla"></a>Contributor License Agreement (CLA) <a class="hash-link" href="#contributor-license-agreement-cla">#</a></h3>
|
||||
@@ -180,7 +181,7 @@ You can check the status of your code styling by simply running <code>npm run li
|
||||
<li>2 spaces for indentation (no tabs)</li>
|
||||
<li>Prefer <code>'</code> over <code>"</code></li>
|
||||
<li><code>'use strict';</code></li>
|
||||
<li>80 character line length (<strong>except documentation</strong>)</li>
|
||||
<li>120 character line length (<strong>except documentation</strong>)</li>
|
||||
<li>Write "attractive" code</li>
|
||||
<li>Do not use the optional parameters of <code>setTimeout</code> and <code>setInterval</code></li>
|
||||
</ul>
|
||||
|
||||
@@ -223,6 +223,52 @@
|
||||
<p><a href="https://codepen.io/gaearon/pen/JbbEzX?editors=0010">Try it on CodePen.</a></p>
|
||||
|
||||
<p>Overall, this makes it so that <code><input type="text"></code>, <code><textarea></code>, and <code><select></code> all work very similarly - they all accept a <code>value</code> attribute that you can use to implement a controlled component.</p>
|
||||
<h2><a class="anchor" name="handling-multiple-inputs"></a>Handling Multiple Inputs <a class="hash-link" href="#handling-multiple-inputs">#</a></h2>
|
||||
<p>When you need to handle multiple controlled <code>input</code> elements, you can add a <code>name</code> attribute to each element and let a handler function choose what to do based on the value of <code>event.target.name</code>. For example:</p>
|
||||
<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="kr">class</span> <span class="nx">Reservation</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">constructor</span><span class="p">(</span><span class="nx">props</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="kr">super</span><span class="p">(</span><span class="nx">props</span><span class="p">);</span>
|
||||
<span class="k">this</span><span class="p">.</span><span class="nx">state</span> <span class="o">=</span> <span class="p">{</span>
|
||||
<span class="nx">isGoing</span><span class="o">:</span> <span class="kc">false</span><span class="p">,</span>
|
||||
<span class="nx">numberOfGuests</span><span class="o">:</span> <span class="mi">0</span>
|
||||
<span class="p">};</span>
|
||||
|
||||
<span class="k">this</span><span class="p">.</span><span class="nx">handleInputChange</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">handleInputChange</span><span class="p">.</span><span class="nx">bind</span><span class="p">(</span><span class="k">this</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="nx">handleInputChange</span><span class="p">(</span><span class="nx">event</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="kr">const</span> <span class="nx">target</span> <span class="o">=</span> <span class="nx">event</span><span class="p">.</span><span class="nx">target</span><span class="p">;</span>
|
||||
<span class="kr">const</span> <span class="nx">value</span> <span class="o">=</span> <span class="nx">target</span><span class="p">.</span><span class="nx">type</span> <span class="o">===</span> <span class="s1">'checkbox'</span> <span class="o">?</span> <span class="nx">target</span><span class="p">.</span><span class="nx">checked</span> <span class="o">:</span> <span class="nx">target</span><span class="p">.</span><span class="nx">value</span><span class="p">;</span>
|
||||
<span class="hll"> <span class="kr">const</span> <span class="nx">name</span> <span class="o">=</span> <span class="nx">target</span><span class="p">.</span><span class="nx">name</span><span class="p">;</span>
|
||||
</span>
|
||||
<span class="k">this</span><span class="p">.</span><span class="nx">setState</span><span class="p">({</span>
|
||||
<span class="hll"> <span class="p">[</span><span class="nx">name</span><span class="p">]</span><span class="o">:</span> <span class="nx">value</span>
|
||||
</span> <span class="p">});</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"><</span><span class="nx">div</span><span class="o">></span>
|
||||
<span class="nx">Is</span> <span class="nx">going</span><span class="o">:</span>
|
||||
<span class="o"><</span><span class="nx">input</span>
|
||||
<span class="hll"> <span class="nx">name</span><span class="o">=</span><span class="s2">"isGoing"</span>
|
||||
</span> <span class="nx">type</span><span class="o">=</span><span class="s2">"checkbox"</span>
|
||||
<span class="nx">checked</span><span class="o">=</span><span class="p">{</span><span class="k">this</span><span class="p">.</span><span class="nx">state</span><span class="p">.</span><span class="nx">isGoing</span><span class="p">}</span>
|
||||
<span class="nx">onChange</span><span class="o">=</span><span class="p">{</span><span class="k">this</span><span class="p">.</span><span class="nx">handleInputChange</span><span class="p">}</span>
|
||||
<span class="o">/></span>
|
||||
<span class="nb">Number</span> <span class="nx">of</span> <span class="nx">guests</span><span class="o">:</span>
|
||||
<span class="o"><</span><span class="nx">input</span>
|
||||
<span class="hll"> <span class="nx">name</span><span class="o">=</span><span class="s2">"numberOfGuests"</span>
|
||||
</span> <span class="nx">type</span><span class="o">=</span><span class="s2">"number"</span>
|
||||
<span class="nx">value</span><span class="o">=</span><span class="p">{</span><span class="k">this</span><span class="p">.</span><span class="nx">state</span><span class="p">.</span><span class="nx">numberOfGuests</span><span class="p">}</span>
|
||||
<span class="nx">onChange</span><span class="o">=</span><span class="p">{</span><span class="k">this</span><span class="p">.</span><span class="nx">handleInputChange</span><span class="p">}</span>
|
||||
<span class="o">/></span>
|
||||
<span class="o"><</span><span class="err">/div></span>
|
||||
<span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
</code></pre></div>
|
||||
<p><a href="https://codepen.io/keyanzhang/pen/pRENvx?editors=0010">Try it on CodePen.</a></p>
|
||||
<h2><a class="anchor" name="alternatives-to-controlled-components"></a>Alternatives to Controlled Components <a class="hash-link" href="#alternatives-to-controlled-components">#</a></h2>
|
||||
<p>It can sometimes be tedious to use controlled components, because you need to write an event handler for every way your data can change and pipe all of the input state through a React component. This can become particularly annoying when you are converting a preexisting codebase to React, or integrating a React application with a non-React library. In these situations, you might want to check out <a href="/react/docs/uncontrolled-components.html">uncontrolled components</a>, an alternative technique for implementing input forms.</p>
|
||||
|
||||
|
||||
@@ -133,12 +133,13 @@
|
||||
<span class="p">))}</span>
|
||||
<span class="o"><</span><span class="err">/div></span>
|
||||
<span class="p">);</span>
|
||||
<span class="p">}}</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
</code></pre></div>
|
||||
<p>Later, you write a component for subscribing to a single blog post, which follows a similar pattern:</p>
|
||||
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="kr">class</span> <span class="nx">BlogPost</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">constructor</span><span class="p">()</span> <span class="p">{</span>
|
||||
<span class="kr">super</span><span class="p">();</span>
|
||||
<span class="nx">constructor</span><span class="p">(</span><span class="nx">props</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="kr">super</span><span class="p">(</span><span class="nx">props</span><span class="p">);</span>
|
||||
<span class="k">this</span><span class="p">.</span><span class="nx">handleChange</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">handleChange</span><span class="p">.</span><span class="nx">bind</span><span class="p">(</span><span class="k">this</span><span class="p">);</span>
|
||||
<span class="k">this</span><span class="p">.</span><span class="nx">state</span> <span class="o">=</span> <span class="p">{</span>
|
||||
<span class="nx">blogPost</span><span class="o">:</span> <span class="nx">DataSource</span><span class="p">.</span><span class="nx">getBlogPost</span><span class="p">(</span><span class="nx">props</span><span class="p">.</span><span class="nx">id</span><span class="p">)</span>
|
||||
@@ -161,7 +162,8 @@
|
||||
|
||||
<span class="nx">render</span><span class="p">()</span> <span class="p">{</span>
|
||||
<span class="k">return</span> <span class="o"><</span><span class="nx">BlogPost</span> <span class="nx">blogPost</span><span class="o">=</span><span class="p">{</span><span class="k">this</span><span class="p">.</span><span class="nx">state</span><span class="p">.</span><span class="nx">blogPost</span><span class="p">}</span> <span class="o">/></span><span class="p">;</span>
|
||||
<span class="p">}}</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
</code></pre></div>
|
||||
<p><code>CommentList</code> and <code>BlogPost</code> aren't identical — they call different methods on <code>DataSource</code>, and they render different output. But much of their implementation is the same:</p>
|
||||
|
||||
@@ -219,7 +221,7 @@
|
||||
<span class="c1">// Notice that we pass through any additional props</span>
|
||||
<span class="k">return</span> <span class="o"><</span><span class="nx">WrappedComponent</span> <span class="nx">data</span><span class="o">=</span><span class="p">{</span><span class="k">this</span><span class="p">.</span><span class="nx">state</span><span class="p">.</span><span class="nx">data</span><span class="p">}</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="o">/></span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">});</span>
|
||||
<span class="p">};</span>
|
||||
<span class="p">}</span>
|
||||
</code></pre></div>
|
||||
<p>Note that an HOC doesn't modify the input component, nor does it use inheritance to copy its behavior. Rather, an HOC <em>composes</em> the original component by <em>wrapping</em> it in a container component. An HOC is a pure function with zero side-effects.</p>
|
||||
|
||||
@@ -140,8 +140,16 @@ npm install --save react react-dom
|
||||
<p>If you use <a href="https://github.com/facebookincubator/create-react-app">Create React App</a>, <code>npm run build</code> will create an optimized build of your app in the <code>build</code> folder.</p>
|
||||
<h4><a class="anchor" name="webpack"></a>Webpack <a class="hash-link" href="#webpack">#</a></h4>
|
||||
<p>Include both <code>DefinePlugin</code> and <code>UglifyJsPlugin</code> into your production Webpack configuration as described in <a href="https://webpack.js.org/guides/production-build/">this guide</a>.</p>
|
||||
|
||||
<blockquote>
|
||||
<p><strong>Note:</strong></p>
|
||||
|
||||
<p>This guide works with Webpack 1.x and 2, but is hosted on the new Webpack 2 site. If you're not using the Webpack 2 beta, refer to the <a href="https://webpack.github.io/">Webpack 1.x website</a> for all other documentation.</p>
|
||||
</blockquote>
|
||||
<h4><a class="anchor" name="browserify"></a>Browserify <a class="hash-link" href="#browserify">#</a></h4>
|
||||
<p>Run Browserify with <code>NODE_ENV</code> environment variable set to <code>production</code> and use <a href="https://github.com/mishoo/UglifyJS">UglifyJS</a> as the last build step so that development-only code gets stripped out.</p>
|
||||
<h4><a class="anchor" name="rollup"></a>Rollup <a class="hash-link" href="#rollup">#</a></h4>
|
||||
<p>Use <a href="https://github.com/rollup/rollup-plugin-replace">rollup-plugin-replace</a> plugin together with <a href="https://github.com/rollup/rollup-plugin-commonjs">rollup-plugin-commonjs</a> (in that order) to remove development-only code. <a href="https://gist.github.com/Rich-Harris/cb14f4bc0670c47d00d191565be36bf0">See this gist</a> for a complete setup example.</p>
|
||||
<h3><a class="anchor" name="using-a-cdn"></a>Using a CDN <a class="hash-link" href="#using-a-cdn">#</a></h3>
|
||||
<p>If you don't want to use npm to manage client packages, the <code>react</code> and <code>react-dom</code> npm packages also provide single-file distributions in <code>dist</code> folders, which are hosted on a CDN:</p>
|
||||
<div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><script </span><span class="na">src=</span><span class="s">"https://unpkg.com/react@15/dist/react.js"</span><span class="nt">></script></span>
|
||||
|
||||
@@ -112,7 +112,7 @@
|
||||
</code></pre></div>
|
||||
<p><a href="http://codepen.io/gaearon/pen/PGEjdG?editors=0010">Try it on CodePen.</a></p>
|
||||
|
||||
<p>We split JSX over multiple lines for readability. While it isn't mandatory, when doing this, we also recommend wrapping it in parentheses to avoid the pitfalls of <a href="http://stackoverflow.com/q/2846283">automatic semicolon insertion</a>.</p>
|
||||
<p>We split JSX over multiple lines for readability. While it isn't required, when doing this, we also recommend wrapping it in parentheses to avoid the pitfalls of <a href="http://stackoverflow.com/q/2846283">automatic semicolon insertion</a>.</p>
|
||||
<h3><a class="anchor" name="jsx-is-an-expression-too"></a>JSX is an Expression Too <a class="hash-link" href="#jsx-is-an-expression-too">#</a></h3>
|
||||
<p>After compilation, JSX expressions become regular JavaScript objects.</p>
|
||||
|
||||
@@ -129,7 +129,9 @@
|
||||
</code></pre></div>
|
||||
<p>You may also use curly braces to embed a JavaScript expression in an attribute:</p>
|
||||
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="kr">const</span> <span class="nx">element</span> <span class="o">=</span> <span class="o"><</span><span class="nx">img</span> <span class="nx">src</span><span class="o">=</span><span class="p">{</span><span class="nx">user</span><span class="p">.</span><span class="nx">avatarUrl</span><span class="p">}</span><span class="o">><</span><span class="err">/img>;</span>
|
||||
</code></pre></div><h3><a class="anchor" name="specifying-children-with-jsx"></a>Specifying Children with JSX <a class="hash-link" href="#specifying-children-with-jsx">#</a></h3>
|
||||
</code></pre></div>
|
||||
<p>Don't put quotes around curly braces when embedding a JavaScript expression in an attribute. Otherwise JSX will treat the attribute as a string literal rather than an expression. You should either use quotes (for string values) or curly braces (for expressions), but not both in the same attribute.</p>
|
||||
<h3><a class="anchor" name="specifying-children-with-jsx"></a>Specifying Children with JSX <a class="hash-link" href="#specifying-children-with-jsx">#</a></h3>
|
||||
<p>If a tag is empty, you may close it immediately with <code>/></code>, like XML:</p>
|
||||
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="kr">const</span> <span class="nx">element</span> <span class="o">=</span> <span class="o"><</span><span class="nx">img</span> <span class="nx">src</span><span class="o">=</span><span class="p">{</span><span class="nx">user</span><span class="p">.</span><span class="nx">avatarUrl</span><span class="p">}</span> <span class="o">/></span><span class="p">;</span>
|
||||
</code></pre></div>
|
||||
|
||||
@@ -95,6 +95,17 @@
|
||||
<span class="p">}),</span>
|
||||
<span class="k">new</span> <span class="nx">webpack</span><span class="p">.</span><span class="nx">optimize</span><span class="p">.</span><span class="nx">UglifyJsPlugin</span><span class="p">()</span>
|
||||
</code></pre></div>
|
||||
<ul>
|
||||
<li>For Rollup, you need to use the <a href="https://github.com/rollup/rollup-plugin-replace">replace</a> plugin <em>before</em> the <a href="https://github.com/rollup/rollup-plugin-commonjs">commonjs</a> plugin so that development-only modules are not imported. For a complete setup example <a href="https://gist.github.com/Rich-Harris/cb14f4bc0670c47d00d191565be36bf0">see this gist</a>.</li>
|
||||
</ul>
|
||||
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="nx">plugins</span><span class="o">:</span> <span class="p">[</span>
|
||||
<span class="nx">require</span><span class="p">(</span><span class="s1">'rollup-plugin-replace'</span><span class="p">)({</span>
|
||||
<span class="s1">'process.env.NODE_ENV'</span><span class="o">:</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">(</span><span class="s1">'production'</span><span class="p">)</span>
|
||||
<span class="p">}),</span>
|
||||
<span class="nx">require</span><span class="p">(</span><span class="s1">'rollup-plugin-commonjs'</span><span class="p">)(),</span>
|
||||
<span class="c1">// ...</span>
|
||||
<span class="p">]</span>
|
||||
</code></pre></div>
|
||||
<p>The development build includes extra warnings that are helpful when building your apps, but it is slower due to the extra bookkeeping it does.</p>
|
||||
<h2><a class="anchor" name="profiling-components-with-chrome-timeline"></a>Profiling Components with Chrome Timeline <a class="hash-link" href="#profiling-components-with-chrome-timeline">#</a></h2>
|
||||
<p>In the <strong>development</strong> mode, you can visualize how components mount, update, and unmount, using the performance tools in supported browsers. For example:</p>
|
||||
@@ -219,7 +230,7 @@
|
||||
<span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
</code></pre></div>
|
||||
<p>The problem is that <code>PureComponent</code> will do a simple comparison between the old and new values of <code>this.props.words</code>. Since this code mutates the <code>words</code> array in the <code>handleClick</code> method of <code>WordAdder</code>, the old and new values of <code>this.props.words</code> will compare as equal, even though the actual words in the array have changed. The <code>ListOfWords</code> will thus not update even though it has new words that shoud be rendered.</p>
|
||||
<p>The problem is that <code>PureComponent</code> will do a simple comparison between the old and new values of <code>this.props.words</code>. Since this code mutates the <code>words</code> array in the <code>handleClick</code> method of <code>WordAdder</code>, the old and new values of <code>this.props.words</code> will compare as equal, even though the actual words in the array have changed. The <code>ListOfWords</code> will thus not update even though it has new words that should be rendered.</p>
|
||||
<h2><a class="anchor" name="the-power-of-not-mutating-data"></a>The Power Of Not Mutating Data <a class="hash-link" href="#the-power-of-not-mutating-data">#</a></h2>
|
||||
<p>The simplest way to avoid this problem is to avoid mutating values that you are using as props or state. For example, the <code>handleClick</code> method above could be rewritten using <code>concat</code> as:</p>
|
||||
<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">handleClick</span><span class="p">()</span> <span class="p">{</span>
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
<span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
</code></pre></div>
|
||||
<p>You may not use the <code>ref</code> attribute on functional components because they don't have instances. You can, however, use the <code>ref</code> attribute inside the <code>render</code> function of a functional component:</p>
|
||||
<p>You may not use the <code>ref</code> attribute on functional components because they don't have instances. You can, however, use the <code>ref</code> attribute inside the functional component:</p>
|
||||
<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="kd">function</span> <span class="nx">CustomTextInput</span><span class="p">(</span><span class="nx">props</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="hll"> <span class="c1">// textInput must be declared here so the ref callback can refer to it</span>
|
||||
</span><span class="hll"> <span class="kd">let</span> <span class="nx">textInput</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
|
||||
|
||||
@@ -207,7 +207,7 @@
|
||||
|
||||
<p>You can start seeing how your application will behave: set <code>filterText</code> to <code>"ball"</code> and refresh your app. You'll see that the data table is updated correctly.</p>
|
||||
<h2><a class="anchor" name="step-5-add-inverse-data-flow"></a>Step 5: Add Inverse Data Flow <a class="hash-link" href="#step-5-add-inverse-data-flow">#</a></h2>
|
||||
<p data-height="265" data-theme-id="0" data-slug-hash="JbYQvL" data-default-tab="js,result" data-user="snakajima" data-embed-version="2" data-pen-title="Thinking In React: Step 5" class="codepen">See the Pen <a href="http://codepen.io/snakajima/pen/JbYQvL/">Thinking In React: Step 5</a> on <a href="http://codepen.io">CodePen</a>.</p>
|
||||
<p data-height="265" data-theme-id="0" data-slug-hash="JbYQvL" data-default-tab="js,result" data-user="snakajima" data-embed-version="2" data-pen-title="Thinking In React: Step 5" class="codepen">See the Pen <a href="http://codepen.io/rohan10/pen/qRqmjd">Thinking In React: Step 5</a> on <a href="http://codepen.io">CodePen</a>.</p>
|
||||
|
||||
<script async src="https://production-assets.codepen.io/assets/embed/ei.js"></script>
|
||||
|
||||
@@ -217,7 +217,7 @@
|
||||
|
||||
<p>If you try to type or check the box in the current version of the example, you'll see that React ignores your input. This is intentional, as we've set the <code>value</code> prop of the <code>input</code> to always be equal to the <code>state</code> passed in from <code>FilterableProductTable</code>.</p>
|
||||
|
||||
<p>Let's think about what we want to happen. We want to make sure that whenever the user changes the form, we update the state to reflect the user input. Since components should only update their own state, <code>FilterableProductTable</code> will pass a callback to <code>SearchBar</code> that will fire whenever the state should be updated. We can use the <code>onChange</code> event on the inputs to be notified of it. And the callback passed by <code>FilterableProductTable</code> will call <code>setState()</code>, and the app will be updated.</p>
|
||||
<p>Let's think about what we want to happen. We want to make sure that whenever the user changes the form, we update the state to reflect the user input. Since components should only update their own state, <code>FilterableProductTable</code> will pass callbacks to <code>SearchBar</code> that will fire whenever the state should be updated. We can use the <code>onChange</code> event on the inputs to be notified of it. The callbacks passed by <code>FilterableProductTable</code> will call <code>setState()</code>, and the app will be updated.</p>
|
||||
|
||||
<p>Though this sounds complex, it's really just a few lines of code. And it's really explicit how your data is flowing throughout the app.</p>
|
||||
<h2><a class="anchor" name="and-thats-it"></a>And That's It <a class="hash-link" href="#and-thats-it">#</a></h2>
|
||||
|
||||
@@ -985,7 +985,7 @@ The console output is tuned to be minimal to help you focus on the problems:<
|
||||
<h4><a class="anchor" name="solution"></a>Solution <a class="hash-link" href="#solution">#</a></h4>
|
||||
<p>If you see rendering logic inside a mixin, it’s time to extract a component!</p>
|
||||
|
||||
<p>Instead of <code>RowMixin</code>, we will define a <code>&lt;Row&gt;</code> component. We will also replace the convention of defining a <code>getHeaderText()</code> method with the standard mechanism of top-data flow in React: passing props.</p>
|
||||
<p>Instead of <code>RowMixin</code>, we will define a <code>&lt;RowHeader&gt;</code> component. We will also replace the convention of defining a <code>getHeaderText()</code> method with the standard mechanism of top-data flow in React: passing props.</p>
|
||||
|
||||
<p>Finally, since neither of those components currently need lifecycle hooks or state, we can declare them as simple functions:</p>
|
||||
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="kd">function</span> <span class="nx">RowHeader</span><span class="p">(</span><span class="nx">props</span><span class="p">)</span> <span class="p">{</span>
|
||||
|
||||
Vendored
-29
File diff suppressed because one or more lines are too long
@@ -1,91 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* This is a web interface for the HTML to JSX converter contained in
|
||||
* `html-jsx-lib.js`.
|
||||
*/
|
||||
;(function () {
|
||||
|
||||
var HELLO_COMPONENT = "\
|
||||
<!-- Hello world -->\n\
|
||||
<div class=\"awesome\" style=\"border: 1px solid red\">\n\
|
||||
<label for=\"name\">Enter your name: </label>\n\
|
||||
<input type=\"text\" id=\"name\" />\n\
|
||||
</div>\n\
|
||||
<p>Enter your HTML here</p>\
|
||||
";
|
||||
|
||||
var HTMLtoJSXComponent = React.createClass({
|
||||
displayName: "HTMLtoJSXComponent",
|
||||
|
||||
getInitialState: function () {
|
||||
return {
|
||||
outputClassName: 'NewComponent',
|
||||
createClass: true
|
||||
};
|
||||
},
|
||||
onReactClassNameChange: function (evt) {
|
||||
this.setState({ outputClassName: evt.target.value });
|
||||
},
|
||||
onCreateClassChange: function (evt) {
|
||||
this.setState({ createClass: evt.target.checked });
|
||||
},
|
||||
setInput: function (input) {
|
||||
this.setState({ input: input });
|
||||
this.convertToJsx();
|
||||
},
|
||||
convertToJSX: function (input) {
|
||||
var converter = new HTMLtoJSX({
|
||||
outputClassName: this.state.outputClassName,
|
||||
createClass: this.state.createClass
|
||||
});
|
||||
return converter.convert(input);
|
||||
},
|
||||
render: function () {
|
||||
return React.createElement(
|
||||
"div",
|
||||
null,
|
||||
React.createElement(
|
||||
"div",
|
||||
{ id: "options" },
|
||||
React.createElement(
|
||||
"label",
|
||||
null,
|
||||
React.createElement("input", {
|
||||
type: "checkbox",
|
||||
checked: this.state.createClass,
|
||||
onChange: this.onCreateClassChange }),
|
||||
"Create class"
|
||||
),
|
||||
React.createElement(
|
||||
"label",
|
||||
{ style: { display: this.state.createClass ? '' : 'none' } },
|
||||
"· Class name:",
|
||||
React.createElement("input", {
|
||||
type: "text",
|
||||
value: this.state.outputClassName,
|
||||
onChange: this.onReactClassNameChange })
|
||||
)
|
||||
),
|
||||
React.createElement(ReactPlayground, {
|
||||
codeText: HELLO_COMPONENT,
|
||||
renderCode: true,
|
||||
transformer: this.convertToJSX,
|
||||
showCompiledJSTab: false,
|
||||
editorTabTitle: "Live HTML Editor"
|
||||
})
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
ReactDOM.render(React.createElement(HTMLtoJSXComponent, null), document.getElementById('jsxCompiler'));
|
||||
})();
|
||||
@@ -325,7 +325,7 @@
|
||||
|
||||
<p>Square no longer keeps its own state; it receives its value from its parent <code>Board</code> and informs its parent when it's clicked. We call components like this <strong>controlled components</strong>.</p>
|
||||
<h2><a class="anchor" name="why-immutability-is-important"></a>Why Immutability Is Important <a class="hash-link" href="#why-immutability-is-important">#</a></h2>
|
||||
<p>In the previous code example, I suggest using the <code>.slice()</code> operator to copy the <code>squares</code> array prior to making changes and to prevent mutating the existing array. Let's talk about what this means and why it is an important concept to learn.</p>
|
||||
<p>In the previous code example, we suggest using the <code>.slice()</code> operator to copy the <code>squares</code> array prior to making changes and to prevent mutating the existing array. Let's talk about what this means and why it is an important concept to learn.</p>
|
||||
|
||||
<p>There are generally two ways for changing data. The first method is to <em>mutate</em> the data by directly changing the values of a variable. The second method is to replace the data with a new copy of the object that also includes desired changes.</p>
|
||||
<h4><a class="anchor" name="data-change-with-mutation"></a>Data change with mutation <a class="hash-link" href="#data-change-with-mutation">#</a></h4><div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">player</span> <span class="o">=</span> <span class="p">{</span><span class="nx">score</span><span class="o">:</span> <span class="mi">1</span><span class="p">,</span> <span class="nx">name</span><span class="o">:</span> <span class="s1">'Jeff'</span><span class="p">};</span>
|
||||
|
||||
Reference in New Issue
Block a user