我正在制作一个简单的Todo列表,该列表由一个容器App
组件以及一个子Todo
无状态功能组件组成。创建新的待办事项时,我希望将其添加到在父组件状态中定义的待办事项数组中。但是,这样做时出现错误:Uncaught TypeError: this.state.todos.map is not a function
。有人可以帮我理解为什么吗。
这是父组件:
class App extends Component {
constructor(props){
super(props);
this.state = {
input: '',
todos: [
'buy milk',
'buy eggs',
'take out trash'
]
};
this.handleSubmit=this.handleSubmit.bind(this);
this.handleChange=this.handleChange.bind(this);
}
handleSubmit(e){
let value = this.state.input;
let todos = this.state.todos;
let newTodos = todos.push(value);
this.setState({todos: newTodos, input: ''});
}
handleChange(e){
this.setState({input: e.target.value})
}
render() {
let todolist = this.state.todos.map((value, index) => {
return(
<ul>
<Todo value={value} />
</ul>
)
})
return (
<div>
<h1>My Todo list</h1>
<form onSubmit={this.handleSubmit}>
<input
type='text'
onChange={this.handleChange}
value={this.state.input}
/>
<input type='submit'/>
</form>
{todolist}
</div>
);
}
}
这是子组件:
let Todo = (props) => {
return(
<li>{props.value}</li>
)
};
答案 0 :(得分:3)
let newTodos = todos.push(value);
的值将是数组的长度,即3
。当您将todos
的状态更新为此时,您会得到错误消息。
您需要使用form
来阻止preventDefault
的默认行为(即重新加载浏览器),并且可以像这样添加待办事项,以避免{{1} }数组:
todos
答案 1 :(得分:1)
只需添加一项改进即可。当前,您有以下内容:
let todolist = this.state.todos.map((value, index) => {
return (<ul>
<Todo value={value}/>
</ul>)
})
它将为每个待办事项呈现UL,并且您的HTML外观如下:
<ul><li>buy milk</li></ul>
<ul><li>buy eggs</li></ul>
<ul><li>take out trash</li></ul>
您可以这样做:
render() {
let todolist = this.state.todos.map((value, index) => {
return <Todo value={value}/> // Return only the todo, not the UL
})
return (<div>
<h1>My Todo list</h1>
<form onSubmit={this.handleSubmit}>
<input type='text' onChange={this.handleChange} value={this.state.input}/>
<input type='submit'/>
</form>
<ul>{todolist}</ul> // UL here
</div>);}
}
您将渲染一个UL:
<ul>
<li>buy milk</li>
<li>buy eggs</li>
<li>take out trash</li>
</ul>