Javascript library for building user interfaces
http://slides.com/muhammadazamuddin/reactjs-meetup
https://github.com/azamuddin/meetup-helloworld
https://github.com/azamuddin/meetup-todolist
<LineChart data={chartData} options={chartOptions} width="600" height="250"/>
var KomponenHello = React.createClass({
render: function(){
return (<div>Hello World</div>)
}
});
React.render(
<KomponenHello />,
document.getElementById('mount-point'));
buat komponen baru
render komponen tersebut
<body>
<div id="mount-point"></div>
</body>
Hello World
var KomponenHello = React.createClass({
render: function(){
return (<div>Hello {this.props.kepada}</div>)
}
});
React.render(
<KomponenHello kepada="Dunia" />,
document.getElementById('mount-point'));
buat komponen baru
render komponen tersebut
<body>
<div id="mount-point"></div>
</body>
Hello Dunia
<html>
<head>
<title>Hello World</title>
<!-- include react -->
<script src="build/react.js"></script>
<!-- diperlukan untuk bisa merender komponen mirip menulis HTML -->
<script src="build/JSXTransformer.js"></script>
</head>
<body>
<div id="mount-point"></div>
</body>
</html>
buat index.html
langkah
<script type="text/jsx">
// buat komponen
var Salam = React.createClass({
render: function(){
return (
<span>
{this.props.ucapan}
<b>{this.props.kepada}</b>
</span>
);
}
});
// render
React.render(<Salam ucapan="Selamat Pagi" kepada="Azam"/>,
document.getElementById('mount-point'));
</script>
langkah
<script type="text/jsx">
// buat komponen
var Salam = React.createClass({
handleClick: function(){
alert('baru saja diklik');
},
render: function(){
return (
<span>
{this.props.ucapan}
<b onClick={this.handleClick}>{this.props.kepada}</b>
</span>
);
}
});
// render
React.render(<Salam ucapan="Selamat Pagi" kepada="Azam"/>,
document.getElementById('mount-point'));
</script>
langkah
<script type="text/jsx">
// buat komponen
var Salam = React.createClass({
getInitialState: function(){
return {
background: '#fff'
}
},
handleClick: function(){
this.setState({background: '#0f0'})
},
render: function(){
return (
<span style={{background: this.state.background}}>
{this.props.ucapan}
<b onClick={this.handleClick}> {this.props.kepada}</b>
</span>
);
}
});
// render
React.render(<Salam ucapan="Selamat Pagi" kepada="Azam"/>,
document.getElementById('mount-point'));
</script>
langkah
...
componentDidMount: function(){
alert('component baru saja dirender');
},
componentWillUnmount: function(){
alert('component akan dihilangkan dari DOM');
}
...
langkah
cd /path/ke/bahan_latihan/helloworld
$ npm install browserify -g
langkah
install tool
langkah
buat index2.html
<html>
<head>
<title>Hello World</title>
</head>
<body>
<div id="mount-point"></div>
<script src="js/bundle.js"></script>
</body>
</html>
langkah
buat folder js, lalu di folder tersebut buat file Salam.react.js
var React = require('react');
var Salam = React.createClass({
getInitialState: function(){
return {
background: '#fff'
}
},
...
render: function(){
return (
<span style={{background: this.state.background}}>
{this.props.ucapan}
<b onClick={this.handleClick}> {this.props.kepada}</b>
</span>
);
}
});
module.exports = Salam;
langkah
buat file app.js pada folder js
var React = require('react');
var Salam = require('./Salam.react');
// render
React.render(<Salam ucapan="Selamat Siang" kepada="Azam"/>,
document.getElementById('mount-point');
langkah
buat bundle.js dengan command browserify
// buka terminal ketik perintah berikut
$ browserify -t reactify js/app.js -o js/bundle.js
Membuat
cd /path/ke/bahan_latihan/todolist
langkah
...
"dependencies": {
"body-parser": "^1.14.1",
"firebase": "^2.3.1",
"express": "^4.13.3",
"cors": "^2.7.1",
"lowdb": "^0.10.2",
"object-assign": "^4.0.1",
"lodash": "^3.10.1",
"jquery": "^2.1.4",
"react": "^0.13.3",
"reactify": "^1.1.1",
"uuid": "^2.0.1"
},
...
langkah
install dependencies
$ npm install
langkah
buat index.html
<html>
<head>
<title>Todo App</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<script src="js/bundle.js"></script>
</body>
</html>
langkah
buat file TodoApp.react.js pada folder js
var React = require('react');
var $ = require('jquery');
var _ = require('lodash');
langkah
buat file TodoApp.react.js pada folder js
var React = require('react');
var $ = require('jquery');
var _ = require('lodash');
var TodoApp = React.createClass({
getInitialState: function(){
return {
todos: []
};
},
clearInput: function(){
this.refs.newTodo.getDOMNode().value = ''; // clear input
},
render: function() {
return (
<div className="todo-container">
<h1>{this.props.title}</h1>
<form>
<input type="text" ref="newTodo" placeholder="Apa yang harus dikerjakan?" />
</form>
</div>
);
}
});
module.exports = TodoApp;
langkah
buat file app.js
var React = require('react');
var TodoApp = require('./TodoApp.react');
React.render(<TodoApp title="My Todo App" />, document.body);
langkah
buat file bundle.js dengan browserify
$ browserify -t reactify js/app.js -o js/bundle.js -v
langkah
update TodoApp.react.js
var React = require('react');
var $ = require('jquery');
var _ = require('lodash');
var Todos = require('./Todos.react');
var TodoApp = React.createClass({
getInitialState: function(){
return {
todos: []
};
},
componentDidMount: function(){
this.getDataFromServer();
},
getDataFromServer: function(){
var component = this;
$.ajax({
method: 'get',
url: 'http://localhost:9000/api/todos',
cache: false,
success: function(data){
component.setState({todos: []});
component.setState({todos: data});
},
error: function(xhr, status, err){
alert(err);
}
});
},
clearInput: function(){
this.refs.newTodo.getDOMNode().value = ''; // clear input
},
render: function() {
return (
<div className="todo-container">
<h1>{this.props.title}</h1>
<form>
<input type="text" ref="newTodo" placeholder="Apa yang harus dikerjakan?" />
</form>
<Todos items={this.state.todos}/>
</div>
);
}
});
module.exports = TodoApp;
langkah
buat file Todos.react.js
var React = require('react');
var PropTypes = React.PropTypes;
var TodoItem = require('./TodoItem.react');
var Todos = React.createClass({
render: function() {
var component = this;
return (
<div>
<ul className="list-item">
{this.props.items.map(function(todo, i){
return (
<TodoItem item={todo} key={i} />
)
})}
</ul>
</div>
);
}
});
module.exports = Todos;
langkah
buat file TodoItem.react.js
var React = require('react');
var PropTypes = React.PropTypes;
var _ = require('lodash');
var TodoItem = React.createClass({
getInitialState: function(){
return {
item: this.props.item
};
},
render: function() {
return (
<div className="item">
<div>
<input
ref="done"
type="checkbox"
/>
<span>{this.state.item.title}</span>
<a className="delete-item">hapus</a>
</div>
</div>
);
}
});
module.exports = TodoItem;
langkah
update file TodoApp.react.js
var React = require('react');
var PropTypes = React.PropTypes;
var $ = require('jquery');
var _ = require('lodash');
var Todos = require('./Todos.react');
var TodoApp = React.createClass({
getInitialState: function(){
return {
todos: []
};
},
componentDidMount: function(){
this.getDataFromServer();
},
getDataFromServer: function(){
var component = this;
$.ajax({
method: 'get',
url: 'http://localhost:9000/api/todos',
cache: false,
success: function(data){
component.setState({todos: []});
component.setState({todos: data});
},
error: function(xhr, status, err){
alert(err);
}
});
},
addItem: function(e){
e.preventDefault();
var component = this;
var value = this.refs.newTodo.getDOMNode().value;
var newTodo = {title: value, done: ""};
$.ajax({
method: 'post',
url: 'http://localhost:9000/api/todos',
data: {item: newTodo},
success: function(){
component.getDataFromServer();
component.clearInput();
},
error: function(xhr, status, err){
alert(status);
}
});
},
clearInput: function(){
this.refs.newTodo.getDOMNode().value = ''; // clear input
},
render: function() {
return (
<div className="todo-container">
<h1>{this.props.title}</h1>
<form onSubmit={this.addItem}>
<input type="text" ref="newTodo" placeholder="Apa yang harus dikerjakan?" />
</form>
<Todos items={this.state.todos}/>
</div>
);
}
});
module.exports = TodoApp;
langkah
update file TodoItem.react.js
var React = require('react');
var PropTypes = React.PropTypes;
var _ = require('lodash');
var TodoItem = React.createClass({
getInitialState: function(){
return {
item: this.props.item
};
},
deleteItem: function(e){
e.preventDefault();
this.props.onDeleteItem(this.state.item);
},
render: function() {
return (
<div className="item">
<div>
<input
ref="done"
type="checkbox"
/>
<span>{this.state.item.title}</span>
<a onClick={this.deleteItem} className="delete-item">hapus</a>
</div>
</div>
);
}
});
module.exports = TodoItem;
langkah
update file Todos.react.js
var React = require('react');
var PropTypes = React.PropTypes;
var TodoItem = require('./TodoItem.react');
var Todos = React.createClass({
deleteItem: function(item){
this.props.onDeleteItem(item);
},
render: function() {
var component = this;
return (
<div>
<ul className="list-item">
{this.props.items.map(function(todo, i){
return (
<TodoItem onDeleteItem={component.deleteItem} item={todo} key={i} />
)
})}
</ul>
</div>
);
}
});
module.exports = Todos;
langkah
update file TodoApp.react.js
var React = require('react');
var PropTypes = React.PropTypes;
var $ = require('jquery');
var _ = require('lodash');
var Todos = require('./Todos.react');
var TodoApp = React.createClass({
getInitialState: function(){
return {
todos: []
};
},
componentDidMount: function(){
this.getDataFromServer();
},
getDataFromServer: function(){
var component = this;
$.ajax({
method: 'get',
url: 'http://localhost:9000/api/todos',
cache: false,
success: function(data){
component.setState({todos: []});
component.setState({todos: data});
},
error: function(xhr, status, err){
alert(err);
}
});
},
addItem: function(e){
e.preventDefault();
var component = this;
var value = this.refs.newTodo.getDOMNode().value;
var newTodo = {title: value, done: ""};
$.ajax({
method: 'post',
url: 'http://localhost:9000/api/todos',
data: {item: newTodo},
success: function(){
component.getDataFromServer();
component.clearInput();
},
error: function(xhr, status, err){
alert(status);
}
});
},
updateItem: function(item){
var component = this;
$.ajax({
method: 'post',
url: 'http://localhost:9000/api/todos/'+item.id,
data: {
updatedItem: item
},
success: function(){
component.getDataFromServer();
},
error: function(xhr, status, err){
alert(status);
}
});
},
deleteItem: function(item){
var component = this;
$.ajax({
method: 'delete',
url: 'http://localhost:9000/api/todos/'+item.id,
success: function(){
component.getDataFromServer();
},
error: function(){
alert('gagal menghapus data');
}
});
},
clearInput: function(){
this.refs.newTodo.getDOMNode().value = ''; // clear input
},
render: function() {
return (
<div className="todo-container">
<h1>{this.props.title}</h1>
<form onSubmit={this.addItem}>
<input type="text" ref="newTodo" placeholder="Apa yang harus dikerjakan?" />
</form>
<Todos
onDeleteItem={this.deleteItem}
items={this.state.todos}/>
</div>
);
}
});
module.exports = TodoApp;
langkah
update file TodoItem.react.js
var React = require('react');
var PropTypes = React.PropTypes;
var _ = require('lodash');
var TodoItem = React.createClass({
getInitialState: function(){
return {
item: this.props.item,
isEditing: false
};
},
toggleDone: function(e){
var todoDone;
if(Boolean(this.state.item.done)){
todoDone = "";
} else {
todoDone = "yes";
}
this.setState({
item: _.merge(this.state.item, {done: todoDone})
}, this.props.onUpdateItem(this.state.item));
},
deleteItem: function(e){
this.props.onDeleteItem(this.state.item);
},
render: function() {
return (
<div className="item">
<div>
<input
ref="done"
type="checkbox"
checked={Boolean(this.state.item.done)}
onChange={this.toggleDone}
/>
<span className={this.state.item.done ? 'done' : 'not'}>{this.state.item.title}</span>
<a onClick={this.deleteItem} className="delete-item">hapus</a>
</div>
</div>
);
}
});
module.exports = TodoItem;
langkah
update file Todos.react.js
var React = require('react');
var PropTypes = React.PropTypes;
var TodoItem = require('./TodoItem.react');
var Todos = React.createClass({
updateItem: function(item){
this.props.onUpdateItem(item); // kirim lagi ke parent
},
deleteItem: function(item){
this.props.onDeleteItem(item); // kirim lagi ke parent
},
render: function() {
var component = this;
return (
<div>
<ul className="list-item">
{this.props.items.map(function(todo, i){
return (
<TodoItem
item={todo}
onUpdateItem={component.updateItem}
onDeleteItem={component.deleteItem}
key={i}
/>
)
})}
</ul>
</div>
);
}
});
module.exports = Todos;
langkah
update file TodoApp.react.js
var React = require('react');
var PropTypes = React.PropTypes;
var $ = require('jquery');
var _ = require('lodash');
var Todos = require('./Todos.react');
var TodoApp = React.createClass({
getInitialState: function(){
return {
todos: []
};
},
componentDidMount: function(){
this.getDataFromServer();
},
getDataFromServer: function(){
var component = this;
$.ajax({
method: 'get',
url: 'http://localhost:9000/api/todos',
cache: false,
success: function(data){
component.setState({todos: []});
component.setState({todos: data});
},
error: function(xhr, status, err){
alert(err);
}
});
},
addItem: function(e){
e.preventDefault();
var component = this;
var value = this.refs.newTodo.getDOMNode().value;
var newTodo = {title: value, done: ""};
$.ajax({
method: 'post',
url: 'http://localhost:9000/api/todos',
data: {item: newTodo},
success: function(){
component.getDataFromServer();
component.clearInput();
},
error: function(xhr, status, err){
alert(status);
}
});
},
updateItem: function(item){
var component = this;
$.ajax({
method: 'post',
url: 'http://localhost:9000/api/todos/'+item.id,
data: {
updatedItem: item
},
success: function(){
component.getDataFromServer();
},
error: function(xhr, status, err){
alert(status);
}
});
},
deleteItem: function(item){
var component = this;
$.ajax({
method: 'delete',
url: 'http://localhost:9000/api/todos/'+item.id,
success: function(){
component.getDataFromServer();
},
error: function(){
alert('gagal menghapus data');
}
});
},
clearInput: function(){
this.refs.newTodo.getDOMNode().value = ''; // clear input
},
render: function() {
return (
<div className="todo-container">
<h1>{this.props.title}</h1>
<form onSubmit={this.addItem}>
<input type="text" ref="newTodo" placeholder="Apa yang harus dikerjakan?" />
</form>
<Todos
onUpdateItem={this.updateItem}
onDeleteItem={this.deleteItem}
items={this.state.todos}/>
</div>
);
}
});
module.exports = TodoApp;
apa yang baru saja kita pelajari?
apa yang baru saja kita pelajari?
langkah
update file TodoItem.react.js
var React = require('react');
var PropTypes = React.PropTypes;
var _ = require('lodash');
var TodoItem = React.createClass({
getInitialState: function(){
return {
item: this.props.item,
isEditing: false
};
},
toggleDone: function(e){
var todoDone;
if(Boolean(this.state.item.done)){
todoDone = "";
} else {
todoDone = "yes";
}
this.setState({
item: _.merge(this.state.item, {done: todoDone})
}, this.props.onUpdateItem(this.state.item));
},
deleteItem: function(e){
this.props.onDeleteItem(this.state.item);
},
editItem: function(e){
this.setState({
isEditing: true
});
},
handleTitleChange: function(){
var newTitle = this.refs.title.getDOMNode().value;
this.setState({
item: _.merge(this.state.item, {title: newTitle})
});
},
updateItem: function(e){
e.preventDefault();
this.props.onUpdateItem(this.state.item);
},
render: function() {
return (
<div className="item" onDoubleClick={this.editItem}>
<div style={{display: this.state.isEditing ? 'none' : 'block'}}>
<input
ref="done"
type="checkbox"
checked={Boolean(this.state.item.done)}
onChange={this.toggleDone}
/>
<span className={this.state.item.done ? 'done' : 'not'}>{this.state.item.title}</span>
<a onClick={this.deleteItem} className="delete-item">hapus</a>
</div>
<div style={{display: this.state.isEditing ? 'block': 'none'}}>
<form onSubmit={this.updateItem}>
<input type="text" value={this.state.item.title} ref="title" onChange={this.handleTitleChange}/>
</form>
</div>
</div>
);
}
});
module.exports = TodoItem;
langkah
update file Todos.react.js
var React = require('react');
var PropTypes = React.PropTypes;
var TodoItem = require('./TodoItem.react');
var Todos = React.createClass({
updateItem: function(item){
this.props.onUpdateItem(item); // kirim lagi ke parent
},
deleteItem: function(item){
this.props.onDeleteItem(item); // kirim lagi ke parent
},
render: function() {
var component = this;
return (
<div>
<ul className="list-item">
{this.props.items.map(function(todo, i){
return (
<TodoItem
item={todo}
onUpdateItem={component.updateItem}
onDeleteItem={component.deleteItem}
key={i}
/>
)
})}
</ul>
</div>
);
}
});
module.exports = Todos;
langkah
update file TodoApp.react.js
var React = require('react');
var PropTypes = React.PropTypes;
var $ = require('jquery');
var _ = require('lodash');
var Todos = require('./Todos.react');
var TodoApp = React.createClass({
getInitialState: function(){
return {
todos: []
};
},
componentDidMount: function(){
this.getDataFromServer();
},
getDataFromServer: function(){
var component = this;
$.ajax({
method: 'get',
url: 'http://localhost:9000/api/todos',
cache: false,
success: function(data){
component.setState({todos: []});
component.setState({todos: data});
},
error: function(xhr, status, err){
alert(err);
}
});
},
addItem: function(e){
e.preventDefault();
var component = this;
var value = this.refs.newTodo.getDOMNode().value;
var newTodo = {title: value, done: ""};
$.ajax({
method: 'post',
url: 'http://localhost:9000/api/todos',
data: {item: newTodo},
success: function(){
component.getDataFromServer();
component.clearInput();
},
error: function(xhr, status, err){
alert(status);
}
});
},
updateItem: function(item){
var component = this;
$.ajax({
method: 'post',
url: 'http://localhost:9000/api/todos/'+item.id,
data: {
updatedItem: item
},
success: function(){
component.getDataFromServer();
},
error: function(xhr, status, err){
alert(status);
}
});
},
deleteItem: function(item){
var component = this;
$.ajax({
method: 'delete',
url: 'http://localhost:9000/api/todos/'+item.id,
success: function(){
component.getDataFromServer();
},
error: function(){
alert('gagal menghapus data');
}
});
},
clearInput: function(){
this.refs.newTodo.getDOMNode().value = ''; // clear input
},
render: function() {
return (
<div className="todo-container">
<h1>{this.props.title}</h1>
<form onSubmit={this.addItem}>
<input type="text" ref="newTodo" placeholder="Apa yang harus dikerjakan?" />
</form>
<Todos
onUpdateItem={this.updateItem}
onDeleteItem={this.deleteItem}
items={this.state.todos}/>
</div>
);
}
});
module.exports = TodoApp;
langkah
update file TodoApp.react.js
var React = require('react');
var PropTypes = React.PropTypes;
var $ = require('jquery');
var _ = require('lodash');
var Todos = require('./Todos.react');
var TodoCounter = require('./TodoCounter.react');
var TodoApp = React.createClass({
getInitialState: function(){
return {
todos: []
};
},
componentDidMount: function(){
this.getDataFromServer();
},
getDataFromServer: function(){
var component = this;
$.ajax({
method: 'get',
url: 'http://localhost:9000/api/todos',
cache: false,
success: function(data){
component.setState({todos: []});
component.setState({todos: data});
},
error: function(xhr, status, err){
alert(err);
}
});
},
addItem: function(e){
e.preventDefault();
var component = this;
var value = this.refs.newTodo.getDOMNode().value;
var newTodo = {title: value, done: ""};
$.ajax({
method: 'post',
url: 'http://localhost:9000/api/todos',
data: {item: newTodo},
success: function(){
component.getDataFromServer();
component.clearInput();
},
error: function(xhr, status, err){
alert(status);
}
});
},
updateItem: function(item){
var component = this;
$.ajax({
method: 'post',
url: 'http://localhost:9000/api/todos/'+item.id,
data: {
updatedItem: item
},
success: function(){
component.getDataFromServer();
},
error: function(xhr, status, err){
alert(status);
}
});
},
deleteItem: function(item){
var component = this;
$.ajax({
method: 'delete',
url: 'http://localhost:9000/api/todos/'+item.id,
success: function(){
component.getDataFromServer();
},
error: function(){
alert('gagal menghapus data');
}
});
},
clearInput: function(){
this.refs.newTodo.getDOMNode().value = ''; // clear input
},
render: function() {
return (
<div className="todo-container">
<h1>{this.props.title}</h1>
<form onSubmit={this.addItem}>
<input type="text" ref="newTodo" placeholder="Apa yang harus dikerjakan?" />
</form>
<Todos
onUpdateItem={this.updateItem}
onDeleteItem={this.deleteItem}
items={this.state.todos}/>
<TodoCounter
all={this.state.todos.length}
done={_.where(this.state.todos, {done: 'yes'}).length}
notdone={_.where(this.state.todos, {done: ''}).length}
/>
</div>
);
}
});
module.exports = TodoApp;
langkah
buat TodoCounter.react.js pada folder js
var React = require('react');
var TodoCounter = React.createClass({
filter: function(status){
this.props.onFilter(status);
},
render: function() {
return (
<div className="counter">
<span>semua ({this.props.all}) </span>
<span>selesai ({this.props.done}) </span>
<span>belum selesai ({this.props.notdone}) </span>
</div>
);
}
});
module.exports = TodoCounter;
<html>
<head>
<title>Todo App</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<script src="js/bundle.js"></script>
</body>
</html>
langkah
buat index.html