Dataset/JS/ToDoApp_ReactJS/todoItem.tsx (80 lines of code) (raw):

import * as classNames from "classnames"; import * as React from "react"; import * as ReactDOM from "react-dom"; import { ENTER_KEY, ESCAPE_KEY } from "./constants"; class TodoItem extends React.Component<ITodoItemProps, ITodoItemState> { public state : ITodoItemState; constructor(props : ITodoItemProps){ super(props); this.state = { editText: this.props.todo.title }; } public handleSubmit(event : React.FormEvent) { var val = this.state.editText.trim(); if (val) { this.props.onSave(val); this.setState({editText: val}); } else { this.props.onDestroy(); } } public handleEdit() { this.props.onEdit(); this.setState({editText: this.props.todo.title}); } public handleKeyDown(event : React.KeyboardEvent) { if (event.keyCode === ESCAPE_KEY) { this.setState({editText: this.props.todo.title}); this.props.onCancel(event); } else if (event.keyCode === ENTER_KEY) { this.handleSubmit(event); } } public handleChange(event : React.FormEvent) { var input : any = event.target; this.setState({ editText : input.value }); } /** * This is a completely optional performance enhancement that you can * implement on any React component. If you were to delete this method * the app would still work correctly (and still be very performant!), we * just use it as an example of how little code it takes to get an order * of magnitude performance improvement. */ public shouldComponentUpdate(nextProps : ITodoItemProps, nextState : ITodoItemState) { return ( nextProps.todo !== this.props.todo || nextProps.editing !== this.props.editing || nextState.editText !== this.state.editText ); } /** * Safely manipulate the DOM after updating the state when invoking * `this.props.onEdit()` in the `handleEdit` method above. * For more info refer to notes at https://facebook.github.io/react/docs/component-api.html#setstate * and https://facebook.github.io/react/docs/component-specs.html#updating-componentdidupdate */ public componentDidUpdate(prevProps : ITodoItemProps) { if (!prevProps.editing && this.props.editing) { var node = (ReactDOM.findDOMNode(this.refs["editField"]) as HTMLInputElement); node.focus(); node.setSelectionRange(node.value.length, node.value.length); } } public render() { return ( <li className={classNames({ completed: this.props.todo.completed, editing: this.props.editing })}> <div className="view"> <input className="toggle" type="checkbox" checked={this.props.todo.completed} onChange={this.props.onToggle} /> <label onDoubleClick={ e => this.handleEdit() }> {this.props.todo.title} </label> <button className="destroy" onClick={this.props.onDestroy} /> </div> <input ref="editField" className="edit" value={this.state.editText} onBlur={ e => this.handleSubmit(e) } onChange={ e => this.handleChange(e) } onKeyDown={ e => this.handleKeyDown(e) } /> </li> ); } } export { TodoItem };