this.state.todos.map 不是函数,React.js

Posted

技术标签:

【中文标题】this.state.todos.map 不是函数,React.js【英文标题】:this.state.todos.map is not a function, React.js 【发布时间】:2018-12-22 18:46:51 【问题描述】:

我正在制作一个简单的 Todo 列表,其中包含一个容器 App 组件以及一个子 Todo 无状态功能组件。当我创建一个新的 todo 时,我希望它被添加到我在父组件状态中定义的 todos 数组中。但是,当我这样做时,我收到错误: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>
	)
;

【问题讨论】:

【参考方案1】:

let newTodos = todos.push(value); 的值将是数组的长度,即3。当您将状态中的todos 更新为此您将收到错误消息。

您需要使用preventDefault 防止form 的默认行为(即重新加载浏览器),您可以像这样添加待办事项以避免todos 数组的突变:

handleSubmit(e) 
  e.preventDefault();

  this.setState(previousState => 
    return 
      todos: [...previousState.todos, previousState.input],
      input: ""
    ;
  );

【讨论】:

结合e.preventDefault(),这行得通,谢谢! @MiddleZ 啊,我错过了它是表单的一部分。我更新了答案。不客气!【参考方案2】:

只是为了添加一个改进。目前你有这个:

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>

【讨论】:

以上是关于this.state.todos.map 不是函数,React.js的主要内容,如果未能解决你的问题,请参考以下文章

Firebase身份验证(不是函数,不是构造函数)

passport-local-mongoose:createStrategy 不是一个函数/authenticate 不是一个函数

为啥函数不是对象?

解析云代码函数响应成功不是函数

从头开始定义列表函数而不是库函数

Python 2.7 函数是不是记住值而不是引用?关闭怪异