I am trying to learn react and functional programming by trying to implement a simple todo app. I am not using flux as I am just trying to see the concepts of passing information between parent and children. I am trying to trigger a function in the parent on a click event in the child. However, I get a very nasty error from React about using pure functions and state. Can someone explain what I am doing wrong and what may be the right way of doing things? What is impure about my functions, I don't see the side-effects I am creating. Here is my code:
var React = require('react');
var Todo = require('./Todo');
const todos = [ {task: "Eat", completed: false},
{task: "Breathe", completed: false},
{task: "Sleep", completed: false}];
var TodoList = React.createClass({
getInitialState: function() {
return {todos: todos};
},
changeTodoStatus (task) {
var updatedTodos = this.state.todos.map(function(todo){
if (task.task === todo.task) {
return {task: todo.task, completed: !todo.completed};
} else {
return todo;
}
});
this.setState({todos: updatedTodos});
},
render: function() {
var _that = this;
return(
<div className="container">
<div className="row list-of-things">
<ul className="list-group">
{
this.state.todos.map( (todo, index) => {
return (<Todo clickHandler={ this.changeTodoStatus } key={index} todo={todo} />);
})
}
</ul>
</div>
</div>
);
}
});
module.exports = TodoList;
var Todo = React.createClass({
handleClick( todo ){
this.props.clickHandler( todo );
},
render: function() {
if( this.props.todo.completed === true){
return ( <li onClick={ this.handleClick(this.props.todo.task) } className="list-group-item list-group-item-success"><strike>{this.props.todo.task}</strike></li> );
} else {
return ( <li onClick={ this.handleClick(this.props.todo.task) } className="list-group-item"> {this.props.todo.task} </li> );
}
}
});
module.exports = Todo;
Any help/clarification is greatly appreciated!
This is the error: bundle.js:9139 Warning: setState(...): Cannot update during an existing state transition (such as within render
or another component's constructor). Render methods should be a pure function of props and state; constructor side-effects are an anti-pattern, but can be moved to componentWillMount
.