案例:需求分析
① 渲染评论列表(列表渲染)
② 没有评论数据时渲染:暂无评论(条件渲染)
③ 获取评论信息,包括评论人和评论内容(受控组件)
④ 发表评论,更新评论列表(setState())
实现步骤
1.渲染评论列表
① 在 state 中初始化评论列表数据
② 使用数组的map方法遍历state中的列表数据
③ 给每个被遍历的li元素添加key属性
export default class App extends Component {
// 1.初始化状态
state = {
comments: [
{ id: 1, name: '李明', content: '沙发!!!' },
{ id: 2, name: '丹尼', content: '板凳~' },
{ id: 3, name: '詹尼', content: '楼主好人' }
]
}
render() {
return (
<div className="app">
<div>
<input className="user" type="text" placeholder="请输入评论人" />
<br />
<textarea
className="content"
cols="30"
rows="10"
placeholder="请输入评论内容"
/>
<br />
<button>发表评论</button>
</div>
<div className="no-comment">暂无评论,快去评论吧~</div>
<ul>
{this.state.comments.map(item => (
<li key={item.id}>
<h3>评论人:{item.name}</h3>
<p>评论内容:{item.content}</p>
</li>
))}
</ul>
</div>
)
}
}
2.渲染暂无评论
① 判断列表数据的长度是否为0
② 如果为0,则渲染暂无评论
export default class App extends Component {
// 1.初始化状态
state = {
comments: [
{ id: 1, name: '李明', content: '沙发!!!' },
{ id: 2, name: '丹尼', content: '板凳~' },
{ id: 3, name: '詹尼', content: '楼主好人' }
]
}
// 2.渲染评论列表
renderList() {
const { comments } = this.state
if (comments.length === 0) {
return <div className="no-comment">暂无评论,快去评论吧~</div>
}
return (
<ul>
{this.state.comments.map(item => (
<li key={item.id}>
<h3>评论人:{item.name}</h3>
<p>评论内容:{item.content}</p>
</li>
))}
</ul>
)
}
render() {
return (
<div className="app">
<div>
<input className="user" type="text" placeholder="请输入评论人" />
<br />
<textarea
className="content"
cols="30"
rows="10"
placeholder="请输入评论内容"
/>
<br />
<button>发表评论</button>
</div>
{/* 通过条件渲染 决定渲染什么内容 */}
{this.renderList()}
</div>
)
}
}
3.获取评论信息
① 使用受控组件方式处理表单元素
export default class App extends Component {
// 1.初始化状态
state = {
comments: [
{ id: 1, name: '李明', content: '沙发!!!' },
{ id: 2, name: '丹尼', content: '板凳~' },
{ id: 3, name: '詹尼', content: '楼主好人' }
],
// 3.评论人
userName: '',
// 4.评论内容
userContent: ''
}
// 2.渲染评论列表
> renderList() {...
}
// 5.处理表单元素值
handerForm = e => {
const { name, value } = e.target
this.setState({
[name]: value
})
}
render() {
const { userName, userContent } = this.state
return (
<div className="app">
<div>
<input className="user" type="text" placeholder="请输入评论人"
value={userName}
name="userName"
onChange={this.handerForm}
/>
<br />
<textarea
className="content"
cols="30"
rows="10"
placeholder="请输入评论内容"
value={userContent}
name="userContent"
onChange={this.handerForm}
/>
<br />
<button>发表评论</button>
</div>
{/* 通过条件渲染 决定渲染什么内容 */}
{this.renderList()}
</div>
)
}
}
4. 发表评论
① 给按钮绑定单击事件
② 在事件处理程序中,通过state获取评论信息
③ 将评论信息添加到state中,并调用 setState() 方法更新state
④ 边界情况:清空文本框
⑤ 边界情况:非空判断
export default class App extends Component {
// 1.初始化状态
state = {
comments: [
{ id: 1, name: '李明', content: '沙发!!!' },
{ id: 2, name: '丹尼', content: '板凳~' },
{ id: 3, name: '詹尼', content: '楼主好人' }
],
// 3.评论人
userName: '',
// 4.评论内容
userContent: ''
}
// 2.渲染评论列表
> renderList() {...
}
// 5.处理表单元素值
> handerForm = e => {...
}
// 6.发表评论
addComment = () => {
const { comments, userName, userContent } = this.state
// console.log(userName, userContent);
// 非空判断
if (userName.trim() === '' || userContent.trim() === '') {
alert('请输入内容!')
return
}
const newComment = [
{
id: Math.random(),
name: userName,
content: userContent
}
, ...comments]
// console.log(newComment);
this.setState({
comments: newComment,
userName: '',
userContent: ''
})
}
render() {
const { userName, userContent } = this.state
return (
<div className="app">
<div>
<input className="user" type="text" placeholder="请输入评论人"
value={userName}
name="userName"
onChange={this.handerForm}
/>
<br />
<textarea
className="content"
cols="30"
rows="10"
placeholder="请输入评论内容"
value={userContent}
name="userContent"
onChange={this.handerForm}
/>
<br />
<button onClick={this.addComment}>发表评论</button>
</div>
{/* 通过条件渲染 决定渲染什么内容 */}
{this.renderList()}
</div>
)
}
}