1.渲染评论列表
- 在state中初始化评论列表数据
- 使用数组的map方法 遍历state中的列表数据
- 给每个被遍历的li元素添加key属性
数据如下
state = {
comments: [
{ id: 1, name: 'jack', content: '沙发!!' },
{ id: 2, name: 'rose', content: '版本!~' },
{ id: 3, name: 'tom', content: '嘻嘻嘻' }
],
}
使用map() 渲染列表
// ES6 中模块化语法
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
class App extends React.Component {
state = {
comments: [
{ id: 1, name: 'jack', content: '沙发!!' },
{ id: 2, name: 'rose', content: '版本!~' },
{ id: 3, name: 'tom', content: '嘻嘻嘻' }
],
}
render() {
return (
<div className="app">
<div className="container">
<input className="user" type="text" placeholder="请输入评论人" name="userName"
style={{margin:'10px'}}
></input>
<br />
<textarea
className="content"
cols="30"
rows="10"
placeholder="请输入评论内容"
name="userContent"
style={{margin:'3px'}}
/>
<br/>
<button>发表评论</button>
<ul>
{
this.state.comments.map((item => (
<li key={item.id}>
<h3>评论人:{item.name}</h3>
<p>评论内容:{item.content}</p>
</li>
)))
}
</ul>
</div>
</div>
)
}
}
ReactDOM.render(<App />, document.getElementById('root'))
使用 数据的 id 做为遍历出 li 的 key
数据就被渲染出来了
2. 渲染暂无评论
- 判断列表数据的长度是否为0
- 如果为0,渲染 暂无评论
使用三元运算符 判断列表数据长度 渲染出不同效果
// ES6 中模块化语法
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
class App extends React.Component {
state = {
comments: [
{ id: 1, name: 'jack', content: '沙发!!' },
{ id: 2, name: 'rose', content: '版本!~' },
{ id: 3, name: 'tom', content: '嘻嘻嘻' }
],
}
render() {
return (
<div className="app">
<div className="container">
<input className="user" type="text" placeholder="请输入评论人" name="userName"
onChange={this.handleForm} style={{ margin: '10px' }}
></input>
<br />
<textarea
className="content"
cols="30"
rows="10"
placeholder="请输入评论内容"
name="userContent"
style={{ margin: '3px' }}
/>
<br />
<button>发表评论</button>
{/* 通过条件渲染 */}
{
this.state.comments.length === 0 ? (<div style={{ textAlign: 'center' }}> 暂无评论,快去评论吧~ </div>) : (<ul>
{
this.state.comments.map((item => (
<li key={item.id}>
<h3>评论人:{item.name}</h3>
<p>评论内容:{item.content}</p>
</li>
)))
}
</ul>)
}
</div>
</div>
)
}
}
ReactDOM.render(<App />, document.getElementById('root'))
将数据注释掉 ,可以看出我们想要的效果得到了
虽然 现在功能实现了 但是逻辑并不清晰 。我们优化一下
// ES6 中模块化语法
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
class App extends React.Component {
state = {
comments: [
{ id: 1, name: 'jack', content: '沙发!!' },
{ id: 2, name: 'rose', content: '版本!~' },
{ id: 3, name: 'tom', content: '嘻嘻嘻' }
],
}
// 渲染评论列表
renderList() {
// return 和后面的代码要写在一行
return this.state.comments.length === 0 ? (<div style={{ textAlign: 'center' }}> 暂无评论,快去评论吧~ </div>) : (<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 className="container">
<input className="user" type="text" placeholder="请输入评论人" name="userName"
onChange={this.handleForm} style={{ margin: '10px' }}
></input>
<br />
<textarea
className="content"
cols="30"
rows="10"
placeholder="请输入评论内容"
name="userContent"
style={{ margin: '3px' }}
/>
<br />
<button>发表评论</button>
{
this.renderList()
}
</div>
</div>
)
}
}
ReactDOM.render(<App />, document.getElementById('root'))
可见,我们把渲染评论列表拿到了外面。写成了一个有返回值的方法。
如果觉得三元表达式不够清晰 可以写成 if else
if(this.state.comments.length === 0){
<div style={{ textAlign: 'center' }}>
暂无评论,快去评论吧~
</div>
}
return (
<ul>
{
this.state.comments.map((item => (
<li key={item.id}>
<h3>评论人:{item.name}</h3>
<p>评论内容:{item.content}</p>
</li>
)))
}
</ul>
)
代码优化:
this.state.comments出现多次。声明个变量接收它
renderList() {
// 解构的方式
const {comments} = this.state.comments.length
// return 和后面的代码要写在一行
return comments.length === 0 ? (<div style={{ textAlign: 'center' }}> 暂无评论,快去评论吧~ </div>) : (<ul>
{
comments.map((item => (
<li key={item.id}>
<h3>评论人:{item.name}</h3>
<p>评论内容:{item.content}</p>
</li>
)))
}
</ul>)
}
3. 获取评论信息
- 使用受控组件的方式
在数据中添加变量
state = {
comments: [
{ id: 1, name: 'jack', content: '沙发!!' },
{ id: 2, name: 'rose', content: '版本!~' },
{ id: 3, name: 'tom', content: '嘻嘻嘻' },
],
userName: '',
userContent: ''
}
添加 value 、name 属性 并且 解构出 userName,userContent
const {userName,userContent} = this.state
return (
<div className="app">
<div className="container">
<input className="user" type="text" placeholder="请输入评论人" value={userName} name="userName"
onChange={this.handleForm}
></input>
<br />
<textarea
className="content"
cols="30"
rows="10"
placeholder="请输入评论内容"
value={userContent}
name="userContent"
onChange={this.handleForm}
/>
<br></br>
<button>发表评论</button>
{
this.renderList()
}
</div>
</div>
)
添加处理表单元素值的方法
使用setState方法
// 处理表单元素值
handleForm = (e) => {
const { name, value } = e.target
this.setState({
// 在ES6中,把属性名用[ ]括起来,则括号中就可以引用提前定义的变量。
[name]: value
})
}
两个表单元素 发生了变化
4. 发表评论
- 给按钮添加点击事件
- 在事件处置,通过state获取评论信息
- 将评论信息添加到state中,并调用setState()方法更新state
按钮点击触发添加方法
<button onClick={ this.addCOmment}>发表评论</button>
添加后 添加到列表 顶部
addComment = ()=>{
const {comments,userName, userContent } = this.state
// 延展操作符
const newComments = [{
// 随机数
id:Math.random(),
name:userName,
content:userContent
},...comments];
// 更新状态
this.setState({
comments:newComments
})
}
如果想添加到尾部
const newComments = [...comments,{
id:Math.random(),
name:userName,
content:userContent
}];
5. 完善
5.1 清空文本框内容
把 state中的 userName和userContent清空
addComment = ()=>{
const {comments,userName, userContent } = this.state
// 延展操作符
const newComments = [...comments,{
id:Math.random(),
name:userName,
content:userContent
}];
// 更新状态
this.setState({
comments:newComments,
userName: '',
userContent: ''
})
}
5.2 发布为空时提示
addComment = ()=>{
const {comments,userName, userContent } = this.state
//非空校验
if(userName.trim() ==='' || userContent.trim==''){
alert('请输入')
return
}
// 延展操作符
const newComments = [...comments,{
id:Math.random(),
name:userName,
content:userContent
}];
// 更新状态
this.setState({
comments:newComments,
userName: '',
userContent: ''
})
}
6. 完整代码
// ES6 中模块化语法
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
class App extends React.Component {
state = {
comments: [
{ id: 1, name: 'jack', content: '沙发!!' },
{ id: 2, name: 'rose', content: '版本!~' },
{ id: 3, name: 'tom', content: '嘻嘻嘻' },
],
userName: '',
userContent: ''
}
// 渲染评论列表
renderList() {
return this.state.comments.length === 0 ? (<div style={{ textAlign: 'center' }}> 暂无评论,快去评论吧~ </div>) : (<ul>
{
this.state.comments.map((item => (
<li key={item.id}>
<h3>评论人:{item.name}</h3>
<p>评论内容:{item.content}</p>
</li>
)))
}
</ul>)
}
// 处理表单元素值
handleForm = (e) => {
const { name, value } = e.target
this.setState({
[name]: value
})
}
addComment = ()=>{
const {comments,userName, userContent } = this.state
//非空校验
if(userName.trim() ==='' || userContent.trim==''){
alert('请输入')
return
}
// 延展操作符
const newComments = [...comments,{
id:Math.random(),
name:userName,
content:userContent
}];
// 更新状态
this.setState({
comments:newComments,
userName: '',
userContent: ''
})
}
render() {
const { userName, userContent } = this.state
return (
<div className="app">
<div className="container">
<input className="user" type="text" placeholder="请输入评论人" value={userName} name="userName"
onChange={this.handleForm}
></input>
<br />
<textarea
className="content"
cols="30"
rows="10"
placeholder="请输入评论内容"
value={userContent}
name="userContent"
onChange={this.handleForm}
/>
<br></br>
<button onClick={ this.addComment}>发表评论</button>
{
this.renderList()
}
</div>
</div>
)
}
}
ReactDOM.render(<App />, document.getElementById('root'))