Files
react/docs/create-fragment-zh-CN.html
T
2016-03-21 11:28:34 -07:00

530 lines
22 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>Keyed Fragments | React</title>
<meta name="viewport" content="width=device-width">
<meta property="og:title" content="Keyed Fragments | React">
<meta property="og:type" content="website">
<meta property="og:url" content="https://facebook.github.io/react/docs/create-fragment-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>
Keyed Fragments
<a class="edit-page-link" href="https://github.com/facebook/react/tree/master/docs/docs/10.6-create-fragment.zh-CN.md" target="_blank">Edit on GitHub</a>
</h1>
<div class="subHeader"></div>
<p>在大多数情况下,你可以使用 <code>key</code> prop 指定你从 <code>render</code> 返回的元素的 keys。然而,这在一个情况下会失败:如果你有两组你需要记录的子级,将没有办法在不使用包裹元素的情况下放置一个 key 到每组上。</p>
<p>即是,如果你有一个像这样的组件:</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="kd">var</span> <span class="nx">Swapper</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">propTypes</span><span class="o">:</span> <span class="p">{</span>
<span class="c1">// `leftChildren` and `rightChildren` can be a string, element, array, etc.</span>
<span class="nx">leftChildren</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">node</span><span class="p">,</span>
<span class="nx">rightChildren</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">node</span><span class="p">,</span>
<span class="nx">swapped</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">bool</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="kd">var</span> <span class="nx">children</span><span class="p">;</span>
<span class="k">if</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">swapped</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">children</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">rightChildren</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">leftChildren</span><span class="p">];</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="nx">children</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">leftChildren</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">rightChildren</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="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>这些子级会在当你改变 <code>swapped</code> prop 时加载和卸载,因为没有任何的 key 标记在这两组子级上。</p>
<p>要解决这个问题,你可以使用 <code>createFragment</code> 插件来给予这两组子级 keys.</p>
<h4><a class="anchor" name="arrayltreactnodegt-createfragmentobject-children"></a><code>Array&lt;ReactNode&gt; createFragment(object children)</code> <a class="hash-link" href="#arrayltreactnodegt-createfragmentobject-children">#</a></h4>
<p>代替创建数组,我们这样写:</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="kd">var</span> <span class="nx">createFragment</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;react-addons-create-fragment&#39;</span><span class="p">);</span>
<span class="k">if</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">swapped</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">children</span> <span class="o">=</span> <span class="nx">createFragment</span><span class="p">({</span>
<span class="nx">right</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">rightChildren</span><span class="p">,</span>
<span class="nx">left</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">leftChildren</span>
<span class="p">});</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="nx">children</span> <span class="o">=</span> <span class="nx">createFragment</span><span class="p">({</span>
<span class="nx">left</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">leftChildren</span><span class="p">,</span>
<span class="nx">right</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">rightChildren</span>
<span class="p">});</span>
<span class="p">}</span>
</code></pre></div>
<p>被传入对象的 keys (即 <code>left</code><code>right</code>)被用作为整组子级的 keys,并且对象 keys 的顺序被用于决定渲染子级的顺序。通过这个改变,这两个子级将会恰当的在 DOM 里排序,而不被卸载。</p>
<p><code>createFragment</code> 的返回值应该被对待为一个不透明的对象;你可以使用 <code>React.Children</code> 来遍历一个 fragment 但是不应该直接访问它。同样注意,我们依赖于 JavaScript 引擎保留了对象的枚举顺序,这点在 spec 上是不保证的,但是所有主要的浏览器和 VMs 都对非数字键的对象实现了这个特性。</p>
<blockquote>
<p><strong>注意:</strong></p>
<p>将来,<code>createFragment</code> 也许会被替换为如下的API</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><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">x</span><span class="o">:</span><span class="nx">frag</span> <span class="nx">key</span><span class="o">=</span><span class="s2">&quot;right&quot;</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">rightChildren</span><span class="p">}</span><span class="o">&lt;</span><span class="err">/x:frag&gt;,</span>
<span class="o">&lt;</span><span class="nx">x</span><span class="o">:</span><span class="nx">frag</span> <span class="nx">key</span><span class="o">=</span><span class="s2">&quot;left&quot;</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">leftChildren</span><span class="p">}</span><span class="o">&lt;</span><span class="err">/x:frag&gt;</span>
<span class="o">&lt;</span><span class="err">/div&gt;</span>
<span class="p">);</span>
</code></pre></div>
<p>允许你直接在 JSX 里赋值 keys 而不用添加包裹元素。 </p>
</blockquote>
<div class="docs-prevnext">
<a class="docs-prev" href="/react/docs/clone-with-props-zh-CN.html">&larr; Prev</a>
<a class="docs-next" href="/react/docs/update-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>