React入门六: 组件基础练习

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'))
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值