Initial implementation

This commit is contained in:
Rico Sta. Cruz 2017-08-24 06:22:00 +08:00
parent f533a52407
commit d0142fb682
No known key found for this signature in database
GPG Key ID: CAAD38AE2962619A
9 changed files with 992 additions and 247 deletions

View File

@ -9,7 +9,7 @@ exclude:
- _deprecated - _deprecated
# Markdown # Markdown
highlighter: rouge highlighter: false
markdown: kramdown markdown: kramdown
kramdown: kramdown:
input: GFM input: GFM

3
_includes/2017/foot.html Normal file
View File

@ -0,0 +1,3 @@
</div>
</body>
</html>

19
_includes/2017/head.html Normal file
View File

@ -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'>

9
_layouts/2017/sheet.html Normal file
View File

@ -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 %}

80
assets/2017/script.js Normal file
View File

@ -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
}
}

248
assets/2017/style.css Normal file
View File

@ -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;
}

453
react.md
View File

@ -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, callback: React.PropTypes.func,
settings: React.PropTypes.object, isClosed: React.PropTypes.bool,
callback: React.PropTypes.func, any: React.PropTypes.any
isClosed: React.PropTypes.bool, }
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%}

416
react@0.14.md Normal file
View File

@ -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%}

View File

@ -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}