Introduction to React and Flux (CodeLabs)
-
Upload
eueung-mulyana -
Category
Software
-
view
426 -
download
3
Transcript of Introduction to React and Flux (CodeLabs)
React + FluxEueung Mulyana
http://eueung.github.io/js/reactJS CodeLabs | Attribution-ShareAlike CC BY-SA
1 / 40
React Basics #1A JavaScript library for building UIs | React
3 / 40
<!DOCTYPE html><html> <head> <meta charset="UTF-8" /> <title>Hello React!</title> <script src="react-0.14.5/react.js"></script> <script src="react-0.14.5/react-dom.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js" </head> <body> <div id="example"></div> <script type="text/babel"> ReactDOM.render( <h1>Hello, world!</h1>, document.getElementById('example') ); </script> </body></html>
Render @Browserhello-00-A.html
4 / 40
Render @Browserhello-01-B.html
src/hello-01.js
ReactDOM.render( document.getElementById('example'));
<!DOCTYPE html><html> <head> <meta charset="UTF-8" /> <title>Hello React!</title> <script src="react-0.14.5/react.js"></script> <script src="react-0.14.5/react-dom.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js" </head> <body> <div id="example"></div> <script type="text/babel" src="src/hello-01.js"></script </body></html>
<h1>Hello, world!</h1>,
5 / 40
<!DOCTYPE html><html> <head> <meta charset="UTF-8" /> <title>Hello React!</title> <script src="react-0.14.5/react.js"></script> <script src="react-0.14.5/react-dom.js"></script> </head> <body> <div id="example"></div> <script src="build/hello-02.js"></script> </body></html>
# src/hello-02.js (JSX)ReactDOM.render( document.getElementById('example'));
# build/hello-02.js (compiled)ReactDOM.render(React.createElement( 'h1', null, 'Hello, world!'), document.getElementById('example'));
<h1>Hello, world!</h1>,
PrecompileJSX to vanilla JS
npm install -g babel-cli npm install -g babel-preset-react npm install -g babel-preset-es2015
$> babel --presets react hello-02.js --out-dir=../buildhello-02.js -> ..\build\hello-02.js
6 / 40
this.props
hello-03.js
<!DOCTYPE html><html> <head> <meta charset="UTF-8" /> <title>Hello React!</title> <script src="react-0.14.5/react.js"></script> <script src="react-0.14.5/react-dom.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js" </head> <body> <div id="example"></div> <script type="text/babel" src="src/hello-03.js"></script </body></html>
var HelloMessage = React.createClass({ render: function() { return }});
ReactDOM.render(
<div>Hello {this.props.name}</div>;
<HelloMessage name="John" />, document.getElementById('example'));
7 / 40
hello-04.js
var Timer = React.createClass({ getInitialState: function() { return {secondsElapsed: 0}; }, tick: function() { this.setState({secondsElapsed: this.state.secondsElapsed + }, componentDidMount: function() { this.interval = setInterval(this.tick, 1000); }, componentWillUnmount: function() { clearInterval(this.interval); }, render: function() { return ( ); }});
ReactDOM.render(
<div>Seconds Elapsed: {this.state.secondsElapsed}</div
<Timer />, document.getElementById('example'));
this.state
8 / 40
TodoApp
var TodoList = React.createClass({ render: function() { var createItem = function(item) { return }; return }});
hello-05.js
<li key={item.id}>{item.text}</li>;
<ul>{this.props.items.map(createItem)}</ul>;
var TodoApp = React.createClass({ getInitialState: function() { return {items: [], text: ''}; }, onChange: function(e) { this.setState({text: e.target.value}); }, handleSubmit: function(e) { e.preventDefault(); var nextItems = this.state.items.concat([{text: this.state.text, id: var nextText = ''; this.setState({items: nextItems, text: nextText}); }, render: function() { return ( <h3>TODO</h3> <TodoList items={this.state.items} /> <form onSubmit={this.handleSubmit}> <input onChange={this.onChange} value={this.state.text} <button>{'Add #' + (this.state.items.length + 1)} </form> </div> ); }});
ReactDOM.render(
<div>
<TodoApp />, document.getElementById('example'));
9 / 40
hello-06.html
<!DOCTYPE html><html> <head> <meta charset="UTF-8" /> <title>Hello React!</title> <script src="react-0.14.5/react.js"></script> <script src="react-0.14.5/react-dom.js"></script>
<script src="https://facebook.github.io/react/js/marked.min.js" <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js" </head> <body> <div id="example"></div> <script type="text/babel" src="src/hello-06.js"></script </body></html>
MarkdownEditorA Component Using External Plugins
11 / 40
hello-06.js
var MarkdownEditor = React.createClass({ getInitialState: function() { return {value: 'Type some *markdown* here!'}; }, handleChange: function() { this.setState({value: this.refs.textarea.value}); }, rawMarkup: function() { return { __html: marked(this.state.value, {sanitize: true }, render: function() { return ( <h3>Input</h3> <textarea onChange={this.handleChange} ref="textarea" defaultValue={this.state.value} /> <h3>Output</h3> <div className="content" dangerouslySetInnerHTML={this.rawMarkup()} /> </div> ); }});
ReactDOM.render(
<div className="MarkdownEditor">
<MarkdownEditor />, document.getElementById('example'));
12 / 40
React Basics #2Starter Kit Examples
13 / 40
<!DOCTYPE html><html> <head> <meta charset="utf-8"> <title>Basic Example</title> <link rel="stylesheet" href="../shared/css/base.css" /> </head> <body> <h1>Basic Example</h1>
<div id="container"> <p> To install React, follow the instructions on <a href <p> If you can see this, React is not working right. If you checked out the source from GitHub make sure to run </div>
<h4>Example Details</h4> <p>This is written in vanilla JavaScript (without JSX) and transformed in the browser. <p> Learn more about React at <a href="https://facebook.github.io/react"
<script src="../../react-0.14.5/react.js"></script> <script src="../../react-0.14.5/react-dom.js"></script> <script> ... </script> </body></html>
Example #1React with Vanilla JS
<script> var ExampleApplication = React.createClass({ render: function() { var elapsed = Math.round(this.props.elapsed / 100); var seconds = elapsed / 10 + (elapsed % 10 ? '' : '.0' var message = 'React has been successfully running for ' + seconds +
return React.DOM.p(null, message); } });
// Call React.createFactory instead of directly call ExampleApplication({...}) in React.render var ExampleApplicationFactory = React.createFactory(ExampleApplication);
var start = new Date().getTime(); setInterval(function() { ReactDOM.render( ExampleApplicationFactory({elapsed: new Date().getTime() - start}), document.getElementById('container') ); }, 50);</script>
14 / 40
Example #2React with JSX
<!DOCTYPE html><html> <head> <meta charset="utf-8"> <title>Basic Example with JSX</title> <link rel="stylesheet" href="../shared/css/base.css" /> </head> <body> <h1>Basic Example with JSX</h1> <div id="container"> <p> To install React, follow the instructions on <a href <p> If you can see this, React is not working right. If you checked out the source from GitHub make sure to run </div>
<h4>Example Details</h4> <p>This is written with JSX and transformed in the browser. <p>Learn more about React at <a href="https://facebook.github.io/react"
<script src="../../react-0.14.5/react.js"></script> <script src="../../react-0.14.5/react-dom.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.34/browser.min.js"
<script type="text/babel"> ... </script> </body></html>
<script type="text/babel"> var ExampleApplication = React.createClass({ render: function() { var elapsed = Math.round(this.props.elapsed / 100); var seconds = elapsed / 10 + (elapsed % 10 ? '' : '.0' var message = 'React has been successfully running for ' + seconds +
return } }); var start = new Date().getTime(); setInterval(function() { ReactDOM.render( document.getElementById('container') ); }, 50);</script>
<p>{message}</p>;
<ExampleApplication elapsed={new Date().getTime() - start
15 / 40
Example #3Basic Click Counter (JSX)
<!DOCTYPE html><html> <head> <meta charset="utf-8"> <title>Basic Example with Click Counter</title> <script src="../../react-0.14.5/react.js"></script> <script src="../../react-0.14.5/react-dom.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.34/browser.min.js" </head> <body> <div id="message" align="center"></div>
<script type="text/babel"> var Counter = React.createClass({ getInitialState: function () { return { clickCount: 0 }; }, handleClick: function () { this.setState(function(state) { return {clickCount: state.clickCount + 1}; }); }, render: function () { return (<h2 onClick={this.handleClick}>Click me! Number of clicks: {this.state.clickCount} } }); ReactDOM.render( <Counter />, document.getElementById('message') ); </script></body></html>
17 / 40
<!DOCTYPE html><html> <head> ... </head>
<body> ...
<script src="../../react-0.14.5/react.js"></script> <script src="../../react-0.14.5/react-dom.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.34/browser.min.js" <script type="text/babel" src="example.js"></script> </body></html>
Example #4External JSX
example.js
var ExampleApplication = React.createClass({ render: function() { var elapsed = Math.round(this.props.elapsed / 100); var seconds = elapsed / 10 + (elapsed % 10 ? '' : '.0' ); var message = 'React has been successfully running for '
return }});
var start = new Date().getTime();
setInterval(function() { ReactDOM.render( }, 50);
<p>{message}</p>;
<ExampleApplication elapsed={new Date().getTime
18 / 40
Example #5Precompiled JSX (Vanilla JS @Browser)
$> babel --presets react example.js --out-dir=buildexample.js -> build\example.js
<!DOCTYPE html><html> <head> <meta charset="utf-8"> <title>Basic Example with Precompiled JSX</title> <link rel="stylesheet" href="../shared/css/base.css" /> </head> <body> <h1>Basic Example with Precompiled JSX</h1> <div id="container"> <p> If you can see this, React is not running. Try running: <pre> ... </pre> </div>
<h4>Example Details</h4> <p>This is written with JSX in a separate file and precompiled to vanilla JS by running: <pre> npm install -g babel cd examples/basic-jsx-precompile/ babel example.js --out-dir=build </pre> <p> Learn more about React at <a href="https://facebook.github.io/react"
<script src="../../react-0.14.5/react.js"></script> <script src="../../react-0.14.5/react-dom.js"></script> <script src="build/example.js"></script> </body></html>
19 / 40
Example #6JSX and Harmony (ES6|ES2015)
<!DOCTYPE html>
<head> <meta charset="utf-8"> <title>Basic Example with JSX and ES6 features</title> <link rel="stylesheet" href="../shared/css/base.css" /> </head> <body> <h1>Basic Example with JSX and ES6 features</h1> <div id="container"> <p>To install React, follow the instructions on <a href <p> If you can see this, React is not working right. If you checked out the source from GitHub make sure to run </div>
<h4>Example Details</h4> <p>This is written with JSX with Harmony (ES6) syntax and transformed in the browser. <p>Learn more about React at <a href="https://facebook.github.io/react"
<script src="../../react-0.14.5/react.js"></script> <script src="../../react-0.14.5/react-dom.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.34/browser.min.js" <script type="text/babel"> ... </script> </body></html>
<html>
<script type="text/babel"> class ExampleApplication extends React.Component { render() { var elapsed = Math.round(this.props.elapsed / 100); var seconds = elapsed / 10 + (elapsed % 10 ? '' : '.0' var message = ̀React has been successfully running for
return } } var start = new Date().getTime(); setInterval(() => { ReactDOM.render( }, 50);</script>
<p>{message}</p>;
<ExampleApplication elapsed={new Date()
20 / 40
Example #7CommonJS & Browserify (Bundled Vanilla JS @ Browser)
package.json
{ "name": "react-basic-commonjs-example", "description": "Basic example of using React with CommonJS" "main": "index.js", "dependencies": { "babelify": "̂6.3.0", "react": "̂0.14.0-rc1", "react-dom": "̂0.14.0-rc1", "watchify": "̂3.4.0" }, "scripts": { "start": "watchify index.js -v -t babelify -o bundle.js" }} npm install
npm start
21 / 40
index.js
'use strict';
var React = require('react');var ReactDOM = require('react-dom');
var ExampleApplication = React.createClass({ render: function() { var elapsed = Math.round(this.props.elapsed / 100); var seconds = elapsed / 10 + (elapsed % 10 ? '' : '.0' ); var message = 'React has been successfully running for ' + seconds +
return }});
var start = new Date().getTime();
setInterval(function() { ReactDOM.render( document.getElementById('container') );}, 50);
<p>{message}</p>;
<ExampleApplication elapsed={new Date().getTime() - start
index.html
<!DOCTYPE html><html> <head> <meta charset="utf-8"> <title>Basic CommonJS Example with Browserify</title> <link rel="stylesheet" href="../shared/css/base.css" /> </head> <body> <h1>Basic CommonJS Example with Browserify</h1> <div id="container"> <p>To install React, follow the instructions on <a href <p>If you can see this, React is not working right. If you checked out the source from GitHub make sure to run </div>
<h4>Example Details</h4> <p>This is written with JSX in a CommonJS module and precompiled to vanilla JS by running: <pre>npm start</pre> <p>Learn more about React at <a href="https://facebook.github.io/react"
<script src="bundle.js"></script> </body></html>
22 / 40
Example #8
index.html
<!DOCTYPE html><html> <head> <meta charset="utf-8"> <title>Quadratic Formula Calculator</title> <link rel="stylesheet" href="../shared/css/base.css" /> </head> <body> <h1>Quadratic Formula Calculator</h1> <div id="container"> <p>If you can see this, React is not working right. This is probably because you're viewing this on your file system instead of a web server. Try running </div>
<h4>Example Details</h4> <p>This is written with JSX in a separate file and transformed in the browser. <p>Learn more about React at <a href="https://facebook.github.io/react"
<script src="../../react-0.14.5/react.js"></script> <script src="../../react-0.14.5/react-dom.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.34/browser.min.js" <script type="text/babel" src="example.js"></script> </body></html>
23 / 40
var QuadraticCalculator = React.createClass({ getInitialState: function() { return { a: 1, b: 3, c: -4 }; },
handleInputChange: function(key, event) { var partialState = {}; partialState[key] = parseFloat(event.target.value); this.setState(partialState); },
render: function() { var a = this.state.a; var b = this.state.b; var c = this.state.c; var root = Math.sqrt(Math.pow(b, 2) - 4 * a * c); var denominator = 2 * a; var x1 = (-b + root) / denominator; var x2 = (-b - root) / denominator; return ( <strong> <em>ax</em><sup>2</sup> + <em>bx</em> + <em>c</em> = 0 </strong> <h4>Solve for <em>x</em>:</h4> <p> <label> a: <input type="number" value={a} onChange={this.handleInputChange.bind(null, <label> b: <input type="number" value={b} onChange={this.handleInputChange.bind(null, <label> c: <input type="number" value={c} onChange={this.handleInputChange.bind(null, x: <strong>{x1}, {x2}</strong> </p> </div> ); }});
ReactDOM.render(
<div>
<QuadraticCalculator />, document.getElementById('container') );
example.js
24 / 40
<!DOCTYPE html>
<head> <meta http-equiv='Content-type' content='text/html; charset=utf-8' <title>Basic Example with WebComponents</title> <link rel="stylesheet" href="../shared/css/base.css" /> </head> <body> <h1>Basic Example with WebComponents</h1> <div id="container"> <p>To install React, follow the instructions on <a href <p>If you can see this, React is not working right. If you checked out the source from GitHub make sure to run </div><br /><br />
<h4>Example Details</h4> <p>This example demonstrates WebComponent/ReactComponent interoperability by rendering a ReactComponent, which renders a WebComponent, which renders another ReactComponent in the WebComponent's shadow DOM. <p>Learn more about React at <a href="http://facebook.github.io/react"
<script src="../shared/thirdparty/webcomponents.js"></script <script src="../../react-0.14.5/react.js"></script> <script src="../../react-0.14.5/react-dom.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.34/browser.min.js"
<script type="text/babel"> ... </script> </body></html>
<html>
index.html
<script type="text/babel"> var proto = Object.create(HTMLElement.prototype, { createdCallback: { value: function() { var mountPoint = document.createElement('span'); this.createShadowRoot().appendChild(mountPoint);
var name = this.getAttribute('name'); var url = 'https://www.google.com/search?q=' + encodeURIComponent ReactDOM.render( } } }); document.registerElement('x-search', {prototype: proto});
class HelloMessage extends React.Component { render() { return <div>Hello <x-search name={this.props.name} />! } }
// Mount React Component (which uses WebComponent which uses React) var container = document.getElementById('container'); ReactDOM.render(</script>
<a href={url}>{name}</a>, mountPoint);
<HelloMessage name="Jim Sproch" />, container);
26 / 40
Example #10
<div id="container"><span class="animateExample" data-reactid=".0"> <div class="animateItem" style="left: 0px; background: red;" <div class="animateItem" style="left: 128px; background: gray;" <div class="animateItem" style="left:256px;background:blue;"</span></div>
27 / 40
index.html
<!DOCTYPE html>
<head> <meta charset="utf-8"> <title>Example with Transitions</title> <link rel="stylesheet" href="../shared/css/base.css" /> <link rel="stylesheet" href="transition.css" /> </head> <body> <h1>Example with Transitions</h1> <div id="container"> <p>To install React, follow the instructions on <a href <p>If you can see this, React is not working right. If you checked out the source from GitHub make sure to run </div>
<h4>Example Details</h4> <p>This is written with JSX and transformed in the browser. <p>Learn more about React at <a href="https://facebook.github.io/react"
<script src="../../react-0.14.5/react-with-addons.js"></ <script src="../../react-0.14.5/react-dom.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.34/browser.min.js"
<script type="text/babel"> ... </script> </body></html>
<html>
<script type="text/babel"> var CSSTransitionGroup = React.addons.CSSTransitionGroup; var INTERVAL = 2000;
var AnimateDemo = React.createClass({ getInitialState: function() { return {current: 0}; }, componentDidMount: function() { this.interval = setInterval( componentWillUnmount: function() { clearInterval(this.interval); }, tick: function() { this.setState({current: this.state.current +
render: function() { var children = []; var pos = 0; var colors = ['red', 'gray', 'blue']; for (var i = this.state.current; i < this.state.current + colors.length; i++) { var style = { left: pos * 128, background: colors[i % colors.length] }; pos++; children.push( } return ( {children} </CSSTransitionGroup> ); } });
ReactDOM.render(</script>
<div key={i} className="animateItem" style
<CSSTransitionGroup className="animateExample" transitionEnterTimeout
<AnimateDemo />, document.getElementById('container'));
28 / 40
transition.css
.example-enter,
.example-leave { -webkit-transition: all .25s; transition: all .25s;}
.example-enter,
.example-leave.example-leave-active { opacity: 0.01;}
.example-leave.example-leave-active { margin-left: -128px;}
.example-enter { margin-left: 128px;}
.example-enter.example-enter-active,
.example-leave { margin-left: 0; opacity: 1;}
.animateExample { display: block; height: 128px; position: relative; width: 384px;}
.animateItem { color: white; font-size: 36px; font-weight: bold; height: 128px; line-height: 128px; position: absolute; text-align: center; -webkit-transition: all .25s; /* TODO: make this a move animation */ transition: all .25s; /* TODO: make this a move animation */ width: 128px;}
29 / 40
FluxEasy Flux Example | @tonyspiro
30 / 40
Structureapp.jsstores/ListStore.jsdispatcher/AppDispatcher.jscomponents/
AppRoot.jsxNewItemForm.jsx
31 / 40
{ ..., "dependencies": { "babelify": "̂7.2.0", "babel-preset-react": "̂6.3.13", "babel-preset-es2015": "̂6.3.13", "browserify": "̂12.0.1", "events": "̂1.1.0", "flux": "̂2.1.1", "gulp": "̂3.9.0", "gulp-rename": "̂1.2.1", "gulp-uglify": "̂1.5.1", "lodash": "̂3.10.1", "react": "̂0.14.5", "react-dom": "̂0.14.5", "run-sequence": "̂1.1.5", "vinyl-source-stream": "̂1.1.0" }, "devDependencies": {}, ...}
npm install -g react react-dom babelify browserify flux lodash eventsnpm install -g babel-preset-react babel-preset-es2015npm install -g vinyl-source-stream gulp gulp-uglify gulp-rename run-sequence
package.json
33 / 40
var gulp = require('gulp');var browserify = require('browserify');var babelify = require('babelify');var source = require('vinyl-source-stream');var uglify = require('gulp-uglify');var rename = require('gulp-rename');var runSequence = require('run-sequence');
gulp.task('build', function () { return browserify({ entries: 'app.js', extensions: ['.jsx'], debug: true }) .transform(babelify, {presets: ['es2015','react']}) .bundle() .pipe(source('bundle.js')) .pipe(gulp.dest('dist'));});
gulp.task('compress', function() { return gulp.src('./dist/bundle.js') .pipe(uglify()) .pipe(rename({suffix: '.min'})) .pipe(gulp.dest('dist'));});
gulp.task('default', function(cb) { runSequence('build','compress', cb);});
gulpfile.jsgulp.task('watch', function () { gulp.watch("./*.js", ['default']); gulp.watch("./components/*.jsx", ['default']); gulp.watch("./dispatcher/*.js", ['default']); gulp.watch("./stores/*.js", ['default']);});
34 / 40
index.html<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Easy Flux Example</title></head><body> <h1>Easy Flux Example</h1> <div id="app-root"></div> <script src="dist/bundle.min.js"></script></body></html>
$> gulp[09:25:53] Using gulpfile ./gulpfile.js[09:25:53] Starting 'default'...[09:25:53] Starting 'build'...[09:25:59] Finished 'build' after 5.48 s[09:25:59] Starting 'compress'...[09:26:04] Finished 'compress' after 4.99 s[09:26:04] Finished 'default' after 10 s
app.jsimport React from 'react';import ReactDOM from 'react-dom';import AppRoot from './components/AppRoot';
ReactDOM.render(<AppRoot />, document.getElementById('app-root'));
35 / 40
ListStore.js
import {EventEmitter} from 'events';import _ from 'lodash';//-----------------------------------let ListStore = _.extend({}, EventEmitter.prototype, { items: [ { name: 'Item 1', id: 0 }, { name: 'Item 2', id:
getItems: function(){ return this.items; }, addItem: function(new_item){ this.items.push(new_item); },
removeItem: function(item_id){ let items = this.items; _.remove(items,(item) => { return item_id == item.id; }); this.items = items; },
emitChange: function(){ this.emit('change'); }, addChangeListener: function(callback){ this.on('change', callback); }, removeChangeListener: function(callback) { this.removeListener(});//-----------------------------------export default ListStore;
AppDispatcher.js
import {Dispatcher} from 'flux';import ListStore from '../stores/ListStore';//-----------------------------------let AppDispatcher = new Dispatcher();//-----------------------------------AppDispatcher.register((payload) => { let action = payload.action; let new_item = payload.new_item; let id = payload.id;
switch(action) { case 'add-item': ListStore.addItem(new_item); break; case 'remove-item': ListStore.removeItem(id); break; default: return true; }
ListStore.emitChange(); return true;});//-----------------------------------export default AppDispatcher;
36 / 40
import React from 'react';import ListStore from '../stores/ListStore';import AppDispatcher from '../dispatcher/AppDispatcher';import NewItemForm from './NewItemForm';//-----------------------------------let getListState = () => { return { items: ListStore.getItems() }; }//-----------------------------------class AppRoot extends React.Component { constructor() { super(); this.state = getListState(); } _onChange() { this.setState(getListState()); }
componentDidMount() { ListStore.addChangeListener(this._onChange.bind(this)); } componentWillUnmount() { ListStore.removeChangeListener(this._onChange.bind(this)); }
removeItem(e){ let id = e.target.dataset.id; AppDispatcher.dispatch({ action: 'remove-item', id: id }); }
render(){ let _this = this; let items = ListStore.getItems(); let itemHtml = items.map(( listItem ) => { return }); return ( ; }}//-----------------------------------export default AppRoot;
<li key={ listItem.id }> { listItem.name } <button onClick={ _this.removeItem
<div> <ul> { itemHtml } </ul> <NewItemForm /> </div> )
AppRoot.jsx
37 / 40
NewItemForm.jsx
import React from 'react';import ReactDOM from 'react-dom';import AppDispatcher from '../dispatcher/AppDispatcher';//-----------------------------------class NewItemForm extends React.Component { createItem(e){ e.preventDefault(); let id = guid();
let item_title = ReactDOM.findDOMNode(this.refs.item_title).value.trim(); ReactDOM.findDOMNode(this.refs.item_title).value = '';
AppDispatcher.dispatch({ action: 'add-item', new_item: { id: id, name: item_title } }); }
render(){ return }}//-----------------------------------function guid() { function s4() { return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1); } return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();}//-----------------------------------export default NewItemForm;
<form onSubmit={ this.createItem.bind(this) }> <input type="text" ref="item_title"
38 / 40
References1. A JavaScript library for building user interfaces | React2. Getting Started | React3. Building A Simple React Application Using The Flux Pattern: A Step-By-Step Guide4. flux/examples/flux-todomvc
39 / 40
ENDEueung Mulyana
http://eueung.github.io/js/reactJS CodeLabs | Attribution-ShareAlike CC BY-SA
40 / 40