[英]Why the map function doesn't work in my React app?
我正在学习 React,我想构建一个如下所示的应用程序:
基本上,用户可以输入他的姓名和评论并发布。 发表的评论将显示在底部。 我正在使用 Tailwind CSS 来设置应用程序的样式。 下面是我的代码。
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
class MyName extends React.Component {
render() {
return (<div className="rounded border border-indigo-400 m-8 p-2">
<div className="flex flex-col items-stretch space-y-2">
<input type="text" placeholder="Who you are?" className="border border-gray-500" value={this.state.currentUser} onChange={(e) => {
this.setState({currentUser: e.target.value});
}} />
<textarea placeholder="Say something" className="h-32 border border-gray-500" value={this.state.currentData} onChange={(e) => {
this.setState({currentData: e.target.value});
}}></textarea>
<button className="bg-green-400 text-green-100 rounded py-1 hover:bg-green-600" onClick={() => {
if (this.state.currentUser && this.state.currentData) {
this.setState({
comments: this.state.comments.push({
user: this.state.currentUser,
data: this.state.currentData
})
});
this.state.currentUser = "";
this.state.currentData = "";
}
}}>Post comment
</button>
</div>
<div className="mt-8">
{this.comments_section()}
</div>
</div>);
}
comments_section() {
if (this.state.comments.length == 0) {
return <span>No Comments.</span>
}
else {
console.log(Array.isArray(this.state.comments));
console.log(this.state.comments);
return (<ul className="space-y-4">{this.state.comments.map((item) =>
<li className="flex items-start space-x-2" key={item.user + item.data}>
<div className="flex flex-col items-start space-y-1">
<img className="rounded-full" src="http://placekitten.com/50/50" />
<span className="text-xs text-gray-500">{item.user}</span>
</div>
<span>{item.data}</span>
</li>)}
</ul>)
}
}
constructor() {
super();
this.state = {
currentUser: "",
currentData: "",
comments: [{
user: "User One",
data: "Hi, hello world!"
}, {
user: "User Two",
data: "Hi, hello world!"
}]
}
}
}
ReactDOM.render(
<MyName />,
document.getElementById('root')
);
reportWebVitals();
问题是,当我在输入中键入内容并单击按钮时,它会出错并指出this.state.comments.map不是 function。 我添加了一些console.log语句来调试它,发现起初this.state.comments是一个数组。 但是一旦我点击了按钮,它就不是了。 如何解决这个问题? 谢谢。
this.setState({
comments: this.state.comments.push({
user: this.state.currentUser,
data: this.state.currentData
})
});
array.push 返回一个数字,即数组的长度。 因此,您将 state.comments 设置为一个数字,而数字没有 map 方法。
您不应该为此使用 push,因为它会改变数组,并且 react 要求您的 state 是不可变的。 此外,您有几行手动设置 this.state.currentUser 和 this.state.currentData。 对 state 的更改应始终通过设置 state,而不是手动修改 this.state。
const newComments = [...this.state.comments, {
user: this.state.currentUser,
data: this.state.currentData
}]
this.setState({
comments: newComments,
currentUser: "",
currentData: ""
});
另一个改进:由于您将新的 state 基于旧的 state,因此您应该使用 setState 的 function 版本。 React 将向您传递最新版本的 state,这消除了您使用过时版本的 state 的可能性(您的代码可能无法遇到此错误,但它可能发生在更复杂的情况下,所以它是好习惯)
this.setState(prev => {
const newComments = [...prev.comments, {
user: prev.currentUser,
data: prev.currentData
}]
return {
comments: newComments
currentUser: "",
currentData: ""
};
});
array.push
返回一个数字,即数组的长度,因此您基本上是在将注释设置为其长度。
if (this.state.currentUser && this.state.currentData) {
let { comments, currentUser, currentData } = this.state;
comments.push({
user: currentUser,
data: currentData
})
this.setState({comments, currentUser : "", currentData: "" })
}
我不是反应专家,但我认为您需要像这样从 map 返回您的 jsx:
<ul className="space-y-4">
{this.state.comments.map((item) => return (
<li className="flex items-start space-x-2" key={item.user + item.data}>
<div className="flex flex-col items-start space-y-1">
<img className="rounded-full" src="http://placekitten.com/50/50" />
<span className="text-xs text-gray-500">{item.user}</span>
</div>
<span>{item.data}</span>
</li>))}
</ul>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.