React组件基础案例——评论列表

案例:需求分析

  1. 渲染评论列表 (列表渲染)

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

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

  4. 发表评论,更新评论列表(setState())

案例:实现步骤

  1. 渲染评论列表

    1. 在state中初始化评论列表数据

    2. 使用数组的map方法遍历state中的列表数据

    3. 给每个被遍历的li元素添加key属性

//1. 导入react
import React from 'react';
import ReactDOM from 'react-dom';


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>
          <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>
    )
  }
}

//渲染组件
ReactDOM.render(<App />, document.getElementById('root'))

  2.渲染暂无评论

    1. 判断列表数据的长度是否为0

    2. 如果为0;则渲染暂无评论

//1. 导入react
import React from 'react';
import ReactDOM from 'react-dom';


class App extends React.Component {
  // 初始化状态
  state = {
    Comments: [
      { id: 1, name: 'jack', content: '沙发!!!'},
      { id: 2, name: 'rose', content: '板凳~'},
      { id: 3, name: 'tom', content: '楼主好人'},
    ]
  }

  // 渲染评论列表:
  renderList() {
   const {Comments} = this.state
if (Comments.length === 0) { return ( <div className="no-comment">暂无评论,快去评论吧~</div> ) } return ( <ul> {Comments.map(item => ( <li key={item.id}> <h3>评论人:{item.name}</h3> <p>评论内容:{item.content}</p> </li> ))} </ul> ) // return this.state.Comments.length === 0 ? ( // <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> // ) } 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.state.Comments.length === 0 ? ( <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> )} */} {this.renderList()} </div> ) } } //渲染组件 ReactDOM.render(<App />, document.getElementById('root'))

   3. 获取评论信息

    1. 使用受控组件方式处理表单元素

//1. 导入react
import React from 'react';
import ReactDOM from 'react-dom';


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() {
    const {Comments} = this.state

    if (Comments.length === 0) {
      return (
      <div className="no-comment">暂无评论,快去评论吧~</div>
      )
    }

    return (
      <ul>
         {Comments.map(item => (
          <li key={item.id}>
            <h3>评论人:{item.name}</h3>
            <p>评论内容:{item.content}</p>
          </li>
        ))}
      </ul>
    )
    
    // return this.state.Comments.length === 0 ? (
    //   <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>
    // )
  }

  //处理表单元素值
  handleForm = (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.handleForm} />
          <br/>
          <textarea 
            className="content"
            cols="30"
            rows="10"
            placeholder="请输入评论内容"
            value={userContent}
            name="userContent"
            onChange={this.handleForm}
          />
          <br/>
          <button>发表评论</button>
        </div>

        {/* 通过条件渲染决定渲染什么内容: */}
        {/* {this.state.Comments.length === 0 ? (
          <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>
        )} */}
        {this.renderList()}
      </div>
    )
  }
}

//渲染组件
ReactDOM.render(<App />, document.getElementById('root'))

  4. 发表评论

    1. 给按钮绑定单击事件

    2. 在事件处理程序中,通过state获取评论信息

    3. 将评论信息添加到state中,并调用setState()方法更新state

