I have a working useless todo app created with ReactJS. I'm just wondering if my code can be improved.
This app can add a todo item and it can display editable list of todo items.
This is my ReactJS code.
var TodoApp = React.createClass({
getInitialState: function() {
return {items: []};
},
addItem: function(item) {
var allItems = this.state.items.concat([item]);
this.updateItems(allItems);
},
editItem: function(editedItem) {
var allItems = this.state.items.map(function(item) {
if (item.id !== editedItem.id) {
return item;
}
return editedItem;
});
this.updateItems(allItems);
},
updateItems: function(items) {
this.setState({items: items});
},
render: function() {
return (
<div className="todo-app">
<TodoForm onFormSubmit={this.addItem}/>
<TodoList items={this.state.items} onItemEdit={this.editItem}/>
</div>
);
}
});
var TodoForm = React.createClass({
getInitialState: function() {
return {item: {id: 0, title: '', description: ''}};
},
render: function() {
return (
<form onSubmit={this.handleSubmit}>
<input type="hidden" ref="id" value={this.state.item.id} onChange={this.handleUserInput}/>
<input type="text" ref="title" value={this.state.item.title} onChange={this.handleUserInput}/>
<input type="text" ref="description" value={this.state.item.description} onChange={this.handleUserInput}/>
<input type="submit" value="Add"/>
</form>
);
},
handleSubmit: function(e) {
e.preventDefault();
this.props.onFormSubmit(this.state.item);
this.setState({item: {id: 0, title: '', description: '', done: false}});
},
handleUserInput: function() {
this.setState({item: {
id: this.refs.id.value,
title: this.refs.title.value,
description: this.refs.description.value,
done: false
}});
}
});
var TodoList = React.createClass({
render: function() {
var component = this;
var itemNodes = this.props.items.map(function(item) {
return <TodoListItem key={item.title} item={item} onFormSubmit={component.props.onItemEdit}/>
});
return (
<ul>{itemNodes}</ul>
);
}
});
var TodoListItem = React.createClass({
getInitialState: function() {
return {
id: this.props.item.id,
done: this.props.item.done,
title: this.props.item.title,
description: this.props.item.description,
};
},
render: function() {
return (
<li>
<form onSubmit={this.handleFormSubmit}>
<input type="hidden" ref="id" value={this.state.id}/>
<input type="checkbox" ref="done" value={this.state.done} onChange={this.handleUserInput}/>
<input type="text" ref="title" value={this.state.title} onChange={this.handleUserInput}/>
<input type="text" ref="description" value={this.state.description} onChange={this.handleUserInput}/>
<input type="submit" value="Save"/>
</form>
</li>
);
},
handleUserInput: function() {
this.setState({
id: this.refs.id.value,
done: this.refs.done.checked,
title: this.refs.title.value,
description: this.refs.description.value
});
},
handleFormSubmit: function(e) {
e.preventDefault();
this.props.onFormSubmit(this.state);
}
});
ReactDOM.render(<TodoApp/>, document.getElementById('todoListBox'));
ReactJS said in their docs that components should be stateless as possible.
I'm aware that in the TodoListItem
component, It has a state
based from its props
. I did that so I can change the form inside TodoListItem
.
Is there any other possible solutions to do this other than their two way binding add-on?