我正在学习 React 并且为了接受培训,我想创建一个基本的 Todo 应用程序。第一步,我想创建一个名为 AddTodo 的组件,它呈现一个输入字段和一个按钮,每次我在输入字段中输入内容并按下按钮时,我想将输入字段的值传递给另一个名为TodoList 并将其附加到列表中。
问题是当我启动应用程序时,AddTodo 组件成功呈现,但是当我输入内容并按下按钮时,应用程序停止响应 2 秒,之后,我得到这个:Uncaught RangeError: Maximum call超出堆栈大小
,但没有任何反应。
我的应用程序源代码:Main.jsx
import React, {Component} from 'react';
import TodoList from 'TodoList';
import AddTodo from 'AddTodo';
class Main extends Component {
constructor(props) {
super(props);
this.setNewTodo = this.setNewTodo.bind(this);
this.state = {
newTodo: ''
};
}
setNewTodo(todo) {
this.setState({
newTodo: todo
});
}
render() {
var {newTodo} = this.state;
return (
<div>
<TodoList addToList={newTodo} />
<AddTodo setTodo={this.setNewTodo}/>
</div>
);
}
}
export default Main;
AddTodo.jsx
import React, {Component} from 'react';
class AddTodo extends Component {
constructor(props) {
super(props);
this.handleNewTodo = this.handleNewTodo.bind(this);
}
handleNewTodo() {
var todo = this.refs.todo.value;
this.refs.todo.value = '';
if (todo) {
this.props.setTodo(todo);
}
}
render() {
return (
<div>
<input type="text" ref="todo" />
<button onClick={this.handleNewTodo}>Add to Todo List</button>
</div>
);
}
}
AddTodo.propTypes = {
setTodo: React.PropTypes.func.isRequired
};
export default AddTodo;
待办列表.jsx
import React, {Component} from 'react';
class TodoList extends Component {
constructor(props) {
super(props);
this.renderItems = this.renderItems.bind(this);
this.state = {
todos: []
};
}
componentDidUpdate() {
var newTodo = this.props.addToList;
var todos = this.state.todos;
todos = todos.concat(newTodo);
this.setState({
todos: todos
});
}
renderItems() {
var todos = this.state.todos;
todos.map((item) => {
<h4>{item}</h4>
});
}
render() {
return (
<div>
{this.renderItems()}
</div>
);
}
}
export default TodoList;
最佳答案
第一次componentDidUpdate
被调用(这发生在它的 Prop /状态第一次改变之后,在你的情况下发生在添加第一个待办事项之后)它添加了 this.props.addToList
至 this.state.todo
并更新状态。更新状态将运行 componentDidUpdate
再次添加 this.props.addToList
的值再次转到“this.state.todo”,它会无限地进行。
您可以使用一些肮脏的技巧来修复它,但您的方法总体上是一种糟糕的方法。正确的做法是将待办事项保留在父组件 ( Main
) 中,将新的待办事项附加到 setNewTodo
中。 (您可能会将其重命名为 addTodo
)并传递来自 Main
的待办事项列表状态为 TodoList
: <TodoList todos={this.state.todos}/>
例如。
关于javascript - React App 中未捕获的 RangeError 超出最大调用堆栈大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44978921/