Files
react/docs/multiple-components-zh-CN.html
T
Paul O’Shannessy 63dff641cf Update website
2016-03-21 11:28:34 -07:00

609 lines
32 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>复合组件 | React</title>
<meta name="viewport" content="width=device-width">
<meta property="og:title" content="复合组件 | React">
<meta property="og:type" content="website">
<meta property="og:url" content="https://facebook.github.io/react/docs/multiple-components-zh-CN.html">
<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="/react/js/html5shiv.min.js"></script>
<script src="/react/js/es5-shim.min.js"></script>
<script src="/react/js/es5-sham.min.js"></script>
<![endif]-->
<script type="text/javascript" src="https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js"></script>
<script src="/react/js/codemirror.js"></script>
<script src="/react/js/javascript.js"></script>
<script src="/react/js/react.js"></script>
<script src="/react/js/react-dom.js"></script>
<script src="/react/js/babel-browser.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/index.html">
<img class="nav-logo" src="/react/img/logo.svg" width="36" height="36">
React
</a>
<ul class="nav-site nav-site-internal">
<li><a href="/react/docs/getting-started.html" class="active">Docs</a></li>
<li><a href="/react/support.html">Support</a></li>
<li><a href="/react/downloads.html">Download</a></li>
<li><a href="/react/blog/">Blog</a></li>
<li>
<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://facebook.github.io/react-native/">React Native</a></li>
</ul>
</div>
</div>
<section class="content wrap documentationContent">
<div class="nav-docs">
<!-- Docs Nav -->
<div class="nav-docs-section">
<h3>Quick Start</h3>
<ul>
<li>
<a href="/react/docs/getting-started.html">Getting Started</a>
</li>
<li>
<a href="/react/docs/tutorial.html">Tutorial</a>
</li>
<li>
<a href="/react/docs/thinking-in-react.html">Thinking in React</a>
</li>
</ul>
</div>
<div class="nav-docs-section">
<h3>Community Resources</h3>
<ul>
<li>
<a href="/react/docs/conferences.html">Conferences</a>
</li>
<li>
<a href="/react/docs/videos.html">Videos</a>
</li>
<li>
<a href="https://github.com/facebook/react/wiki/Complementary-Tools" class="external">Complementary Tools</a>
</li>
<li>
<a href="https://github.com/facebook/react/wiki/Examples" class="external">Examples</a>
</li>
</ul>
</div>
<div class="nav-docs-section">
<h3>Guides</h3>
<ul>
<li>
<a href="/react/docs/why-react.html">Why React?</a>
</li>
<li>
<a href="/react/docs/displaying-data.html">Displaying Data</a>
<ul>
<li>
<a href="/react/docs/jsx-in-depth.html">JSX in Depth</a>
</li>
<li>
<a href="/react/docs/jsx-spread.html">JSX Spread Attributes</a>
</li>
<li>
<a href="/react/docs/jsx-gotchas.html">JSX Gotchas</a>
</li>
</ul>
</li>
<li>
<a href="/react/docs/interactivity-and-dynamic-uis.html">Interactivity and Dynamic UIs</a>
</li>
<li>
<a href="/react/docs/multiple-components.html">Multiple Components</a>
</li>
<li>
<a href="/react/docs/reusable-components.html">Reusable Components</a>
</li>
<li>
<a href="/react/docs/transferring-props.html">Transferring Props</a>
</li>
<li>
<a href="/react/docs/forms.html">Forms</a>
</li>
<li>
<a href="/react/docs/working-with-the-browser.html">Working With the Browser</a>
<ul>
<li>
<a href="/react/docs/more-about-refs.html">Refs to Components</a>
</li>
</ul>
</li>
<li>
<a href="/react/docs/tooling-integration.html">Tooling Integration</a>
</li>
<li>
<a href="/react/docs/addons.html">Add-Ons</a>
<ul>
<li>
<a href="/react/docs/animation.html">Animation</a>
</li>
<li>
<a href="/react/docs/two-way-binding-helpers.html">Two-Way Binding Helpers</a>
</li>
<li>
<a href="/react/docs/test-utils.html">Test Utilities</a>
</li>
<li>
<a href="/react/docs/clone-with-props.html">Cloning Elements</a>
</li>
<li>
<a href="/react/docs/create-fragment.html">Keyed Fragments</a>
</li>
<li>
<a href="/react/docs/update.html">Immutability Helpers</a>
</li>
<li>
<a href="/react/docs/pure-render-mixin.html">PureRenderMixin</a>
</li>
<li>
<a href="/react/docs/perf.html">Performance Tools</a>
</li>
<li>
<a href="/react/docs/shallow-compare.html">Shallow Compare</a>
</li>
</ul>
</li>
<li>
<a href="/react/docs/advanced-performance.html">Advanced Performance</a>
</li>
<li>
<a href="/react/docs/context.html">Context</a>
</li>
</ul>
</div>
<div class="nav-docs-section">
<h3>Reference</h3>
<ul>
<li>
<a href="/react/docs/top-level-api.html">Top-Level API</a>
</li>
<li>
<a href="/react/docs/component-api.html">Component API</a>
</li>
<li>
<a href="/react/docs/component-specs.html">Component Specs and Lifecycle</a>
</li>
<li>
<a href="/react/docs/tags-and-attributes.html">Supported Tags and Attributes</a>
</li>
<li>
<a href="/react/docs/events.html">Event System</a>
</li>
<li>
<a href="/react/docs/dom-differences.html">DOM Differences</a>
</li>
<li>
<a href="/react/docs/special-non-dom-attributes.html">Special Non-DOM Attributes</a>
</li>
<li>
<a href="/react/docs/reconciliation.html">Reconciliation</a>
</li>
<li>
<a href="/react/docs/webcomponents.html">Web Components</a>
</li>
<li>
<a href="/react/docs/glossary.html">React (Virtual) DOM Terminology</a>
</li>
</ul>
</div>
<div class="nav-docs-section">
<h3>Flux</h3>
<ul>
<li>
<a href="https://facebook.github.io/flux/docs/overview.html" class="external">Flux Overview</a>
</li>
<li>
<a href="https://facebook.github.io/flux/docs/todo-list.html" class="external">Flux TodoMVC Tutorial</a>
</li>
</ul>
</div>
<!-- Tips Nav -->
<div class="nav-docs-section">
<h3>Tips</h3>
<ul>
<li>
<a href="/react/tips/introduction.html">Introduction</a>
</li>
<li>
<a href="/react/tips/inline-styles.html">Inline Styles</a>
</li>
<li>
<a href="/react/tips/if-else-in-JSX.html">If-Else in JSX</a>
</li>
<li>
<a href="/react/tips/self-closing-tag.html">Self-Closing Tag</a>
</li>
<li>
<a href="/react/tips/maximum-number-of-jsx-root-nodes.html">Maximum Number of JSX Root Nodes</a>
</li>
<li>
<a href="/react/tips/style-props-value-px.html">Shorthand for Specifying Pixel Values in style props</a>
</li>
<li>
<a href="/react/tips/children-props-type.html">Type of the Children props</a>
</li>
<li>
<a href="/react/tips/controlled-input-null-value.html">Value of null for Controlled Input</a>
</li>
<li>
<a href="/react/tips/componentWillReceiveProps-not-triggered-after-mounting.html">componentWillReceiveProps Not Triggered After Mounting</a>
</li>
<li>
<a href="/react/tips/props-in-getInitialState-as-anti-pattern.html">Props in getInitialState Is an Anti-Pattern</a>
</li>
<li>
<a href="/react/tips/dom-event-listeners.html">DOM Event Listeners in a Component</a>
</li>
<li>
<a href="/react/tips/initial-ajax.html">Load Initial Data via AJAX</a>
</li>
<li>
<a href="/react/tips/false-in-jsx.html">False in JSX</a>
</li>
<li>
<a href="/react/tips/communicate-between-components.html">Communicate Between Components</a>
</li>
<li>
<a href="/react/tips/expose-component-functions.html">Expose Component Functions</a>
</li>
<li>
<a href="/react/tips/children-undefined.html">this.props.children undefined</a>
</li>
<li>
<a href="/react/tips/use-react-with-other-libraries.html">Use React with Other Libraries</a>
</li>
<li>
<a href="/react/tips/dangerously-set-inner-html.html">Dangerously Set innerHTML</a>
</li>
</ul>
</div>
</div>
<div class="inner-content">
<h1>
复合组件
<a class="edit-page-link" href="https://github.com/facebook/react/tree/master/docs/docs/04-multiple-components.zh-CN.md" target="_blank">Edit on GitHub</a>
</h1>
<div class="subHeader"></div>
<p>目前为止,我们已经学了如何用单个组件来展示数据和处理用户输入。下一步让我们来体验 React 最激动人心的特性之一:可组合性(composability)。</p>
<h2><a class="anchor" name=""></a>动机:关注分离 <a class="hash-link" href="#">#</a></h2>
<p>通过复用那些接口定义良好的组件来开发新的模块化组件,我们得到了与使用函数和类相似的好处。具体来说就是能够通过开发简单的组件把程序的<em>不同关注面分离</em>。如果为程序开发一套自定义的组件库,那么就能以最适合业务场景的方式来展示你的用户界面。</p>
<h2><a class="anchor" name=""></a>组合实例 <a class="hash-link" href="#">#</a></h2>
<p>让我们用 Facebook Graph API 来开发一个显示 Facebook 页面图片和用户名的简单 Avatar 组件吧。</p>
<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">Avatar</span> <span class="o">=</span> <span class="nx">React</span><span class="p">.</span><span class="nx">createClass</span><span class="p">({</span>
<span class="nx">render</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="o">&lt;</span><span class="nx">div</span><span class="o">&gt;</span>
<span class="o">&lt;</span><span class="nx">PagePic</span> <span class="nx">pagename</span><span class="o">=</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">pagename</span><span class="p">}</span> <span class="o">/&gt;</span>
<span class="o">&lt;</span><span class="nx">PageLink</span> <span class="nx">pagename</span><span class="o">=</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">pagename</span><span class="p">}</span> <span class="o">/&gt;</span>
<span class="o">&lt;</span><span class="err">/div&gt;</span>
<span class="p">);</span>
<span class="p">}</span>
<span class="p">});</span>
<span class="kd">var</span> <span class="nx">PagePic</span> <span class="o">=</span> <span class="nx">React</span><span class="p">.</span><span class="nx">createClass</span><span class="p">({</span>
<span class="nx">render</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="o">&lt;</span><span class="nx">img</span> <span class="nx">src</span><span class="o">=</span><span class="p">{</span><span class="s1">&#39;https://graph.facebook.com/&#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">pagename</span> <span class="o">+</span> <span class="s1">&#39;/picture&#39;</span><span class="p">}</span> <span class="o">/&gt;</span>
<span class="p">);</span>
<span class="p">}</span>
<span class="p">});</span>
<span class="kd">var</span> <span class="nx">PageLink</span> <span class="o">=</span> <span class="nx">React</span><span class="p">.</span><span class="nx">createClass</span><span class="p">({</span>
<span class="nx">render</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="o">&lt;</span><span class="nx">a</span> <span class="nx">href</span><span class="o">=</span><span class="p">{</span><span class="s1">&#39;https://www.facebook.com/&#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">pagename</span><span class="p">}</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">pagename</span><span class="p">}</span>
<span class="o">&lt;</span><span class="err">/a&gt;</span>
<span class="p">);</span>
<span class="p">}</span>
<span class="p">});</span>
<span class="nx">ReactDOM</span><span class="p">.</span><span class="nx">render</span><span class="p">(</span>
<span class="o">&lt;</span><span class="nx">Avatar</span> <span class="nx">pagename</span><span class="o">=</span><span class="s2">&quot;Engineering&quot;</span> <span class="o">/&gt;</span><span class="p">,</span>
<span class="nb">document</span><span class="p">.</span><span class="nx">getElementById</span><span class="p">(</span><span class="s1">&#39;example&#39;</span><span class="p">)</span>
<span class="p">);</span>
</code></pre></div><h2><a class="anchor" name=""></a>从属关系 <a class="hash-link" href="#">#</a></h2>
<p>上面例子中,<code>Avatar</code> 拥有 <code>PagePic</code><code>PageLink</code> 的实例。<code>拥有者</code> 就是给其它组件设置 <code>props</code> 的那个组件。更正式地说,如果组件 <code>Y</code><code>render()</code> 方法是创建了组件 <code>X</code>,那么 <code>Y</code> 就拥有 <code>X</code>。上面讲过,组件不能修改自身的 <code>props</code> - 它们总是与它们拥有者设置的保持一致。这是保持用户界面一致性的基本不变量。</p>
<p>把从属关系与父子关系加以区别至关重要。从属关系是 React 特有的,而父子关系简单来讲就是DOM 里的标签的关系。在上一个例子中,<code>Avatar</code> 拥有 <code>div</code><code>PagePic</code><code>PageLink</code> 实例,<code>div</code><code>PagePic</code><code>PageLink</code> 实例的<strong>父级</strong>(但不是拥有者)。</p>
<h2><a class="anchor" name=""></a>子级 <a class="hash-link" href="#">#</a></h2>
<p>实例化 React 组件时,你可以在开始标签和结束标签之间引用在React 组件或者Javascript 表达式:</p>
<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="o">&lt;</span><span class="nx">Parent</span><span class="o">&gt;&lt;</span><span class="nx">Child</span> <span class="o">/&gt;&lt;</span><span class="err">/Parent&gt;</span>
</code></pre></div>
<p><code>Parent</code> 能通过专门的 <code>this.props.children</code> props 读取子级。<strong><code>this.props.children</code> 是一个不透明的数据结构:</strong> 通过 <a href="/react/docs/top-level-api.html#react.children">React.Children 工具类</a> 来操作。</p>
<h3><a class="anchor" name="reconciliation"></a>子级校正(Reconciliation <a class="hash-link" href="#reconciliation">#</a></h3>
<p><strong>校正就是每次 render 方法调用后 React 更新 DOM 的过程。</strong> 一般情况下,子级会根据它们被渲染的顺序来做校正。例如,下面代码描述了两次渲染的过程:</p>
<div class="highlight"><pre><code class="language-html" data-lang="html">// 第一次渲染
<span class="nt">&lt;Card&gt;</span>
<span class="nt">&lt;p&gt;</span>Paragraph 1<span class="nt">&lt;/p&gt;</span>
<span class="nt">&lt;p&gt;</span>Paragraph 2<span class="nt">&lt;/p&gt;</span>
<span class="nt">&lt;/Card&gt;</span>
// 第二次渲染
<span class="nt">&lt;Card&gt;</span>
<span class="nt">&lt;p&gt;</span>Paragraph 2<span class="nt">&lt;/p&gt;</span>
<span class="nt">&lt;/Card&gt;</span>
</code></pre></div>
<p>直观来看,只是删除了<code>&lt;p&gt;Paragraph 1&lt;/p&gt;</code>。事实上,React 先更新第一个子级的内容,然后删除最后一个组件。React 是根据子级的<em>顺序</em>来校正的。</p>
<h3><a class="anchor" name=""></a>子组件状态管理 <a class="hash-link" href="#">#</a></h3>
<p>对于大多数组件,这没什么大碍。但是,对于使用 <code>this.state</code> 来在多次渲染过程中里维持数据的状态化组件,这样做潜在很多问题。</p>
<p>多数情况下,可以通过隐藏组件而不是删除它们来绕过这些问题。</p>
<div class="highlight"><pre><code class="language-html" data-lang="html">// 第一次渲染
<span class="nt">&lt;Card&gt;</span>
<span class="nt">&lt;p&gt;</span>Paragraph 1<span class="nt">&lt;/p&gt;</span>
<span class="nt">&lt;p&gt;</span>Paragraph 2<span class="nt">&lt;/p&gt;</span>
<span class="nt">&lt;/Card&gt;</span>
// 第二次渲染
<span class="nt">&lt;Card&gt;</span>
<span class="nt">&lt;p</span> <span class="na">style=</span><span class="s">{{display:</span> <span class="err">&#39;</span><span class="na">none</span><span class="err">&#39;}}</span><span class="nt">&gt;</span>Paragraph 1<span class="nt">&lt;/p&gt;</span>
<span class="nt">&lt;p&gt;</span>Paragraph 2<span class="nt">&lt;/p&gt;</span>
<span class="nt">&lt;/Card&gt;</span>
</code></pre></div><h3><a class="anchor" name=""></a>动态子级 <a class="hash-link" href="#">#</a></h3>
<p>如果子组件位置会改变(如在搜索结果中)或者有新组件添加到列表开头(如在流中)情况会变得更加复杂。如果子级要在多个渲染阶段保持自己的特征和状态,在这种情况下,你可以通过给子级设置惟一标识的 <code>key</code> 来区分。</p>
<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"> <span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">results</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">results</span><span class="p">;</span>
<span class="k">return</span> <span class="p">(</span>
<span class="o">&lt;</span><span class="nx">ol</span><span class="o">&gt;</span>
<span class="p">{</span><span class="nx">results</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">result</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="nx">key</span><span class="o">=</span><span class="p">{</span><span class="nx">result</span><span class="p">.</span><span class="nx">id</span><span class="p">}</span><span class="o">&gt;</span><span class="p">{</span><span class="nx">result</span><span class="p">.</span><span class="nx">text</span><span class="p">}</span><span class="o">&lt;</span><span class="err">/li&gt;;</span>
<span class="p">})}</span>
<span class="o">&lt;</span><span class="err">/ol&gt;</span>
<span class="p">);</span>
<span class="p">}</span>
</code></pre></div>
<p>当 React 校正带有 key 的子级时,它会确保它们被重新排序(而不是破坏)或者删除(而不是重用)。
<code>务必</code><code>key</code> 添加到子级数组里组件本身上,而不是每个子级内部最外层 HTML 上:</p>
<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// 错误!</span>
<span class="kd">var</span> <span class="nx">ListItemWrapper</span> <span class="o">=</span> <span class="nx">React</span><span class="p">.</span><span class="nx">createClass</span><span class="p">({</span>
<span class="nx">render</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="o">&lt;</span><span class="nx">li</span> <span class="nx">key</span><span class="o">=</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">data</span><span class="p">.</span><span class="nx">id</span><span class="p">}</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">data</span><span class="p">.</span><span class="nx">text</span><span class="p">}</span><span class="o">&lt;</span><span class="err">/li&gt;;</span>
<span class="p">}</span>
<span class="p">});</span>
<span class="kd">var</span> <span class="nx">MyComponent</span> <span class="o">=</span> <span class="nx">React</span><span class="p">.</span><span class="nx">createClass</span><span class="p">({</span>
<span class="nx">render</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="o">&lt;</span><span class="nx">ul</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">results</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">result</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="o">&lt;</span><span class="nx">ListItemWrapper</span> <span class="nx">data</span><span class="o">=</span><span class="p">{</span><span class="nx">result</span><span class="p">}</span><span class="o">/&gt;</span><span class="p">;</span>
<span class="p">})}</span>
<span class="o">&lt;</span><span class="err">/ul&gt;</span>
<span class="p">);</span>
<span class="p">}</span>
<span class="p">});</span>
</code></pre></div><div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// 正确 :)</span>
<span class="kd">var</span> <span class="nx">ListItemWrapper</span> <span class="o">=</span> <span class="nx">React</span><span class="p">.</span><span class="nx">createClass</span><span class="p">({</span>
<span class="nx">render</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="o">&lt;</span><span class="nx">li</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">data</span><span class="p">.</span><span class="nx">text</span><span class="p">}</span><span class="o">&lt;</span><span class="err">/li&gt;;</span>
<span class="p">}</span>
<span class="p">});</span>
<span class="kd">var</span> <span class="nx">MyComponent</span> <span class="o">=</span> <span class="nx">React</span><span class="p">.</span><span class="nx">createClass</span><span class="p">({</span>
<span class="nx">render</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="o">&lt;</span><span class="nx">ul</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">results</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">result</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="o">&lt;</span><span class="nx">ListItemWrapper</span> <span class="nx">key</span><span class="o">=</span><span class="p">{</span><span class="nx">result</span><span class="p">.</span><span class="nx">id</span><span class="p">}</span> <span class="nx">data</span><span class="o">=</span><span class="p">{</span><span class="nx">result</span><span class="p">}</span><span class="o">/&gt;</span><span class="p">;</span>
<span class="p">})}</span>
<span class="o">&lt;</span><span class="err">/ul&gt;</span>
<span class="p">);</span>
<span class="p">}</span>
<span class="p">});</span>
</code></pre></div>
<p>也可以传递ReactFragment 对象 来做有 key 的子级。详见<a href="create-fragment.html">Keyed Fragments</a></p>
<h2><a class="anchor" name=""></a>数据流 <a class="hash-link" href="#">#</a></h2>
<p>React 里,数据通过上面介绍过的 <code>props</code> 从拥有者流向归属者。这就是高效的单向数据绑定(one-way data binding):拥有者通过它的 <code>props</code><code>state</code> 计算出一些值,并把这些值绑定到它们拥有的组件的 props 上。因为这个过程会递归地调用,所以数据变化会自动在所有被使用的地方自动反映出来。</p>
<h2><a class="anchor" name=""></a>性能提醒 <a class="hash-link" href="#">#</a></h2>
<p>你或许会担心如果一个拥有者有大量子级时,对于数据变化做出响应非常耗费性能。值得庆幸的是执行 JavaScript 非常的快,而且 <code>render()</code> 方法一般比较简单,所以在大部分应用里这样做速度极快。此外,性能的瓶颈大多是因为 DOM 更新,而非 JS 执行,而且 React 会通过批量更新和变化检测来优化性能。</p>
<p>但是,有时候需要做细粒度的性能控制。这种情况下,可以重写 <code>shouldComponentUpdate()</code> 方法返回 false 来让 React 跳过对子树的处理。参考 <a href="/react/docs/component-specs.html">React reference docs</a> 了解更多。</p>
<blockquote>
<p>注意:</p>
<p>如果在数据变化时让 <code>shouldComponentUpdate()</code> 返回 false,React 就不能保证用户界面同步。当使用它的时候一定确保你清楚到底做了什么,并且只在遇到明显性能问题的时候才使用它。不要低估 JavaScript 的速度,DOM 操作通常才是慢的原因。</p>
</blockquote>
<div class="docs-prevnext">
<a class="docs-prev" href="/react/docs/interactivity-and-dynamic-uis-zh-CN.html">&larr; Prev</a>
<a class="docs-next" href="/react/docs/reusable-components-zh-CN.html">Next &rarr;</a>
</div>
</div>
</section>
<footer class="wrap">
<div class="left">
A Facebook &amp; Instagram collaboration.<br>
<a href="/react/acknowledgements.html">Acknowledgements</a>
</div>
<div class="right">
&copy; 2013&ndash;2016 Facebook Inc.<br>
Documentation licensed under <a href="https://creativecommons.org/licenses/by/4.0/">CC BY 4.0</a>.
</div>
</footer>
</div>
<div id="fb-root"></div>
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
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/all.js#xfbml=1&appId=623268441017527";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
docsearch({
apiKey: '36221914cce388c46d0420343e0bb32e',
indexName: 'react',
inputSelector: '#algolia-doc-search'
});
</script>
</body>
</html>