let ID = 0; // incrementing counter for todo item ids const TodoWarning = React.createClass({ propTypes: { itemCount: React.PropTypes.number.isRequired }, render() { if (this.props.itemCount > 3000) { return <div>'YOU HAVE TOO MANY TASKS. SLOW DOWN.'</div>; } return null; } }); const TodoItems = React.createClass({ mixins: [React.addons.PureRenderMixin], render() { return ( <div className="todoItems"> {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({ mixins: [React.addons.LinkedStateMixin], 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, text: '', }; }, addTask(e) { e.preventDefault(); this.setState({ items: [{id: ID++, text: this.state.text}].concat(this.state.items), text: '', }); }, deleteItem(itemId) { this.setState({ items: this.state.items.filter((item) => item.id !== itemId), }); }, render: function() { return ( <div> <TodoWarning itemCount={this.state.items.length} /> <h1>My TODOs</h1> <form onSubmit={this.addTask}> <input valueLink={this.linkState('text')} /> <button>Add Task</button> </form> <TodoItems items={this.state.items} deleteItem={this.deleteItem} /> </div> ); }, }); // Create a Todos component, initialized with 1000 items. const items = []; for (let i = 0; i < 3000; i++) { items.push({id: ID++, text: 'Todo Item #' + i}); } React.render(<Todos initialItems={items} />, document.body);
div:nth-child(even) { background-color: gray; } div.todoItems { background-color: white; }