React实现一个发布评论的小案例(易学)

329 阅读2分钟

image.png

案例:需求分析

① 渲染评论列表(列表渲染)

② 没有评论数据时渲染:暂无评论(条件渲染)

③ 获取评论信息,包括评论人和评论内容(受控组件)

④ 发表评论,更新评论列表(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>
    )
  }
}