let ID = 0; // incrementing counter for todo item ids const AddTaskForm = React.createClass({ mixins: [React.addons.LinkedStateMixin, React.addons.PureRenderMixin], getInitialState() { return { text: '', }; }, addTask(e) { e.preventDefault(); this.props.addTask(this.state.text); this.setState({text: ''}); }, render() { return ( <form onSubmit={this.addTask}> <input valueLink={this.linkState('text')} /> <button>Add Task</button> </form> ); } }); const TodoItems = React.createClass({ mixins: [React.addons.PureRenderMixin], render() { return ( <div> {this.props.items.map((item) => { return ( <TodoItem key={item.id} item={item} tags={Todos.tags} deleteItem={this.props.deleteItem} /> ); })} </div> ); } }); const TodoItem = React.createClass({ mixins: [React.addons.PureRenderMixin], propTypes: { deleteItem: React.PropTypes.func.isRequired, tags: React.PropTypes.arrayOf(React.PropTypes.string.isRequired).isRequired, item: React.PropTypes.shape({ text: React.PropTypes.string.isRequired, id: React.PropTypes.number.isRequired, }).isRequired, }, deleteItem() { this.props.deleteItem(this.props.item.id); }, render() { return ( <div> <button style={{width: 30}} onClick={this.deleteItem}>x</button> <span>{this.props.item.text}</span> {this.props.tags.map((tag) => { return <span key={tag} className="tag"> {tag}</span>; })} </div> ); }, }); const Todos = React.createClass({ statics: { tags: ['important', 'starred'], }, propTypes: { initialItems: React.PropTypes.arrayOf(React.PropTypes.shape({ text: React.PropTypes.string.isRequired, id: React.PropTypes.number.isRequired, }).isRequired).isRequired, }, getInitialState() { return { items: this.props.initialItems, }; }, addTask(text) { this.setState({ items: [{id: ID++, text}].concat(this.state.items), }); }, deleteItem(itemId) { this.setState({ items: this.state.items.filter((item) => item.id !== itemId), }); }, render: function() { return ( <div> <h1>My TODOs</h1> <AddTaskForm addTask={this.addTask} /> <TodoItems items={this.state.items} deleteItem={this.deleteItem} /> </div> ); }, }); // Create a Todos component, initialized with 1000 items. const items = []; for (let i = 0; i < 1000; i++) { items.push({id: ID++, text: 'Todo Item #' + i}); } React.render(<Todos initialItems={items} />, document.body);