本文是学习React笔记,对应视频为:https://www.bilibili.com/video/BV1oW41157DY 的 17 - 23 节。
一、脚手架创建应用
src/index.js
import React from 'react'
import ReactDOM from 'react-dom'
import App from "./components/app";
import './index.css';
ReactDOM.render(<App/>, document.getElementById('root'))
src/index.css
.logo{
width: 200px;
height: 200px
}
.title{
color: red;
font-size: 25px;
}
src/components/app.jsx
import React, {Component} from 'react'
import logo from '../logo.svg'
export default class App extends Component{
render() {
return(
<div>
<img className='logo' src={logo} alt="logo"/>
<p className='title'>React组件</p>
</div>
)
}
}
最终效果
二、评论管理练习
内容概要:
1. 一个评论系统可以在左侧编辑内容,点击添加添加到右边,并清除编辑框内容
2. 右侧是列表,可以删除其中一项
public/index.html 添加一行
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.5.3/css/bootstrap.css" rel="stylesheet">
src目录结构
app.jsx
import React, {Component} from 'react'
import CommentAdd from "../comment-add/comment-add";
import CommentList from "../comment-list/comment-list";
export default class App extends Component {
/*constructor(props) {
super(props);
this.state = {
comments: [
{username: 'Tom', content: 'React挺好的'},
{username: 'Jack', content: 'React挺难的'}
]
}
}*/
//给组件对象指定state属性,和上面效果一样
state = {
comments: [
{username: 'Tom', content: 'React挺好的'},
{username: 'Jack', content: 'React挺难的'}
]
}
//添加评论
addComment = (comment) => {
const {comments} = this.state;
comments.unshift(comment);
//更新状态
this.setState({comments})
}
//删除指定评论
deleteComment = (index) => {
const {comments} = this.state;
comments.splice(index, 1)
//更新状态
this.setState({comments})
}
render() {
const comments = this.state.comments;
return (
<div>
<header className="site-header jumbotron">
<div className="container">
<div className="row">
<div className="col-xs-12">
<h1>请发表对React的评论</h1>
</div>
</div>
</div>
</header>
<div className="container">
<CommentAdd addComment={this.addComment}/>
<CommentList comments={comments} deleteComment={this.deleteComment}/>
</div>
</div>
)
}
}
comment-add.jsx
import React, {Component} from 'react'
import PropTypes from 'prop-types';
export default class CommentAdd extends Component{
static propTypes = {
addComment: PropTypes.func.isRequired
}
state = {
username: '',
content: ''
}
handleSubmit = () => {
//收集数据
const comment = this.state
//更新状态
this.props.addComment(comment);
//清除输入数据
this.setState({
username: '',
content: ''
})
}
handleNameChange = (event) => {
const username = event.target.value;
this.setState({username});
}
handleContentChange = (event) => {
const content = event.target.value;
this.setState({content});
}
render() {
const {username, content} = this.state;
return(
<div className="col-md-4 float-left">
<form className="form-horizontal">
<div className="form-group">
<label>用户名</label>
<input type="text" className="form-control" placeholder="请输入用户名"
value={username} onChange={this.handleNameChange}/>
</div>
<div className="form-group">
<label>评论内容</label>
<textarea className="form-control" rows="6" placeholder="评论详情"
value={content} onChange={this.handleContentChange}/>
</div>
<div className="form-group">
<div className="col-sm-offset-2 col-sm-10">
<button type="button" className="btn btn-default pull-right" onClick={this.handleSubmit}>提交</button>
</div>
</div>
</form>
</div>
)
}
}
comment-item.jsx
import React, {Component} from 'react'
import PropTypes from 'prop-types';
import './commentItem.css'
export default class CommentItem extends Component{
static propTypes = {
comment: PropTypes.object.isRequired,
deleteComment: PropTypes.func.isRequired,
index: PropTypes.number.isRequired,
}
handleClick = () =>{
const {comment, deleteComment, index} = this.props;
//提示
if(window.confirm(`确定删除 ${comment.username} 的评论吗?`)){
//确定后删除
deleteComment(index);
}
}
render() {
const {comment} = this.props;
return(
<li className="list-group-item">
<div className="handle">
<a onClick={this.handleClick}>删除</a>
</div>
<p className="user"><span>{comment.username}</span><span>说:</span></p>
<p className="centence">{comment.content}</p>
</li>
)
}
}
li{
overflow: hidden;
}
.handle{
width: 40px;
border: 1px solid #CCC;
background-color: #fff;
position: absolute;
right: 10px;
top: 1px;
text-align: center;
}
.handle a{
display: block;
text-decoration: none;
}
.list-group-item .centence{
padding: 0 50px;
}
.user{
font-size: 22px;
}
.col-md-8{
float: left;
}
comment-list.jsx
import React, {Component} from 'react'
import PropTypes from 'prop-types';
import './commentList.css'
import CommentItem from "../comment-item/comment-item";
export default class CommentList extends Component{
static propTypes = {
comments: PropTypes.array.isRequired,
deleteComment: PropTypes.func.isRequired
}
render() {
const {comments, deleteComment} = this.props;
const display = comments.length === 0 ? 'block' : 'none';
return(
<div className="col-md-8 float-left">
<h3 className="reply">评论回复</h3>
<h2 style={{display: display}}>暂无评论,点击右侧添加评论!</h2>
<ul className="list-group">
{
comments.map((comment, index) => <CommentItem comment={comment} key={index}
deleteComment={deleteComment} index={index}/>)
}
</ul>
</div>
)
}
}
/*
CommentList.propTypes = {
comments: PropTypes.array.isRequired
}*/
.reply{
margin-top: 0px;
}
index.js
import React from 'react'
import ReactDOM from 'react-dom'
import App from "./components/app/app";
ReactDOM.render(<App/>, document.getElementById('root'))