mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
578 lines
31 KiB
HTML
578 lines
31 KiB
HTML
<!DOCTYPE html>
|
|
<!--[if IE]><![endif]-->
|
|
<html>
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
|
<title>React | Reusable Components</title>
|
|
<meta name="viewport" content="width=device-width">
|
|
<meta property="og:title" content="React | Reusable Components" />
|
|
<meta property="og:type" content="website" />
|
|
<meta property="og:url" content="http://facebook.github.io/react/docs/reusable-components.html" />
|
|
<meta property="og:image" content="http://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="http://facebook.github.io/react/feed.xml">
|
|
|
|
<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 type="text/javascript" src="//use.typekit.net/vqa1hcx.js"></script>
|
|
<script type="text/javascript">try{Typekit.load();}catch(e){}</script>
|
|
|
|
<!--[if lte IE 8]>
|
|
<script type="text/javascript" src="/react/js/html5shiv.min.js"></script>
|
|
<script type="text/javascript" src="/react/js/es5-shim.min.js"></script>
|
|
<script type="text/javascript" src="/react/js/es5-sham.min.js"></script>
|
|
<![endif]-->
|
|
<script type="text/javascript" src="/react/js/codemirror.js"></script>
|
|
<script type="text/javascript" src="/react/js/javascript.js"></script>
|
|
<script type="text/javascript" src="/react/js/react.min.js"></script>
|
|
<script type="text/javascript" src="/react/js/JSXTransformer.js"></script>
|
|
<script type="text/javascript" src="/react/js/live_editor.js"></script>
|
|
<script type="text/javascript" src="/react/js/showdown.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" alt="" src="/react/img/logo_small.png" width="38" height="38">
|
|
React
|
|
</a>
|
|
<ul class="nav-site">
|
|
<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><a href="http://github.com/facebook/react">github</a>
|
|
</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/videos.html">
|
|
Videos
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/react/docs/complementary-tools.html">
|
|
Complementary Tools
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/react/docs/example-apps.html">
|
|
Example Apps
|
|
</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-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" class="active">
|
|
Reusable Components
|
|
</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">
|
|
More About Refs
|
|
</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/class-name-manipulation.html">
|
|
Class Name Manipulation
|
|
</a>
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/react/docs/test-utils.html">
|
|
Test Utilities
|
|
</a>
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/react/docs/clone-with-props.html">
|
|
Cloning Components
|
|
</a>
|
|
</li>
|
|
|
|
</ul>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/react/docs/examples.html">
|
|
Examples
|
|
</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>
|
|
|
|
</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>
|
|
|
|
</ul>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
<div class="inner-content">
|
|
<h1>Reusable Components</h1>
|
|
<div class="subHeader"></div>
|
|
<p>When designing interfaces, break down the common design elements (buttons, form fields, layout components, etc) into reusable components with well-defined interfaces. That way, the next time you need to build some UI you can write much less code, which means faster development time, less bugs, and less bytes down the wire.</p>
|
|
<h2><a class="anchor" name="prop-validation"></a>Prop Validation <a class="hash-link" href="#prop-validation">#</a></h2>
|
|
<p>As your app grows it's helpful to ensure that your components are used correctly. We do this by allowing you to specify <code>propTypes</code>. <code>React.PropTypes</code> exports a range of validators that can be used to make sure the data you receive is valid. When an invalid value is provided for a prop, a warning will be shown in the JavaScript console. Note that for performance reasons <code>propTypes</code> is only checked in development mode. Here is an example documenting the different validators provided:</p>
|
|
<div class="highlight"><pre><code class="javascript language-javascript" data-lang="javascript"><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">// You can declare that a prop is a specific JS primitive. By default, these</span>
|
|
<span class="c1">// are all optional.</span>
|
|
<span class="nx">optionalArray</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">array</span><span class="p">,</span>
|
|
<span class="nx">optionalBool</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">optionalFunc</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">func</span><span class="p">,</span>
|
|
<span class="nx">optionalNumber</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">number</span><span class="p">,</span>
|
|
<span class="nx">optionalObject</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">object</span><span class="p">,</span>
|
|
<span class="nx">optionalString</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="c1">// Anything that can be rendered: numbers, strings, components or an array</span>
|
|
<span class="c1">// containing these types.</span>
|
|
<span class="nx">optionalRenderable</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">renderable</span><span class="p">,</span>
|
|
|
|
<span class="c1">// A React component.</span>
|
|
<span class="nx">optionalComponent</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">component</span><span class="p">,</span>
|
|
|
|
<span class="c1">// You can ensure that your prop is limited to specific values by treating</span>
|
|
<span class="c1">// it as an enum.</span>
|
|
<span class="nx">optionalEnum</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">oneOf</span><span class="p">([</span><span class="s1">'News'</span><span class="p">,</span> <span class="s1">'Photos'</span><span class="p">]),</span>
|
|
|
|
<span class="c1">// An object that could be one of many types</span>
|
|
<span class="nx">optionalUnion</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">oneOfType</span><span class="p">([</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">React</span><span class="p">.</span><span class="nx">PropTypes</span><span class="p">.</span><span class="nx">number</span>
|
|
<span class="p">]),</span>
|
|
|
|
<span class="c1">// An array of a certain type</span>
|
|
<span class="nx">optionalArrayOf</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">arrayOf</span><span class="p">(</span><span class="nx">React</span><span class="p">.</span><span class="nx">PropTypes</span><span class="p">.</span><span class="nx">number</span><span class="p">),</span>
|
|
|
|
<span class="c1">// An object taking on a particular shape</span>
|
|
<span class="nx">optionalObjectWithShape</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">shape</span><span class="p">({</span>
|
|
<span class="nx">color</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">fontSize</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">number</span>
|
|
<span class="p">}),</span>
|
|
|
|
<span class="c1">// You can also declare that a prop is an instance of a class. This uses</span>
|
|
<span class="c1">// JS's instanceof operator.</span>
|
|
<span class="nx">someClass</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">instanceOf</span><span class="p">(</span><span class="nx">SomeClass</span><span class="p">),</span>
|
|
|
|
<span class="c1">// You can chain any of the above with isRequired to make sure a warning is</span>
|
|
<span class="c1">// shown if the prop isn't provided.</span>
|
|
<span class="nx">requiredFunc</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">func</span><span class="p">.</span><span class="nx">isRequired</span><span class="p">,</span>
|
|
|
|
<span class="c1">// An object of any kind</span>
|
|
<span class="nx">requiredAny</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">any</span><span class="p">.</span><span class="nx">isRequired</span><span class="p">,</span>
|
|
|
|
<span class="c1">// You can also specify a custom validator.</span>
|
|
<span class="nx">customProp</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">props</span><span class="p">,</span> <span class="nx">propName</span><span class="p">,</span> <span class="nx">componentName</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="sr">/matchme/</span><span class="p">.</span><span class="nx">test</span><span class="p">(</span><span class="nx">props</span><span class="p">[</span><span class="nx">propName</span><span class="p">]))</span> <span class="p">{</span>
|
|
<span class="nx">console</span><span class="p">.</span><span class="nx">warn</span><span class="p">(</span><span class="s1">'Validation failed!'</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span>
|
|
<span class="p">},</span>
|
|
<span class="cm">/* ... */</span>
|
|
<span class="p">});</span>
|
|
</code></pre></div><h2><a class="anchor" name="default-prop-values"></a>Default Prop Values <a class="hash-link" href="#default-prop-values">#</a></h2>
|
|
<p>React lets you define default values for your <code>props</code> in a very declarative way:</p>
|
|
<div class="highlight"><pre><code class="javascript language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">ComponentWithDefaultProps</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">getDefaultProps</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">value</span><span class="o">:</span> <span class="s1">'default value'</span>
|
|
<span class="p">};</span>
|
|
<span class="p">}</span>
|
|
<span class="cm">/* ... */</span>
|
|
<span class="p">});</span>
|
|
</code></pre></div>
|
|
<p>The result of <code>getDefaultProps()</code> will be cached and used to ensure that <code>this.props.value</code> will have a value if it was not specified by the parent component. This allows you to safely just use your props without having to write repetitive and fragile code to handle that yourself.</p>
|
|
<h2><a class="anchor" name="transferring-props-a-shortcut"></a>Transferring Props: A Shortcut <a class="hash-link" href="#transferring-props-a-shortcut">#</a></h2>
|
|
<p>A common type of React component is one that extends a basic HTML in a simple way. Often you'll want to copy any HTML attributes passed to your component to the underlying HTML element to save typing. React provides <code>transferPropsTo()</code> to do just this.</p>
|
|
<div class="highlight"><pre><code class="javascript language-javascript" data-lang="javascript"><span class="cm">/** @jsx React.DOM */</span>
|
|
|
|
<span class="kd">var</span> <span class="nx">CheckLink</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="c1">// transferPropsTo() will take any props passed to CheckLink</span>
|
|
<span class="c1">// and copy them to <a></span>
|
|
<span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">transferPropsTo</span><span class="p">(</span><span class="o"><</span><span class="nx">a</span><span class="o">></span><span class="p">{</span><span class="s1">'√ '</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">children</span><span class="p">}</span><span class="o"><</span><span class="err">/a>);</span>
|
|
<span class="p">}</span>
|
|
<span class="p">});</span>
|
|
|
|
<span class="nx">React</span><span class="p">.</span><span class="nx">renderComponent</span><span class="p">(</span>
|
|
<span class="o"><</span><span class="nx">CheckLink</span> <span class="nx">href</span><span class="o">=</span><span class="s2">"javascript:alert('Hello, world!');"</span><span class="o">></span>
|
|
<span class="nx">Click</span> <span class="nx">here</span><span class="o">!</span>
|
|
<span class="o"><</span><span class="err">/CheckLink>,</span>
|
|
<span class="nb">document</span><span class="p">.</span><span class="nx">getElementById</span><span class="p">(</span><span class="s1">'example'</span><span class="p">)</span>
|
|
<span class="p">);</span>
|
|
</code></pre></div><h2><a class="anchor" name="single-child"></a>Single Child <a class="hash-link" href="#single-child">#</a></h2>
|
|
<p>With <code>React.PropTypes.component</code> you can specify that only a single child can be passed to
|
|
a component as children.</p>
|
|
<div class="highlight"><pre><code class="javascript language-javascript" data-lang="javascript"><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">propTypes</span><span class="o">:</span> <span class="p">{</span>
|
|
<span class="nx">children</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">component</span><span class="p">.</span><span class="nx">isRequired</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"><</span><span class="nx">div</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">children</span><span class="p">}</span> <span class="c1">// This must be exactly one element or it will throw.</span>
|
|
<span class="o"><</span><span class="err">/div>;</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="p">});</span>
|
|
</code></pre></div><h2><a class="anchor" name="mixins"></a>Mixins <a class="hash-link" href="#mixins">#</a></h2>
|
|
<p>Components are the best way to reuse code in React, but sometimes very different components may share some common functionality. These are sometimes called <a href="http://en.wikipedia.org/wiki/Cross-cutting_concern">cross-cutting concerns</a>. React provides <code>mixins</code> to solve this problem.</p>
|
|
|
|
<p>One common use case is a component wanting to update itself on a time interval. It's easy to use <code>setInterval()</code>, but it's important to cancel your interval when you don't need it anymore to save memory. React provides <a href="/react/docs/working-with-the-browser.html#component-lifecycle">lifecycle methods</a> that let you know when a component is about to be created or destroyed. Let's create a simple mixin that uses these methods to provide an easy <code>setInterval()</code> function that will automatically get cleaned up when your component is destroyed.</p>
|
|
<div class="highlight"><pre><code class="javascript language-javascript" data-lang="javascript"><span class="cm">/** @jsx React.DOM */</span>
|
|
|
|
<span class="kd">var</span> <span class="nx">SetIntervalMixin</span> <span class="o">=</span> <span class="p">{</span>
|
|
<span class="nx">componentWillMount</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="k">this</span><span class="p">.</span><span class="nx">intervals</span> <span class="o">=</span> <span class="p">[];</span>
|
|
<span class="p">},</span>
|
|
<span class="nx">setInterval</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="k">this</span><span class="p">.</span><span class="nx">intervals</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">setInterval</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="kc">null</span><span class="p">,</span> <span class="nx">arguments</span><span class="p">));</span>
|
|
<span class="p">},</span>
|
|
<span class="nx">componentWillUnmount</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="k">this</span><span class="p">.</span><span class="nx">intervals</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="nx">clearInterval</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="p">};</span>
|
|
|
|
<span class="kd">var</span> <span class="nx">TickTock</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">mixins</span><span class="o">:</span> <span class="p">[</span><span class="nx">SetIntervalMixin</span><span class="p">],</span> <span class="c1">// Use the mixin</span>
|
|
<span class="nx">getInitialState</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">seconds</span><span class="o">:</span> <span class="mi">0</span><span class="p">};</span>
|
|
<span class="p">},</span>
|
|
<span class="nx">componentDidMount</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="k">this</span><span class="p">.</span><span class="nx">setInterval</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">tick</span><span class="p">,</span> <span class="mi">1000</span><span class="p">);</span> <span class="c1">// Call a method on the mixin</span>
|
|
<span class="p">},</span>
|
|
<span class="nx">tick</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="k">this</span><span class="p">.</span><span class="nx">setState</span><span class="p">({</span><span class="nx">seconds</span><span class="o">:</span> <span class="k">this</span><span class="p">.</span><span class="nx">state</span><span class="p">.</span><span class="nx">seconds</span> <span class="o">+</span> <span class="mi">1</span><span class="p">});</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"><</span><span class="nx">p</span><span class="o">></span>
|
|
<span class="nx">React</span> <span class="nx">has</span> <span class="nx">been</span> <span class="nx">running</span> <span class="k">for</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">seconds</span><span class="p">}</span> <span class="nx">seconds</span><span class="p">.</span>
|
|
<span class="o"><</span><span class="err">/p></span>
|
|
<span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="p">});</span>
|
|
|
|
<span class="nx">React</span><span class="p">.</span><span class="nx">renderComponent</span><span class="p">(</span>
|
|
<span class="o"><</span><span class="nx">TickTock</span> <span class="o">/></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">'example'</span><span class="p">)</span>
|
|
<span class="p">);</span>
|
|
</code></pre></div>
|
|
<p>A nice feature of mixins is that if a component is using multiple mixins and several mixins define the same lifecycle method (i.e. several mixins want to do some cleanup when the component is destroyed), all of the lifecycle methods are guaranteed to be called.</p>
|
|
|
|
|
|
<div class="docs-prevnext">
|
|
|
|
<a class="docs-prev" href="/react/docs/multiple-components.html">← Prev</a>
|
|
|
|
|
|
<a class="docs-next" href="/react/docs/forms.html">Next →</a>
|
|
|
|
</div>
|
|
|
|
<div class="fb-comments" data-width="650" data-num-posts="10" data-href="http://facebook.github.io/react/docs/reusable-components.html"></div>
|
|
</div>
|
|
</section>
|
|
|
|
|
|
<footer class="wrap">
|
|
<div class="left">
|
|
A Facebook & Instagram collaboration.<br>
|
|
<a href="/react/acknowledgements.html">Acknowledgements</a>
|
|
</div>
|
|
<div class="right">© 2014 Facebook Inc.</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'));
|
|
</script>
|
|
</body>
|
|
</html>
|