Initial implementation
This commit is contained in:
parent
f533a52407
commit
d0142fb682
|
@ -9,7 +9,7 @@ exclude:
|
||||||
- _deprecated
|
- _deprecated
|
||||||
|
|
||||||
# Markdown
|
# Markdown
|
||||||
highlighter: rouge
|
highlighter: false
|
||||||
markdown: kramdown
|
markdown: kramdown
|
||||||
kramdown:
|
kramdown:
|
||||||
input: GFM
|
input: GFM
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,19 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html lang='en' class='no-js {{ page.html_class }}'>
|
||||||
|
<head>
|
||||||
|
{% include meta.html %}
|
||||||
|
{% include polyfills.html %}
|
||||||
|
|
||||||
|
<!-- 3rd-party libs -->
|
||||||
|
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
|
||||||
|
<script src="https://unpkg.com/isotope-layout@3/dist/isotope.pkgd.min.js"></script>
|
||||||
|
<script src="https://unpkg.com/prismjs@1.6.0"></script>
|
||||||
|
<script src="https://unpkg.com/prismjs@1.6.0/components/prism-jsx.min.js"></script>
|
||||||
|
<link rel='stylesheet' href='https://unpkg.com/prismjs@1.6.0/themes/prism-solarizedlight.css' />
|
||||||
|
|
||||||
|
<!-- 2017 layout -->
|
||||||
|
<link href='{{base}}/assets/2017/style.css?t={{ timestamp }}' rel='stylesheet' />
|
||||||
|
<script src='{{base}}/assets/2017/script.js?t={{ timestamp }}'></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class='all'>
|
|
@ -0,0 +1,9 @@
|
||||||
|
---
|
||||||
|
type: article
|
||||||
|
---
|
||||||
|
{% include 2017/head.html %}
|
||||||
|
<h1 class='main-heading'>{{ page.title }}</h1>
|
||||||
|
<div class='post-content MarkdownBody' data-js-main-body>
|
||||||
|
{{ content }}
|
||||||
|
</div>
|
||||||
|
{% include 2017/foot.html %}
|
|
@ -0,0 +1,80 @@
|
||||||
|
$(function () {
|
||||||
|
const $root = $('[data-js-main-body]')
|
||||||
|
wrapify($root)
|
||||||
|
})
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Isotope
|
||||||
|
*/
|
||||||
|
|
||||||
|
$(function () {
|
||||||
|
$('[data-js-h3-section-list]').each(function () {
|
||||||
|
var iso = new Isotope(this, {
|
||||||
|
itemSelector: '.h3-section',
|
||||||
|
transitionDuration: 0
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wraps h2 sections into h2-section.
|
||||||
|
* Wraps h3 sections into h3-section.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function wrapify ($root) {
|
||||||
|
const $h2sections = groupify($root, {
|
||||||
|
tag: 'h2',
|
||||||
|
wrapper: '<div class="h2-section">',
|
||||||
|
body: '<div class="body h3-section-list" data-js-h3-section-list>'
|
||||||
|
})
|
||||||
|
|
||||||
|
$h2sections.each(function () {
|
||||||
|
const $body = $(this).children('[data-js-h3-section-list]')
|
||||||
|
|
||||||
|
groupify($body, {
|
||||||
|
tag: 'h3',
|
||||||
|
wrapper: '<div class="h3-section">',
|
||||||
|
body: '<div class="body">'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Groups stuff
|
||||||
|
*/
|
||||||
|
|
||||||
|
function groupify ($this, { tag, wrapper, body }) {
|
||||||
|
const $first = $this.children(':first-child')
|
||||||
|
let $result = $()
|
||||||
|
|
||||||
|
// Handle the markup before the first h2
|
||||||
|
if (!$first.is(tag)) {
|
||||||
|
const $sibs = $first.nextUntil(tag)
|
||||||
|
$result = $result.add(wrap($first, null, $first.add($sibs)))
|
||||||
|
}
|
||||||
|
|
||||||
|
$this.children(tag).each(function () {
|
||||||
|
const $sibs = $(this).nextUntil(tag)
|
||||||
|
const $heading = $(this)
|
||||||
|
$result = $result.add(wrap($heading, $heading, $sibs))
|
||||||
|
})
|
||||||
|
|
||||||
|
return $result
|
||||||
|
|
||||||
|
function wrap ($pivot, $first, $sibs) {
|
||||||
|
const $wrap = $(wrapper)
|
||||||
|
$wrap.addClass($pivot.attr('class'))
|
||||||
|
console.log($pivot[0])
|
||||||
|
console.log('addclass', $pivot.attr('class'))
|
||||||
|
$pivot.before($wrap)
|
||||||
|
|
||||||
|
const $body = $(body)
|
||||||
|
$body.addClass($pivot.attr('class'))
|
||||||
|
$body.append($sibs)
|
||||||
|
|
||||||
|
if ($first) $wrap.append($first)
|
||||||
|
$wrap.append($body)
|
||||||
|
|
||||||
|
return $wrap
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,248 @@
|
||||||
|
@import url('https://unpkg.com/sanitize.css@5.0.0/sanitize.css');
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--gutter: 32px;
|
||||||
|
--column: 400px;
|
||||||
|
|
||||||
|
--body-font: roboto, sans-serif;
|
||||||
|
--monospace-font: menlo, monospace;
|
||||||
|
|
||||||
|
--gray-bg: #fcfcfc;
|
||||||
|
--gray-text: #678;
|
||||||
|
--text-color: #333;
|
||||||
|
--baseA-400: #53a;
|
||||||
|
--line-color: #f5f5f5;
|
||||||
|
--dark-line-color: #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Base
|
||||||
|
*/
|
||||||
|
|
||||||
|
html, body {
|
||||||
|
background: #fcfcfc;
|
||||||
|
font-family: var(--body-font);
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.6;
|
||||||
|
color: var(--text-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
padding: 16px;
|
||||||
|
max-width: calc(var(--column) * 3 + 32px);
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre, code {
|
||||||
|
font-family: var(--monospace-font);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MarkdownBody context
|
||||||
|
*/
|
||||||
|
|
||||||
|
.main-heading,
|
||||||
|
.MarkdownBody h1,
|
||||||
|
.MarkdownBody h2 {
|
||||||
|
font-weight: 300;
|
||||||
|
font-family: var(--body-font);
|
||||||
|
margin: calc(var(--gutter) / 2);
|
||||||
|
padding: 0;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
padding-bottom: 16px;
|
||||||
|
border-bottom: solid 1px var(--line-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-heading,
|
||||||
|
.MarkdownBody h1 {
|
||||||
|
font-size: 3.2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.MarkdownBody h2 {
|
||||||
|
font-size: 2.4em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.MarkdownBody h3 {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
font-family: var(--body-font);
|
||||||
|
font-size: 1.66em;
|
||||||
|
font-weight: 300;
|
||||||
|
color: var(--baseA-400);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* h2 section
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Hide the first h2 heading */
|
||||||
|
.h2-section > h2 {
|
||||||
|
margin-top: 64px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.h2-section:first-child > h2 {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* H3 section list:
|
||||||
|
* The body that is isotoped.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.h3-section-list {
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.h3-section-list::after {
|
||||||
|
content: '';
|
||||||
|
display: table;
|
||||||
|
clear: both;
|
||||||
|
zoom: 1;
|
||||||
|
}
|
||||||
|
.h3-section-list > .h3-section {
|
||||||
|
float: left;
|
||||||
|
padding: calc(var(--gutter) / 2);
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.h3-section-list > .h3-section {
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.h3-section-list > .h3-section.-wide {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.h3-section-list > .h3-section.-halfwide {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 960px) {
|
||||||
|
.h3-section-list > .h3-section {
|
||||||
|
width: 33.33%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.h3-section-list > .h3-section.-wide {
|
||||||
|
width: 66.67%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.h3-section-list > .h3-section.-halfwide {
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* H3 section
|
||||||
|
*/
|
||||||
|
|
||||||
|
.h3-section > .body > pre {
|
||||||
|
margin: 0;
|
||||||
|
padding: 16px;
|
||||||
|
font-size: 12px;
|
||||||
|
overflow: auto;
|
||||||
|
background: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.h3-section > .body {
|
||||||
|
background: white;
|
||||||
|
box-shadow: 0 4px 5px rgba(80, 100, 150, 0.05), 0 2px 3px rgba(80, 100, 150, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.h3-section > .body > ul {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
list-style-type: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.h3-section > .body > ul > li {
|
||||||
|
padding: 8px 16px;
|
||||||
|
padding-left: 32px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.h3-section > .body > ul > li::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
display: inline-block;
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
background: #666;
|
||||||
|
border-radius: 50%;
|
||||||
|
left: 16px;
|
||||||
|
top: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.h3-section > .body > ul > li + li {
|
||||||
|
border-top: solid 1px var(--line-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Description paragraphs */
|
||||||
|
.h3-section > .body > pre ~ p,
|
||||||
|
.h3-section > .body > ul ~ p,
|
||||||
|
.h3-section > .body > table ~ p {
|
||||||
|
padding: 16px;
|
||||||
|
margin: 0;
|
||||||
|
background: var(--gray-bg);
|
||||||
|
color: var(--gray-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.h3-section > .body > p > a,
|
||||||
|
.h3-section > .body > p > a:visited {
|
||||||
|
color: var(--text-color);
|
||||||
|
text-decoration: none;
|
||||||
|
border-bottom: solid 1px var(--line-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.h3-section > .body > *:not(:first-child) {
|
||||||
|
border-top: solid 1px var(--line-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Table
|
||||||
|
*/
|
||||||
|
|
||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
table tr + tr {
|
||||||
|
border-top: solid 1px var(--line-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Horizontal lines */
|
||||||
|
table tbody + tbody {
|
||||||
|
border-top: solid 1px var(--dark-line-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
table td,
|
||||||
|
table th {
|
||||||
|
padding: 8px 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table tr td:last-child {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
table code {
|
||||||
|
font-size: 0.86em;
|
||||||
|
color: #35a;
|
||||||
|
}
|
||||||
|
|
||||||
|
table a,
|
||||||
|
table a:visited {
|
||||||
|
color: #35a;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
table code ~ em {
|
||||||
|
font-style: normal;
|
||||||
|
font-size: 0.86em;
|
||||||
|
color: var(--gray-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
table thead {
|
||||||
|
display: none;
|
||||||
|
}
|
445
react.md
445
react.md
|
@ -1,121 +1,82 @@
|
||||||
---
|
---
|
||||||
title: React.js
|
title: React.js
|
||||||
category: React
|
category: React
|
||||||
layout: default-ad
|
layout: 2017/sheet
|
||||||
---
|
---
|
||||||
|
|
||||||
{%raw%}
|
{%raw%}
|
||||||
|
|
||||||
Use the [React.js jsfiddle](http://jsfiddle.net/reactjs/69z2wepo/) to start hacking. (or the unofficial [jsbin](http://jsbin.com/yafixat/edit?js,output))
|
Getting started
|
||||||
{:.brief-intro.center}
|
---------------
|
||||||
|
|
||||||
```js
|
{:.-three-column}
|
||||||
var Component = React.createClass({
|
|
||||||
render: function () {
|
<!-- .-three-column -->
|
||||||
return <div>Hello {this.props.name}</div>;
|
|
||||||
|
### Getting started
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
class MyComponent extends React.Component {
|
||||||
|
render () {
|
||||||
|
return <div className='message-box'>
|
||||||
|
Hello {this.props.name}
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
```js
|
|
||||||
ReactDOM.render(<Component name="John" />, document.body);
|
|
||||||
```
|
|
||||||
{:.light}
|
|
||||||
|
|
||||||
## Nesting
|
|
||||||
Nest components to separate concerns. See [multiple components](http://facebook.github.io/react/docs/multiple-components.html).
|
|
||||||
{:.center}
|
|
||||||
|
|
||||||
```js
|
|
||||||
var UserAvatar = React.createClass({...});
|
|
||||||
var UserProfile = React.createClass({...});
|
|
||||||
```
|
|
||||||
{:.light}
|
|
||||||
|
|
||||||
```js
|
|
||||||
var Info = React.createClass({
|
|
||||||
render() {
|
|
||||||
return <div>
|
|
||||||
<UserAvatar src={this.props.avatar} />
|
|
||||||
<UserProfile username={this.props.username} />
|
|
||||||
</div>;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
## States & Properties
|
|
||||||
Use [props](https://facebook.github.io/react/docs/tutorial.html#using-props) (`this.props`) to access parameters passed from the parent.
|
|
||||||
Use [states](https://facebook.github.io/react/docs/tutorial.html#reactive-state) (`this.state`) to manage dynamic data.
|
|
||||||
{:.center}
|
|
||||||
|
|
||||||
```html
|
|
||||||
<MyComponent fullscreen={true} />
|
|
||||||
```
|
|
||||||
{:.light}
|
|
||||||
|
|
||||||
```js
|
|
||||||
// props
|
|
||||||
this.props.fullscreen //=> true
|
|
||||||
|
|
||||||
// state
|
|
||||||
this.setState({ username: 'rstacruz' });
|
|
||||||
this.replaceState({ ... });
|
|
||||||
this.state.username //=> 'rstacruz'
|
|
||||||
```
|
|
||||||
|
|
||||||
```js
|
|
||||||
render: function () {
|
|
||||||
return <div className={this.props.fullscreen ? 'full' : ''}>
|
|
||||||
Welcome, {this.state.username}
|
|
||||||
</div>;
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Setting defaults
|
```jsx
|
||||||
Pre-populates `this.state.comments` and `this.props.name`.
|
const el = document.body
|
||||||
|
ReactDOM.render(<MyComponent name='John' />, el)
|
||||||
```js
|
|
||||||
React.createClass({
|
|
||||||
getInitialState: function () {
|
|
||||||
return { comments: [] };
|
|
||||||
},
|
|
||||||
|
|
||||||
getDefaultProps: function () {
|
|
||||||
return { name: "Hello" };
|
|
||||||
}
|
|
||||||
);
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Component API
|
Use the [React.js jsfiddle](http://jsfiddle.net/reactjs/69z2wepo/) to start hacking. (or the unofficial [jsbin](http://jsbin.com/yafixat/edit?js,output)).
|
||||||
|
|
||||||
|
### Functional components
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
function MyComponent ({ name }) {
|
||||||
|
return <div className='message-box'>
|
||||||
|
Hello {name}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Nesting
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
class Info extends React.Component {
|
||||||
|
render () {
|
||||||
|
const { avatar, username } = this.props
|
||||||
|
|
||||||
|
return <div>
|
||||||
|
<UserAvatar src={avatar} />
|
||||||
|
<UserProfile username={username} />
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Nest components to separate concerns. See: [multiple components](http://facebook.github.io/react/docs/multiple-components.html)
|
||||||
|
|
||||||
|
|
||||||
|
### Component API
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
this.forceUpdate()
|
||||||
|
this.isMounted()
|
||||||
|
|
||||||
|
this.setState({ ... })
|
||||||
|
this.replaceState({ ... })
|
||||||
|
|
||||||
|
this.state
|
||||||
|
this.props
|
||||||
|
```
|
||||||
|
|
||||||
These are methods available for `Component` instances. See [Component API](http://facebook.github.io/react/docs/component-api.html).
|
These are methods available for `Component` instances. See [Component API](http://facebook.github.io/react/docs/component-api.html).
|
||||||
{:.center}
|
|
||||||
|
|
||||||
```js
|
|
||||||
ReactDOM.findDOMNode(c) // 0.14+
|
|
||||||
React.findDOMNode(c) // 0.13
|
|
||||||
c.getDOMNode() // 0.12 below
|
|
||||||
```
|
|
||||||
{:.light}
|
|
||||||
|
|
||||||
```js
|
|
||||||
c.forceUpdate()
|
|
||||||
c.isMounted()
|
|
||||||
|
|
||||||
c.state
|
|
||||||
c.props
|
|
||||||
|
|
||||||
c.setState({ ... })
|
|
||||||
c.replaceState({ ... })
|
|
||||||
|
|
||||||
c.setProps({ ... }) // for deprecation
|
|
||||||
c.replaceProps({ ... }) // for deprecation
|
|
||||||
|
|
||||||
c.refs
|
|
||||||
```
|
|
||||||
|
|
||||||
### Component specs
|
### Component specs
|
||||||
Methods and properties you can override. See [component specs](http://facebook.github.io/react/docs/component-specs.html).
|
|
||||||
|
|
||||||
| Method | What |
|
| Method | What |
|
||||||
| ---- | ---- |
|
| ---- | ---- |
|
||||||
|
@ -130,77 +91,95 @@ Methods and properties you can override. See [component specs](http://facebook.g
|
||||||
| [`displayName: "..."`](http://facebook.github.io/react/docs/component-specs.html#displayname) | Automatically filled by JSX |
|
| [`displayName: "..."`](http://facebook.github.io/react/docs/component-specs.html#displayname) | Automatically filled by JSX |
|
||||||
{:.greycode.no-head}
|
{:.greycode.no-head}
|
||||||
|
|
||||||
## Lifecycle
|
Methods and properties you can override. See [component specs](http://facebook.github.io/react/docs/component-specs.html).
|
||||||
|
|
||||||
|
### States & properties
|
||||||
|
|
||||||
|
```html
|
||||||
|
<MyComponent fullscreen={true} />
|
||||||
|
```
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
// props
|
||||||
|
this.props.fullscreen //=> true
|
||||||
|
|
||||||
|
// state
|
||||||
|
this.setState({ username: 'rstacruz' });
|
||||||
|
this.replaceState({ ... });
|
||||||
|
this.state.username //=> 'rstacruz'
|
||||||
|
```
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
render: function () {
|
||||||
|
return <div className={this.props.fullscreen ? 'full' : ''}>
|
||||||
|
Welcome, {this.state.username}
|
||||||
|
</div>;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Use [props](https://facebook.github.io/react/docs/tutorial.html#using-props) (`this.props`) to access parameters passed from the parent.
|
||||||
|
Use [states](https://facebook.github.io/react/docs/tutorial.html#reactive-state) (`this.state`) to manage dynamic data.
|
||||||
|
|
||||||
|
### Setting defaults
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
React.createClass({
|
||||||
|
getInitialState: function () {
|
||||||
|
return { comments: [] };
|
||||||
|
},
|
||||||
|
|
||||||
|
getDefaultProps: function () {
|
||||||
|
return { name: "Hello" };
|
||||||
|
}
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
Pre-populates `this.state.comments` and `this.props.name`.
|
||||||
|
|
||||||
|
Lifecycle
|
||||||
|
---------
|
||||||
|
|
||||||
|
{:.-two-column}
|
||||||
|
|
||||||
### Mounting
|
### Mounting
|
||||||
Before initial rendering occurs. Add your DOM stuff on didMount (events, timers, etc). See [reference](http://facebook.github.io/react/docs/component-specs.html#mounting-componentwillmount).
|
|
||||||
|
|
||||||
| `componentWillMount()` | Before rendering (no DOM yet) |
|
| `componentWillMount()` | Before rendering (no DOM yet) |
|
||||||
| `componentDidMount()` | After rendering |
|
| `componentDidMount()` | After rendering |
|
||||||
{:.greycode.no-head.lc}
|
| `componentWillUnmount()` | Invoked before DOM removal |
|
||||||
|
|
||||||
<br>
|
Before initial rendering occurs. Add your DOM stuff on didMount (events, timers, etc). See [reference](http://facebook.github.io/react/docs/component-specs.html#mounting-componentwillmount).
|
||||||
|
|
||||||
|
Clear your DOM stuff in componentWillMount (probably done on didMount). See [reference](http://facebook.github.io/react/docs/component-specs.html#unmounting-componentwillunmount).
|
||||||
|
|
||||||
### Updating
|
### Updating
|
||||||
Called when parents change properties and `.setState()`. These are not called for initial renders. See [reference](http://facebook.github.io/react/docs/component-specs.html#updating-componentwillreceiveprops).
|
|
||||||
|
|
||||||
| `componentWillReceiveProps`*(newProps={})* | Use `setState()` here |
|
| `componentWillReceiveProps`*(newProps={})* | Use `setState()` here |
|
||||||
| `shouldComponentUpdate`*(newProps={}, newState={})* | Skips `render()` if returns false |
|
| `shouldComponentUpdate`*(newProps={}, newState={})* | Skips `render()` if returns false |
|
||||||
| `componentWillUpdate`*(newProps={}, newState={})* | Can't use `setState()` here |
|
| `componentWillUpdate`*(newProps={}, newState={})* | Can't use `setState()` here |
|
||||||
| `componentDidUpdate`*(prevProps={}, prevState={})* | Operate on the DOM here |
|
| `componentDidUpdate`*(prevProps={}, prevState={})* | Operate on the DOM here |
|
||||||
{:.greycode.no-head.lc}
|
|
||||||
|
|
||||||
<br>
|
Called when parents change properties and `.setState()`. These are not called for initial renders. See [reference](http://facebook.github.io/react/docs/component-specs.html#updating-componentwillreceiveprops).
|
||||||
|
|
||||||
### Unmounting
|
DOM nodes
|
||||||
Clear your DOM stuff here (probably done on didMount). See [reference](http://facebook.github.io/react/docs/component-specs.html#unmounting-componentwillunmount).
|
---------
|
||||||
|
|
||||||
| `componentWillUnmount()` | Invoked before DOM removal |
|
{:.-two-column}
|
||||||
{:.greycode.no-head.lc}
|
|
||||||
|
|
||||||
<style>
|
|
||||||
table.lc { table-layout: fixed; }
|
|
||||||
table.lc tr>:nth-child(1) { width: 50%; }
|
|
||||||
table.lc tr>:nth-child(2) { text-align: right; }
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<br>
|
|
||||||
|
|
||||||
### Example: loading data
|
|
||||||
See [initial AJAX data](http://facebook.github.io/react/tips/initial-ajax.html).
|
|
||||||
|
|
||||||
```js
|
|
||||||
React.createClass({
|
|
||||||
componentDidMount: function () {
|
|
||||||
$.get(this.props.url, function (data) {
|
|
||||||
this.setState(data);
|
|
||||||
}.bind(this));
|
|
||||||
},
|
|
||||||
|
|
||||||
render: function () {
|
|
||||||
return <CommentList data={this.state.data} />
|
|
||||||
}
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
## DOM nodes
|
|
||||||
|
|
||||||
### References
|
### References
|
||||||
Allows access to DOM nodes. See [References](http://facebook.github.io/react/docs/more-about-refs.html).
|
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<input ref="myInput">
|
<input ref="myInput">
|
||||||
```
|
```
|
||||||
{:.light}
|
|
||||||
|
|
||||||
```js
|
```jsx
|
||||||
this.refs.myInput
|
this.refs.myInput
|
||||||
ReactDOM.findDOMNode(this.refs.myInput).focus()
|
ReactDOM.findDOMNode(this.refs.myInput).focus()
|
||||||
ReactDOM.findDOMNode(this.refs.myInput).value
|
ReactDOM.findDOMNode(this.refs.myInput).value
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Allows access to DOM nodes. See [References](http://facebook.github.io/react/docs/more-about-refs.html).
|
||||||
|
|
||||||
### DOM Events
|
### DOM Events
|
||||||
Add attributes like `onChange`. See [events](https://facebook.github.io/react/docs/events.html).
|
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<input type="text"
|
<input type="text"
|
||||||
|
@ -209,69 +188,86 @@ Add attributes like `onChange`. See [events](https://facebook.github.io/react/do
|
||||||
```
|
```
|
||||||
{:.light}
|
{:.light}
|
||||||
|
|
||||||
```js
|
```jsx
|
||||||
handleChange: function(event) {
|
handleChange: function(event) {
|
||||||
this.setState({ value: event.target.value });
|
this.setState({ value: event.target.value });
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Two-way binding
|
Add attributes like `onChange`. See [events](https://facebook.github.io/react/docs/events.html).
|
||||||
Use [LinkedStateMixin](http://facebook.github.io/react/docs/two-way-binding-helpers.html) for easier two-way binding.
|
|
||||||
|
|
||||||
```html
|
Property validation
|
||||||
Email: <input type="text" valueLink={this.linkState('email')} />
|
-------------------
|
||||||
```
|
|
||||||
{:.light}
|
|
||||||
|
|
||||||
```js
|
### React.PropTypes
|
||||||
React.createClass({
|
|
||||||
mixins: [React.addons.LinkedStateMixin]
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
```js
|
| PropType | Description |
|
||||||
this.state.email
|
| --- | --- |
|
||||||
```
|
| `any` | Anything |
|
||||||
|
| --- | --- |
|
||||||
|
| `string` | |
|
||||||
|
| `number` | |
|
||||||
|
| `func` | Function |
|
||||||
|
| `bool` | True or false |
|
||||||
|
| --- | --- |
|
||||||
|
| `oneOf`_(any)_ | Enum types |
|
||||||
|
| `oneOfType`_(type array)_ | Union |
|
||||||
|
| --- | --- |
|
||||||
|
| `array` | |
|
||||||
|
| `arrayOf`_(...)_ | |
|
||||||
|
| --- | --- |
|
||||||
|
| `object` | |
|
||||||
|
| `objectOf`_(...)_ | |
|
||||||
|
| `instanceOf`_(...)_ | |
|
||||||
|
| `shape`_(...)_ | |
|
||||||
|
| --- | --- |
|
||||||
|
| `element` | React element |
|
||||||
|
| `node` | DOM node |
|
||||||
|
| --- | --- |
|
||||||
|
| `.isRequired` | Required |
|
||||||
|
|
||||||
## Property validation
|
See [propTypes](http://facebook.github.io/react/docs/reusable-components.html#prop-validation).
|
||||||
|
|
||||||
### Basic types
|
### Basic types
|
||||||
Primitive types: `.string`, `.number`, `.func`, and `.bool`. See [propTypes](http://facebook.github.io/react/docs/reusable-components.html#prop-validation).
|
|
||||||
|
|
||||||
```js
|
```jsx
|
||||||
React.createClass({
|
MyComponent.propTypes = {
|
||||||
propTypes: {
|
|
||||||
email: React.PropTypes.string,
|
email: React.PropTypes.string,
|
||||||
seats: React.PropTypes.number,
|
seats: React.PropTypes.number,
|
||||||
settings: React.PropTypes.object,
|
|
||||||
callback: React.PropTypes.func,
|
callback: React.PropTypes.func,
|
||||||
isClosed: React.PropTypes.bool,
|
isClosed: React.PropTypes.bool,
|
||||||
any: React.PropTypes.any,
|
any: React.PropTypes.any
|
||||||
}
|
}
|
||||||
});
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
See [propTypes](http://facebook.github.io/react/docs/reusable-components.html#prop-validation).
|
||||||
|
|
||||||
### Required types
|
### Required types
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
MyComponent.propTypes = {
|
||||||
|
requiredFunc: React.PropTypes.func.isRequired,
|
||||||
|
requiredAny: React.PropTypes.any.isRequired
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
Add `.isRequired`.
|
Add `.isRequired`.
|
||||||
|
|
||||||
```js
|
### React elements
|
||||||
propTypes: {
|
|
||||||
requiredFunc: React.PropTypes.func.isRequired,
|
```jsx
|
||||||
requiredAny: React.PropTypes.any.isRequired,
|
MyComponent.propTypes = {
|
||||||
|
// React element
|
||||||
|
element: React.PropTypes.element,
|
||||||
|
|
||||||
|
// num, string, element, or an array of those
|
||||||
|
node: React.PropTypes.node
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### React elements
|
|
||||||
Use `.element`, `.node`.
|
Use `.element`, `.node`.
|
||||||
|
|
||||||
```js
|
|
||||||
propTypes: {
|
|
||||||
element: React.PropTypes.element, // react element
|
|
||||||
node: React.PropTypes.node, // num, string, element
|
|
||||||
// ...or array of those
|
|
||||||
```
|
|
||||||
|
|
||||||
### Enumerables
|
### Enumerables
|
||||||
Use `.oneOf`, `.oneOfType`.
|
|
||||||
|
|
||||||
```
|
```
|
||||||
propTypes: {
|
propTypes: {
|
||||||
|
@ -281,10 +277,11 @@ propTypes: {
|
||||||
React.PropTypes.number ]),
|
React.PropTypes.number ]),
|
||||||
```
|
```
|
||||||
|
|
||||||
### Arrays and objects
|
Use `.oneOf`, `.oneOfType`.
|
||||||
Use `.array[Of]`, `.object[Of]`, `.instanceOf`, `.shape`.
|
|
||||||
|
|
||||||
```js
|
### Arrays and objects
|
||||||
|
|
||||||
|
```jsx
|
||||||
propTypes: {
|
propTypes: {
|
||||||
array: React.PropTypes.array,
|
array: React.PropTypes.array,
|
||||||
arrayOf: React.PropTypes.arrayOf(React.PropTypes.number),
|
arrayOf: React.PropTypes.arrayOf(React.PropTypes.number),
|
||||||
|
@ -299,10 +296,11 @@ propTypes: {
|
||||||
}),
|
}),
|
||||||
```
|
```
|
||||||
|
|
||||||
### Custom validation
|
Use `.array[Of]`, `.object[Of]`, `.instanceOf`, `.shape`.
|
||||||
Supply your own function.
|
|
||||||
|
|
||||||
```js
|
### Custom validation
|
||||||
|
|
||||||
|
```jsx
|
||||||
propTypes: {
|
propTypes: {
|
||||||
customProp: function(props, propName, componentName) {
|
customProp: function(props, propName, componentName) {
|
||||||
if (!/matchme/.test(props[propName])) {
|
if (!/matchme/.test(props[propName])) {
|
||||||
|
@ -312,61 +310,31 @@ propTypes: {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Supply your own function.
|
||||||
|
|
||||||
## Other features
|
## Other features
|
||||||
|
|
||||||
### Class set
|
|
||||||
Manipulate DOM classes with [classnames](https://www.npmjs.org/package/classnames), previously known as `React.addons.classSet`. See [Class set](http://facebook.github.io/react/docs/class-name-manipulation.html).
|
|
||||||
|
|
||||||
```js
|
|
||||||
var cx = require('classnames');
|
|
||||||
|
|
||||||
render: function() {
|
|
||||||
var classes = cx({
|
|
||||||
'message': true,
|
|
||||||
'message-important': this.props.isImportant,
|
|
||||||
'message-read': this.props.isRead
|
|
||||||
});
|
|
||||||
|
|
||||||
return <div className={classes}>Great Scott!</div>;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Propagating properties
|
### Propagating properties
|
||||||
See [Transferring props](http://facebook.github.io/react/docs/transferring-props.html).
|
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<VideoPlayer src="video.mp4" />
|
<VideoPlayer src="video.mp4" />
|
||||||
```
|
```
|
||||||
{:.light}
|
|
||||||
|
|
||||||
```js
|
```jsx
|
||||||
var VideoPlayer = React.createClass({
|
class VideoPlayer extends React.Component {
|
||||||
render: function() {
|
render () {
|
||||||
/* propagates src="..." down to this sub component */
|
return <VideoEmbed {...this.props} />
|
||||||
return <VideoEmbed {...this.props} controls='false' />;
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### Mixins
|
|
||||||
See [addons](https://facebook.github.io/react/docs/addons.html) for some built-in mixins.
|
|
||||||
|
|
||||||
```js
|
|
||||||
var SetIntervalMixin = {
|
|
||||||
componentWillMount: function() { .. }
|
|
||||||
}
|
|
||||||
```
|
|
||||||
{:.light}
|
|
||||||
|
|
||||||
```js
|
|
||||||
var TickTock = React.createClass({
|
|
||||||
mixins: [SetIntervalMixin]
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## [Top level API](https://facebook.github.io/react/docs/top-level-api.html)
|
Propagates `src="..."` down to the sub-component.
|
||||||
|
|
||||||
```js
|
See [Transferring props](http://facebook.github.io/react/docs/transferring-props.html).
|
||||||
|
|
||||||
|
### Top-level API
|
||||||
|
|
||||||
|
```jsx
|
||||||
React.createClass({ ... })
|
React.createClass({ ... })
|
||||||
|
|
||||||
React.isValidElement(c)
|
React.isValidElement(c)
|
||||||
|
@ -379,27 +347,30 @@ ReactDOMServer.renderToString(<Component />) // 0.14+
|
||||||
ReactDOMServer.renderToStaticMarkup(<Component />) // 0.14+
|
ReactDOMServer.renderToStaticMarkup(<Component />) // 0.14+
|
||||||
```
|
```
|
||||||
|
|
||||||
## JSX patterns
|
JSX patterns
|
||||||
|
------------
|
||||||
|
|
||||||
### Style shorthand
|
### Style shorthand
|
||||||
See [inline styles](https://facebook.github.io/react/tips/inline-styles.html).
|
|
||||||
|
|
||||||
```js
|
```jsx
|
||||||
var style = { backgroundImage: 'url(x.jpg)', height: 10 };
|
var style = { backgroundImage: 'url(x.jpg)', height: 10 };
|
||||||
return <div style={style}></div>;
|
return <div style={style}></div>;
|
||||||
```
|
```
|
||||||
|
|
||||||
### InnerHTML
|
See [inline styles](https://facebook.github.io/react/tips/inline-styles.html).
|
||||||
See [dangerously set innerHTML](https://facebook.github.io/react/tips/dangerously-set-inner-html.html).
|
|
||||||
|
|
||||||
```js
|
### Inner HTML
|
||||||
|
|
||||||
|
```jsx
|
||||||
function markdownify() { return "<p>...</p>"; }
|
function markdownify() { return "<p>...</p>"; }
|
||||||
<div dangerouslySetInnerHTML={{__html: markdownify()}} />
|
<div dangerouslySetInnerHTML={{__html: markdownify()}} />
|
||||||
```
|
```
|
||||||
|
|
||||||
|
See [dangerously set innerHTML](https://facebook.github.io/react/tips/dangerously-set-inner-html.html).
|
||||||
|
|
||||||
### Lists
|
### Lists
|
||||||
|
|
||||||
```js
|
```jsx
|
||||||
var TodoList = React.createClass({
|
var TodoList = React.createClass({
|
||||||
render: function() {
|
render: function() {
|
||||||
function item(itemText) {
|
function item(itemText) {
|
||||||
|
@ -410,7 +381,13 @@ var TodoList = React.createClass({
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
## See also
|
See also
|
||||||
|
--------
|
||||||
|
|
||||||
|
{:.-two-column}
|
||||||
|
|
||||||
|
### Also see
|
||||||
|
|
||||||
* [Animations](http://facebook.github.io/react/docs/animation.html)
|
* [Animations](http://facebook.github.io/react/docs/animation.html)
|
||||||
|
|
||||||
{%endraw%}
|
{%endraw%}
|
||||||
|
|
|
@ -0,0 +1,416 @@
|
||||||
|
---
|
||||||
|
title: React.js
|
||||||
|
category: React
|
||||||
|
layout: default-ad
|
||||||
|
---
|
||||||
|
|
||||||
|
{%raw%}
|
||||||
|
|
||||||
|
Use the [React.js jsfiddle](http://jsfiddle.net/reactjs/69z2wepo/) to start hacking. (or the unofficial [jsbin](http://jsbin.com/yafixat/edit?js,output))
|
||||||
|
{:.brief-intro.center}
|
||||||
|
|
||||||
|
```js
|
||||||
|
var Component = React.createClass({
|
||||||
|
render: function () {
|
||||||
|
return <div>Hello {this.props.name}</div>;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
```js
|
||||||
|
ReactDOM.render(<Component name="John" />, document.body);
|
||||||
|
```
|
||||||
|
{:.light}
|
||||||
|
|
||||||
|
## Nesting
|
||||||
|
Nest components to separate concerns. See [multiple components](http://facebook.github.io/react/docs/multiple-components.html).
|
||||||
|
{:.center}
|
||||||
|
|
||||||
|
```js
|
||||||
|
var UserAvatar = React.createClass({...});
|
||||||
|
var UserProfile = React.createClass({...});
|
||||||
|
```
|
||||||
|
{:.light}
|
||||||
|
|
||||||
|
```js
|
||||||
|
var Info = React.createClass({
|
||||||
|
render() {
|
||||||
|
return <div>
|
||||||
|
<UserAvatar src={this.props.avatar} />
|
||||||
|
<UserProfile username={this.props.username} />
|
||||||
|
</div>;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## States & Properties
|
||||||
|
Use [props](https://facebook.github.io/react/docs/tutorial.html#using-props) (`this.props`) to access parameters passed from the parent.
|
||||||
|
Use [states](https://facebook.github.io/react/docs/tutorial.html#reactive-state) (`this.state`) to manage dynamic data.
|
||||||
|
{:.center}
|
||||||
|
|
||||||
|
```html
|
||||||
|
<MyComponent fullscreen={true} />
|
||||||
|
```
|
||||||
|
{:.light}
|
||||||
|
|
||||||
|
```js
|
||||||
|
// props
|
||||||
|
this.props.fullscreen //=> true
|
||||||
|
|
||||||
|
// state
|
||||||
|
this.setState({ username: 'rstacruz' });
|
||||||
|
this.replaceState({ ... });
|
||||||
|
this.state.username //=> 'rstacruz'
|
||||||
|
```
|
||||||
|
|
||||||
|
```js
|
||||||
|
render: function () {
|
||||||
|
return <div className={this.props.fullscreen ? 'full' : ''}>
|
||||||
|
Welcome, {this.state.username}
|
||||||
|
</div>;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Setting defaults
|
||||||
|
Pre-populates `this.state.comments` and `this.props.name`.
|
||||||
|
|
||||||
|
```js
|
||||||
|
React.createClass({
|
||||||
|
getInitialState: function () {
|
||||||
|
return { comments: [] };
|
||||||
|
},
|
||||||
|
|
||||||
|
getDefaultProps: function () {
|
||||||
|
return { name: "Hello" };
|
||||||
|
}
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Component API
|
||||||
|
|
||||||
|
These are methods available for `Component` instances. See [Component API](http://facebook.github.io/react/docs/component-api.html).
|
||||||
|
{:.center}
|
||||||
|
|
||||||
|
```js
|
||||||
|
ReactDOM.findDOMNode(c) // 0.14+
|
||||||
|
React.findDOMNode(c) // 0.13
|
||||||
|
c.getDOMNode() // 0.12 below
|
||||||
|
```
|
||||||
|
{:.light}
|
||||||
|
|
||||||
|
```js
|
||||||
|
c.forceUpdate()
|
||||||
|
c.isMounted()
|
||||||
|
|
||||||
|
c.state
|
||||||
|
c.props
|
||||||
|
|
||||||
|
c.setState({ ... })
|
||||||
|
c.replaceState({ ... })
|
||||||
|
|
||||||
|
c.setProps({ ... }) // for deprecation
|
||||||
|
c.replaceProps({ ... }) // for deprecation
|
||||||
|
|
||||||
|
c.refs
|
||||||
|
```
|
||||||
|
|
||||||
|
### Component specs
|
||||||
|
Methods and properties you can override. See [component specs](http://facebook.github.io/react/docs/component-specs.html).
|
||||||
|
|
||||||
|
| Method | What |
|
||||||
|
| ---- | ---- |
|
||||||
|
| [`render()`](http://facebook.github.io/react/docs/component-specs.html#render) | |
|
||||||
|
| ---- | ---- |
|
||||||
|
| [`getInitialState()`](http://facebook.github.io/react/docs/component-specs.html#getinitialstate) | |
|
||||||
|
| [`getDefaultProps()`](http://facebook.github.io/react/docs/component-specs.html#getdefaultprops) | |
|
||||||
|
| ---- | ---- |
|
||||||
|
| [`mixins: [ ... ]`](http://facebook.github.io/react/docs/component-specs.html#mixins) | Mixins ... [more](#mixins) |
|
||||||
|
| [`propTypes: { ... }`](http://facebook.github.io/react/docs/component-specs.html#proptypes) | Validation ... [more](#property-validation) |
|
||||||
|
| [`statics: { ... }`](http://facebook.github.io/react/docs/component-specs.html#statics) | Static methods |
|
||||||
|
| [`displayName: "..."`](http://facebook.github.io/react/docs/component-specs.html#displayname) | Automatically filled by JSX |
|
||||||
|
{:.greycode.no-head}
|
||||||
|
|
||||||
|
## Lifecycle
|
||||||
|
|
||||||
|
### Mounting
|
||||||
|
Before initial rendering occurs. Add your DOM stuff on didMount (events, timers, etc). See [reference](http://facebook.github.io/react/docs/component-specs.html#mounting-componentwillmount).
|
||||||
|
|
||||||
|
| `componentWillMount()` | Before rendering (no DOM yet) |
|
||||||
|
| `componentDidMount()` | After rendering |
|
||||||
|
{:.greycode.no-head.lc}
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
### Updating
|
||||||
|
Called when parents change properties and `.setState()`. These are not called for initial renders. See [reference](http://facebook.github.io/react/docs/component-specs.html#updating-componentwillreceiveprops).
|
||||||
|
|
||||||
|
| `componentWillReceiveProps`*(newProps={})* | Use `setState()` here |
|
||||||
|
| `shouldComponentUpdate`*(newProps={}, newState={})* | Skips `render()` if returns false |
|
||||||
|
| `componentWillUpdate`*(newProps={}, newState={})* | Can't use `setState()` here |
|
||||||
|
| `componentDidUpdate`*(prevProps={}, prevState={})* | Operate on the DOM here |
|
||||||
|
{:.greycode.no-head.lc}
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
### Unmounting
|
||||||
|
Clear your DOM stuff here (probably done on didMount). See [reference](http://facebook.github.io/react/docs/component-specs.html#unmounting-componentwillunmount).
|
||||||
|
|
||||||
|
| `componentWillUnmount()` | Invoked before DOM removal |
|
||||||
|
{:.greycode.no-head.lc}
|
||||||
|
|
||||||
|
<style>
|
||||||
|
table.lc { table-layout: fixed; }
|
||||||
|
table.lc tr>:nth-child(1) { width: 50%; }
|
||||||
|
table.lc tr>:nth-child(2) { text-align: right; }
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
### Example: loading data
|
||||||
|
See [initial AJAX data](http://facebook.github.io/react/tips/initial-ajax.html).
|
||||||
|
|
||||||
|
```js
|
||||||
|
React.createClass({
|
||||||
|
componentDidMount: function () {
|
||||||
|
$.get(this.props.url, function (data) {
|
||||||
|
this.setState(data);
|
||||||
|
}.bind(this));
|
||||||
|
},
|
||||||
|
|
||||||
|
render: function () {
|
||||||
|
return <CommentList data={this.state.data} />
|
||||||
|
}
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## DOM nodes
|
||||||
|
|
||||||
|
### References
|
||||||
|
Allows access to DOM nodes. See [References](http://facebook.github.io/react/docs/more-about-refs.html).
|
||||||
|
|
||||||
|
```html
|
||||||
|
<input ref="myInput">
|
||||||
|
```
|
||||||
|
{:.light}
|
||||||
|
|
||||||
|
```js
|
||||||
|
this.refs.myInput
|
||||||
|
ReactDOM.findDOMNode(this.refs.myInput).focus()
|
||||||
|
ReactDOM.findDOMNode(this.refs.myInput).value
|
||||||
|
```
|
||||||
|
|
||||||
|
### DOM Events
|
||||||
|
Add attributes like `onChange`. See [events](https://facebook.github.io/react/docs/events.html).
|
||||||
|
|
||||||
|
```html
|
||||||
|
<input type="text"
|
||||||
|
value={this.state.value}
|
||||||
|
onChange={this.handleChange} />
|
||||||
|
```
|
||||||
|
{:.light}
|
||||||
|
|
||||||
|
```js
|
||||||
|
handleChange: function(event) {
|
||||||
|
this.setState({ value: event.target.value });
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Two-way binding
|
||||||
|
Use [LinkedStateMixin](http://facebook.github.io/react/docs/two-way-binding-helpers.html) for easier two-way binding.
|
||||||
|
|
||||||
|
```html
|
||||||
|
Email: <input type="text" valueLink={this.linkState('email')} />
|
||||||
|
```
|
||||||
|
{:.light}
|
||||||
|
|
||||||
|
```js
|
||||||
|
React.createClass({
|
||||||
|
mixins: [React.addons.LinkedStateMixin]
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
```js
|
||||||
|
this.state.email
|
||||||
|
```
|
||||||
|
|
||||||
|
## Property validation
|
||||||
|
|
||||||
|
### Basic types
|
||||||
|
Primitive types: `.string`, `.number`, `.func`, and `.bool`. See [propTypes](http://facebook.github.io/react/docs/reusable-components.html#prop-validation).
|
||||||
|
|
||||||
|
```js
|
||||||
|
React.createClass({
|
||||||
|
propTypes: {
|
||||||
|
email: React.PropTypes.string,
|
||||||
|
seats: React.PropTypes.number,
|
||||||
|
settings: React.PropTypes.object,
|
||||||
|
callback: React.PropTypes.func,
|
||||||
|
isClosed: React.PropTypes.bool,
|
||||||
|
any: React.PropTypes.any,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Required types
|
||||||
|
Add `.isRequired`.
|
||||||
|
|
||||||
|
```js
|
||||||
|
propTypes: {
|
||||||
|
requiredFunc: React.PropTypes.func.isRequired,
|
||||||
|
requiredAny: React.PropTypes.any.isRequired,
|
||||||
|
```
|
||||||
|
|
||||||
|
### React elements
|
||||||
|
Use `.element`, `.node`.
|
||||||
|
|
||||||
|
```js
|
||||||
|
propTypes: {
|
||||||
|
element: React.PropTypes.element, // react element
|
||||||
|
node: React.PropTypes.node, // num, string, element
|
||||||
|
// ...or array of those
|
||||||
|
```
|
||||||
|
|
||||||
|
### Enumerables
|
||||||
|
Use `.oneOf`, `.oneOfType`.
|
||||||
|
|
||||||
|
```
|
||||||
|
propTypes: {
|
||||||
|
enum: React.PropTypes.oneOf(['M','F']), // enum
|
||||||
|
union: React.PropTypes.oneOfType([ // any
|
||||||
|
React.PropTypes.string,
|
||||||
|
React.PropTypes.number ]),
|
||||||
|
```
|
||||||
|
|
||||||
|
### Arrays and objects
|
||||||
|
Use `.array[Of]`, `.object[Of]`, `.instanceOf`, `.shape`.
|
||||||
|
|
||||||
|
```js
|
||||||
|
propTypes: {
|
||||||
|
array: React.PropTypes.array,
|
||||||
|
arrayOf: React.PropTypes.arrayOf(React.PropTypes.number),
|
||||||
|
object: React.PropTypes.object,
|
||||||
|
objectOf: React.PropTypes.objectOf(React.PropTypes.number),
|
||||||
|
|
||||||
|
message: React.PropTypes.instanceOf(Message),
|
||||||
|
|
||||||
|
object2: React.PropTypes.shape({
|
||||||
|
color: React.PropTypes.string,
|
||||||
|
size: React.PropTypes.number
|
||||||
|
}),
|
||||||
|
```
|
||||||
|
|
||||||
|
### Custom validation
|
||||||
|
Supply your own function.
|
||||||
|
|
||||||
|
```js
|
||||||
|
propTypes: {
|
||||||
|
customProp: function(props, propName, componentName) {
|
||||||
|
if (!/matchme/.test(props[propName])) {
|
||||||
|
return new Error('Validation failed!');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Other features
|
||||||
|
|
||||||
|
### Class set
|
||||||
|
Manipulate DOM classes with [classnames](https://www.npmjs.org/package/classnames), previously known as `React.addons.classSet`. See [Class set](http://facebook.github.io/react/docs/class-name-manipulation.html).
|
||||||
|
|
||||||
|
```js
|
||||||
|
var cx = require('classnames');
|
||||||
|
|
||||||
|
render: function() {
|
||||||
|
var classes = cx({
|
||||||
|
'message': true,
|
||||||
|
'message-important': this.props.isImportant,
|
||||||
|
'message-read': this.props.isRead
|
||||||
|
});
|
||||||
|
|
||||||
|
return <div className={classes}>Great Scott!</div>;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Propagating properties
|
||||||
|
See [Transferring props](http://facebook.github.io/react/docs/transferring-props.html).
|
||||||
|
|
||||||
|
```html
|
||||||
|
<VideoPlayer src="video.mp4" />
|
||||||
|
```
|
||||||
|
{:.light}
|
||||||
|
|
||||||
|
```js
|
||||||
|
var VideoPlayer = React.createClass({
|
||||||
|
render: function() {
|
||||||
|
/* propagates src="..." down to this sub component */
|
||||||
|
return <VideoEmbed {...this.props} controls='false' />;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Mixins
|
||||||
|
See [addons](https://facebook.github.io/react/docs/addons.html) for some built-in mixins.
|
||||||
|
|
||||||
|
```js
|
||||||
|
var SetIntervalMixin = {
|
||||||
|
componentWillMount: function() { .. }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
{:.light}
|
||||||
|
|
||||||
|
```js
|
||||||
|
var TickTock = React.createClass({
|
||||||
|
mixins: [SetIntervalMixin]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## [Top level API](https://facebook.github.io/react/docs/top-level-api.html)
|
||||||
|
|
||||||
|
```js
|
||||||
|
React.createClass({ ... })
|
||||||
|
|
||||||
|
React.isValidElement(c)
|
||||||
|
|
||||||
|
ReactDOM.findDOMNode(c) // 0.14+
|
||||||
|
ReactDOM.render(<Component />, domnode, [callback]) // 0.14+
|
||||||
|
ReactDOM.unmountComponentAtNode(domnode) // 0.14+
|
||||||
|
|
||||||
|
ReactDOMServer.renderToString(<Component />) // 0.14+
|
||||||
|
ReactDOMServer.renderToStaticMarkup(<Component />) // 0.14+
|
||||||
|
```
|
||||||
|
|
||||||
|
## JSX patterns
|
||||||
|
|
||||||
|
### Style shorthand
|
||||||
|
See [inline styles](https://facebook.github.io/react/tips/inline-styles.html).
|
||||||
|
|
||||||
|
```js
|
||||||
|
var style = { backgroundImage: 'url(x.jpg)', height: 10 };
|
||||||
|
return <div style={style}></div>;
|
||||||
|
```
|
||||||
|
|
||||||
|
### InnerHTML
|
||||||
|
See [dangerously set innerHTML](https://facebook.github.io/react/tips/dangerously-set-inner-html.html).
|
||||||
|
|
||||||
|
```js
|
||||||
|
function markdownify() { return "<p>...</p>"; }
|
||||||
|
<div dangerouslySetInnerHTML={{__html: markdownify()}} />
|
||||||
|
```
|
||||||
|
|
||||||
|
### Lists
|
||||||
|
|
||||||
|
```js
|
||||||
|
var TodoList = React.createClass({
|
||||||
|
render: function() {
|
||||||
|
function item(itemText) {
|
||||||
|
return <li>{itemText}</li>;
|
||||||
|
};
|
||||||
|
return <ul>{this.props.items.map(item)}</ul>;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## See also
|
||||||
|
|
||||||
|
* [Animations](http://facebook.github.io/react/docs/animation.html)
|
||||||
|
{%endraw%}
|
|
@ -1,6 +1,7 @@
|
||||||
---
|
---
|
||||||
title: Sketch
|
title: Sketch
|
||||||
category: Apps
|
category: Apps
|
||||||
|
layout: 2017/sheet
|
||||||
---
|
---
|
||||||
|
|
||||||
### Insert
|
### Insert
|
||||||
|
@ -12,7 +13,6 @@ category: Apps
|
||||||
| `R` | rect |
|
| `R` | rect |
|
||||||
| `O` | oval |
|
| `O` | oval |
|
||||||
| `U` | rounded |
|
| `U` | rounded |
|
||||||
{:.shortcuts}
|
|
||||||
|
|
||||||
### Show
|
### Show
|
||||||
|
|
||||||
|
@ -21,7 +21,6 @@ category: Apps
|
||||||
| `^P` | pixels |
|
| `^P` | pixels |
|
||||||
| `^H` | selection handles |
|
| `^H` | selection handles |
|
||||||
| `^R` | rulers |
|
| `^R` | rulers |
|
||||||
{:.shortcuts}
|
|
||||||
|
|
||||||
### Sidebars
|
### Sidebars
|
||||||
|
|
||||||
|
@ -29,7 +28,6 @@ category: Apps
|
||||||
| `⌘⌥2` | toggle right (inspector) |
|
| `⌘⌥2` | toggle right (inspector) |
|
||||||
| `⌘⌥3` | toggle both |
|
| `⌘⌥3` | toggle both |
|
||||||
| `⌘.` | presentation |
|
| `⌘.` | presentation |
|
||||||
{:.shortcuts}
|
|
||||||
|
|
||||||
### Zoom
|
### Zoom
|
||||||
|
|
||||||
|
@ -37,19 +35,16 @@ category: Apps
|
||||||
| `⌘1` | fit to screen |
|
| `⌘1` | fit to screen |
|
||||||
| `⌘2` | fit selection to screen |
|
| `⌘2` | fit selection to screen |
|
||||||
| `⌘3` | center selection |
|
| `⌘3` | center selection |
|
||||||
{:.shortcuts}
|
|
||||||
|
|
||||||
### Arrange
|
### Arrange
|
||||||
|
|
||||||
| `⌘⌥ up/dn` | forward or backward |
|
| `⌘⌥ up/dn` | forward or backward |
|
||||||
| `^⌘⌥ up/dn` | front or back |
|
| `^⌘⌥ up/dn` | front or back |
|
||||||
{:.shortcuts}
|
|
||||||
|
|
||||||
### Distribute
|
### Distribute
|
||||||
|
|
||||||
| `^⌘H` | horizontal |
|
| `^⌘H` | horizontal |
|
||||||
| `^⌘V` | vertical |
|
| `^⌘V` | vertical |
|
||||||
{:.shortcuts}
|
|
||||||
|
|
||||||
### Layers
|
### Layers
|
||||||
|
|
||||||
|
@ -57,7 +52,6 @@ category: Apps
|
||||||
| `⌘F` | find |
|
| `⌘F` | find |
|
||||||
| `⌘G` | group |
|
| `⌘G` | group |
|
||||||
| `⌘⇧G` | ungroup |
|
| `⌘⇧G` | ungroup |
|
||||||
{:.shortcuts}
|
|
||||||
|
|
||||||
### Font
|
### Font
|
||||||
|
|
||||||
|
@ -65,4 +59,3 @@ category: Apps
|
||||||
| `⌘⇧[` | left align |
|
| `⌘⇧[` | left align |
|
||||||
| `⌘⇧\` | center align |
|
| `⌘⇧\` | center align |
|
||||||
| `⌘⇧]` | right align |
|
| `⌘⇧]` | right align |
|
||||||
{:.shortcuts}
|
|
||||||
|
|
Loading…
Reference in New Issue