Reputation: 285
I am trying to count done tasks. I am fetching whole data because I am also rendering it. After componentDidMount I have all data stored in state object like so:
The componentDidMount looks like this:
componentDidMount () {
const dataGoalRef = dbRef.child('goals/'+this.state.uid+'/'+this.state.currentGoalId);
dataGoalRef.on('value', snap => {
this.setState({
dataGoal: snap.val(),
currentGoalId: this.props.match.params.goalId,
});
});
}
I am already counting the tasks with {this.state.allTasksCount++}
but it fires every time component gets rendered it.
render() {
return(
<div>
<main className="content">
<p>{this.state.dataGoal.description}</p><br /><br />
{ this.state.dataGoal.milestones &&
Object.keys(this.state.dataGoal.milestones).map( (milestoneKey) => {
const milestonesData = this.state.dataGoal.milestones[milestoneKey];
console.log(this.doneTasksFromDataGoal());
return <div className="milestone-wrap" key={milestoneKey}>
<label className="milestone-label truncate">{milestonesData.name}</label>
{Object.keys(milestonesData.tasks)
.filter( (taskKey, index) => {
{this.state.allTasksCount++}
return milestonesData.tasks[taskKey].done === false;
})
.map( (taskKey) => {
{this.state.todoTasksCount++}
return <div className="task clearfix" key={taskKey}>
<input
className="checkbox-rounded"
name="done"
type="checkbox"
checked={milestonesData.tasks[taskKey].done}
onChange={(e) => this.handleInputChange(e, milestoneKey, taskKey)} />
<div className="task-content">
<p className="task-name truncate">{milestonesData.tasks[taskKey].name}</p>
<p className="task-date">{milestonesData.tasks[taskKey].finishDate}</p>
</div>
</div>
})}
</div>
})}
</main>
</div>
);
}
What is the best way to get the number of done or not done tasks and keep it in state?
Upvotes: 2
Views: 1114
Reputation: 3121
Here is a really verbose solution to iterate the milestones and tasks and increment a counter inside of the render()
function:
render() {
var doneCount = 0;
var milestones = this.state.dataGoal.milestones;
Object.keys(milestones).forEach(function(milestoneKey) {
Object.keys(milestones[milestoneKey].tasks).forEach(function(taskKey) {
if (milestones[milestoneKey].tasks[taskKey].done) {
doneCount += 1;
}
});
});
return (
<div>Done: {doneCount}</div>
);
}
Upvotes: 1
Reputation: 131
Try componentWillRecieveProps. It will be called whenever props are changed after mounting has been completed. Also here you can compare previous and next props. And this is the preferred place to call setState, by using which you can update done counter.
Please comment if you need detailed explanation.
Upvotes: 0