I've written a to-do list app in React, as I am a beginner and this is my first app, I feel it can be improved. Some assistance in improving it, and how or why improvements are better would be much appreciated.
Here is a working demo of it.
var ToDoContainer = React.createClass({
getInitialState: function(){
var tasks = [
{task:"Go to the gym", completed:false, id:1 },
{task:"Do yoga", completed:false, id:2 },
{task:"Buy groceries", completed:true, id:3 },
{task:"Get tire fixed", completed:true, id:4}
];
return {
tasks:tasks,
numCompleted:null
}
},
addTask: function(task){
this.setState({
tasks:this.state.tasks.concat(task)
});
},
clearComplete: function(){
var remainingTasks = this.state.tasks.filter(function(task){
if (!task.completed) return task;
});
this.setState({
tasks:remainingTasks
});
},
markComplete: function(e){
console.log('markComplete')
var id = e.target.getAttribute('data-id');
var tempTasks = this.state.tasks;
tempTasks.forEach(function(task){
if (id == task.id) {
if (task.completed){
task.completed = false;
}
else if (!task.completed) {
task.completed = true;
}
}
})
this.setState({
tasks:tempTasks
});
},
render: function(){
var numCompleted = this.state.tasks.filter(function(task){
return task.completed;
}).length
var numRemaining = this.state.tasks.filter(function(task){
return !task.completed;
}).length
return (
<div className="rowFluid">
<div className="well row col-md-4 col-md-offset-4">
<h3 className="text-left">You have {numRemaining} tasks to do:</h3>
<TaskList tasks={this.state.tasks} check={this.markComplete} />
<AddTask addNew={this.addTask} />
<ClearTask clear={this.clearComplete} numCompleted={numCompleted}/>
</div>
</div>
)
}
});
var TaskList = React.createClass({
handleCheck: function(e){
console.log('handleCheck')
this.props.check(e);
},
getInitialState: function(){
return {
data:this.props.tasks
}
},
render: function(){
var that = this;
var task = this.props.tasks.map(function(task, index){
return <li key={index} className={task.completed ? "complete" : "incomplete"} >
<input type="checkbox" checked={task.completed} onChange={that.handleCheck} data-id={task.id}/>
{task.task}
</li>
});
return (
<div>
<ul className="list-unstyled">
{task}
</ul>
</div>
)
}
});
var AddTask = React.createClass({
getInitialState: function(){
return{
newTask:""
}
},
handleChange: function(e){
this.setState({
newTask:e.target.value
});
},
handleSubmit: function(e){
e.preventDefault();
this.props.addNew({task:this.state.newTask, completed:false, id:Date.now()});
this.setState({
newTask:""
});
},
render: function(){
var inputStyle = {
marginRight: "10px"
}
return (
<div className="text-left">
<form onSubmit={this.handleSubmit}>
<input type="text" value={this.state.newTask} onChange={this.handleChange} style={inputStyle}/>
<input type="submit" value="Add Task" disabled={this.state.newTask == ""} />
</form>
</div>
)
}
});
var ClearTask = React.createClass({
clear: function(){
this.props.clear();
},
render: function(){
var buttonStyle = {
marginTop: "10px"
}
return (
<button onClick={this.clear} value="Clear Completed" clear={this.clearComplete} disabled={this.props.numCompleted==0} className="text-center" style={buttonStyle}>Clear Completed</button>
)
}
})
ReactDOM.render(<ToDoContainer />, document.getElementById('app'));