反应,纯函数警告?
React, pure function warning?
我正在尝试通过尝试实现一个简单的待办事项应用程序来学习反应和函数式编程。我没有使用 flux,因为我只是想了解在父子之间传递信息的概念。我正在尝试在子项中的单击事件中触发父项中的函数。但是,我从 React 那里得到了一个关于使用纯函数和状态的非常讨厌的错误。有人可以解释我做错了什么以及正确的做事方式是什么吗?我的功能有什么不纯之处,我看不到我正在创建的副作用。这是我的代码:
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;
非常感谢help/clarification!
这是错误:bundle.js:9139 警告:setState(...):无法在现有状态转换期间更新(例如在 render
或其他组件的构造函数中)。渲染方法应该是 props 和 state 的纯函数;构造函数副作用是一种反模式,但可以移至 componentWillMount
.
在你的待办事项的 onclick 处理程序中,你实际上是在调用这些函数而不是引用。我要做的是在你的 Todo 组件中:
handleClick() {
this.props.clickHandler( this.props.todo );
{
然后在你的渲染中做
render: function() {
if( this.props.todo.completed === true){
return ( <li onClick={ this.handleClick } className="list-group-item list-group-item-success"><strike>{this.props.todo.task}</strike></li> );
} else {
return ( <li onClick={ this.handleClick } className="list-group-item"> {this.props.todo.task} </li> );
}
}
你现在拥有它的方式实际上是在调用 this.handleClick(this.props.todo)
所以一旦组件呈现它就会调用该函数,该函数在父组件中立即设置状态,这与反应模式 AKA 你不t 在渲染方法中设置状态
finalfreq
给出的答案
您还必须将函数与 this
绑定
<li onClick={ this.handleClick.bind(this) }
抱歉,我没有 50 的声誉来发表评论。所以写在这里
我正在尝试通过尝试实现一个简单的待办事项应用程序来学习反应和函数式编程。我没有使用 flux,因为我只是想了解在父子之间传递信息的概念。我正在尝试在子项中的单击事件中触发父项中的函数。但是,我从 React 那里得到了一个关于使用纯函数和状态的非常讨厌的错误。有人可以解释我做错了什么以及正确的做事方式是什么吗?我的功能有什么不纯之处,我看不到我正在创建的副作用。这是我的代码:
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;
非常感谢help/clarification!
这是错误:bundle.js:9139 警告:setState(...):无法在现有状态转换期间更新(例如在 render
或其他组件的构造函数中)。渲染方法应该是 props 和 state 的纯函数;构造函数副作用是一种反模式,但可以移至 componentWillMount
.
在你的待办事项的 onclick 处理程序中,你实际上是在调用这些函数而不是引用。我要做的是在你的 Todo 组件中:
handleClick() {
this.props.clickHandler( this.props.todo );
{
然后在你的渲染中做
render: function() {
if( this.props.todo.completed === true){
return ( <li onClick={ this.handleClick } className="list-group-item list-group-item-success"><strike>{this.props.todo.task}</strike></li> );
} else {
return ( <li onClick={ this.handleClick } className="list-group-item"> {this.props.todo.task} </li> );
}
}
你现在拥有它的方式实际上是在调用 this.handleClick(this.props.todo)
所以一旦组件呈现它就会调用该函数,该函数在父组件中立即设置状态,这与反应模式 AKA 你不t 在渲染方法中设置状态
finalfreq
您还必须将函数与 this
<li onClick={ this.handleClick.bind(this) }
抱歉,我没有 50 的声誉来发表评论。所以写在这里