ReactJS

Javascript library for building user interfaces

http://slides.com/muhammadazamuddin/reactjs-meetup

https://github.com/azamuddin/meetup-helloworld

slides

bahan

https://github.com/azamuddin/meetup-todolist

joind3t1k

Guest_Detik

created by

FACEBOOK

MVC

bukan

Kenapa React?

Sederhana

Virtual DOM

Component

Component

<LineChart data={chartData} options={chartOptions} width="600" height="250"/>

Component

Component

Component

React Native

Kapan React Diperlukan?

Membuat Komponen

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

Properti Komponen

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

Latihan Membuat Komponen

<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

1

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>

2

langkah

Latihan Membuat Komponen


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

3

langkah

Latihan Event Handling Komponen

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

4

langkah

Latihan State Komponen

    ...
    componentDidMount: function(){
        alert('component baru saja dirender');
    },
    componentWillUnmount: function(){
        alert('component akan dihilangkan dari DOM');
    }
    ...

5

langkah

Latihan Siklus Komponen

cd /path/ke/bahan_latihan/helloworld

persiapkan terminal / command prompt

$ npm install browserify -g 

1

langkah

Latihan Browserify

install tool

2

langkah

Latihan Browserify

buat index2.html
<html>
  <head>
    <title>Hello World</title>
  </head>
  <body>
     <div id="mount-point"></div>
     <script src="js/bundle.js"></script>
  </body>
</html>

3

langkah

Latihan Browserify

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;

4

langkah

Latihan Browserify

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');

5

langkah

Latihan Browserify

buat bundle.js dengan command browserify
// buka terminal ketik perintah berikut

$ browserify -t reactify js/app.js -o js/bundle.js

TODOLIST APP

Membuat

cd /path/ke/bahan_latihan/todolist

persiapkan terminal / command prompt

1

langkah

package.json


...

  "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"
  },

...

2

langkah

membuat Todolist App

install dependencies
$ npm install

3

langkah

membuat Todolist App

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>

4

langkah

membuat Todolist App

buat file TodoApp.react.js pada folder js
var React = require('react');
var $ = require('jquery');
var _ = require('lodash');

5

langkah

membuat Todolist App

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;

6

langkah

membuat Todolist App

buat file app.js
var React = require('react');
var TodoApp = require('./TodoApp.react');

React.render(<TodoApp title="My Todo App" />, document.body);

7

langkah

membuat Todolist App

buat file bundle.js dengan browserify
$ browserify -t reactify js/app.js -o js/bundle.js -v

Menampilkan TodoItem

8

langkah

membuat Todolist App

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;

8

langkah

membuat Todolist App

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;

9

langkah

membuat Todolist App

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;

Menambah TodoItem

10

langkah

membuat Todolist App

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;

Menghapus TodoItem

11

langkah

membuat Todolist App

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;

12

langkah

membuat Todolist App

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;

13

langkah

membuat Todolist App

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;

Toggle Selesai

14

langkah

membuat Todolist App

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;

15

langkah

membuat Todolist App

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;

16

langkah

membuat Todolist App

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;

BERHENTI SEJENAK

apa yang baru saja kita pelajari?

BERHENTI SEJENAK

apa yang baru saja kita pelajari?
  • Component is composable
  • Uni-directional data flow
  • Data mengalir dari komponen paling atas terus ke bawah melalui props
  • Event naik ke atas dari komponen di bawah ke komponen paling atas
  • Perubahan state menyebabkan komponen dirender ulang dengan data terupdate

Edit TodoItem

17

langkah

membuat Todolist App

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;

18

langkah

membuat Todolist App

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;

19

langkah

membuat Todolist App

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;

Todo Counter

20

langkah

membuat Todolist App

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;

21

langkah

membuat Todolist App

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>

1

langkah

buat index.html
Made with Slides.com