//1. 导入react
import React from 'react';
import ReactDOM from 'react-dom';


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() {
    const {Comments} = this.state

    if (Comments.length === 0) {
      return (
      <div className="no-comment">暂无评论,快去评论吧~</div>
      )
    }

    return (
      <ul>
         {Comments.map(item => (
          <li key={item.id}>
            <h3>评论人:{item.name}</h3>
            <p>评论内容:{item.content}</p>
          </li>
        ))}
      </ul>
    )
    
    // return this.state.Comments.length === 0 ? (
    //   <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>
    // )
  }

  //处理表单元素值
  handleForm = (e) => {
    const { name, value } = e.target

    this.setState({
      [name]: value
    })
  }

  //发表评论:
  addComment = () => {
    const {Comments,userName, userContent} = this.state
    // console.log(userName,userContent)
    const newComments = [{
      id: Math.random(), 
      name: userName, 
      content: userContent
    }, ...Comments]

    // console.log(newComments);
    this.setState({
      Comments:newComments
    })
  }

  render () {
    const {userName,userContent} = this.state

    return (
      <div className="app">
        <div>
          <input className="user" type="text" placeholder="请输入评论人" value={userName} name="userName" 
          onChange={this.handleForm} />
          <br/>
          <textarea 
            className="content"
            cols="30"
            rows="10"
            placeholder="请输入评论内容"
            value={userContent}
            name="userContent"
            onChange={this.handleForm}
          />
          <br/>
          <button onClick={this.addComment}>发表评论</button>
        </div>

        {/* 通过条件渲染决定渲染什么内容: */}
        {/* {this.state.Comments.length === 0 ? (
          <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>
        )} */}
        {this.renderList()}
      </div>
    )
  }
}

//渲染组件
ReactDOM.render(<App />, document.getElementById('root'))

    5.边界情况:清空文本框

    6.边界情况:非空判读

//1. 导入react
import React from 'react';
import ReactDOM from 'react-dom';


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() {
    const {Comments} = this.state

    if (Comments.length === 0) {
      return (
      <div className="no-comment">暂无评论,快去评论吧~</div>
      )
    }

    return (
      <ul>
         {Comments.map(item => (
          <li key={item.id}>
            <h3>评论人:{item.name}</h3>
            <p>评论内容:{item.content}</p>
          </li>
        ))}
      </ul>
    )
    
    // return this.state.Comments.length === 0 ? (
    //   <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>
    // )
  }

  //处理表单元素值
  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
    }

    // console.log(userName,userContent)
    //将评论信息添加到state中
    const newComments = [{
      id: Math.random(), 
      name: userName, 
      content: userContent
    }, ...Comments]

    // console.log(newComments);
    //文本框的值如何清空? 要清空文本框只需要将其对应的state清空即可

    this.setState({
      Comments:newComments,
      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.handleForm} />
          <br/>
          <textarea 
            className="content"
            cols="30"
            rows="10"
            placeholder="请输入评论内容"
            value={userContent}
            name="userContent"
            onChange={this.handleForm}
          />
          <br/>
          <button onClick={this.addComment}>发表评论</button>
        </div>

        {/* 通过条件渲染决定渲染什么内容: */}
        {/* {this.state.Comments.length === 0 ? (
          <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>
        )} */}
        {this.renderList()}
      </div>
    )
  }
}

//渲染组件
ReactDOM.render(<App />, document.getElementById('root'))

 最终版

index.js

//1. 导入react
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() {
    const {Comments} = this.state

    if (Comments.length === 0) {
      return (
      <div className="no-comment">暂无评论,快去评论吧~</div>
      )
    }

    return (
      <ul>
         {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
    }

    //将评论信息添加到state中
    const newComments = [{
      id: Math.random(), 
      name: userName, 
      content: userContent
    }, ...Comments]

    //更新state,并清空文本框的内容
    this.setState({
      Comments:newComments,
      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.handleForm} />
          <br/>
          <textarea 
            className="content"
            cols="30"
            rows="10"
            placeholder="请输入评论内容"
            value={userContent}
            name="userContent"
            onChange={this.handleForm}
          />
          <br/>
          <button onClick={this.addComment}>发表评论</button>
        </div>

        {/* 通过条件渲染决定渲染什么内容: */}
        {this.renderList()}
        
      </div>
    )
  }
}

//渲染组件
ReactDOM.render(<App />, document.getElementById('root'))

index.css

.app {
  border:1px solid black;
  width: 260px;

}
.user{
  width: 240px;
  margin-left: 10px;
  margin-top: 10px;
}
.content{
  width: 240px;
  margin-left: 10px;
  margin-top: 10px;
}
.app button {
  margin-left: 10px;
}

 

posted @ 2021-11-08 17:47  wslfw  阅读(267)  评论(0)    收藏  举报