使用create-react-app创建react应用
react脚手架
1)  xxx脚手架: 用来帮助程序员快速创建一个基于xxx库的模板项目
a.  包含了所有需要的配置
b.  指定好了所有的依赖
c.  可以直接安装/编译/运行一个简单效果
2)  react提供了一个用于创建react项目的脚手架库: create-react-app
3)  项目的整体技术架构为:  react + webpack + es6 + eslint
4)  使用脚手架开发的项目的特点: 模块化, 组件化, 工程化
创建项目并启动
npm i create-react-app -g
create-react-app hello-react
cd hello-react
yarn start
运行后效果:
demo:评论管理
效果:
完成项目的静态组件
- 1.准备工作
下载静态页面 - 
2.使用
create-react-app生成脚手架 
create-react-app comment-demo
cd comment-demo
生成脚手架后的目录结构如下图所示:
删除用不上的文件,以免干扰:
- 3.拆分组件
入口文件:index.js
应用组件: App.jsx
添加评论组件: Add.jsx
评论列表组件: List.jsx
评论项组件: Item.jsx 
src/index.js内容如下:
import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
ReactDOM.render(<App/>,document.getElementById('root'))
src/App.jsx内容如下:
import React, {Component} from 'react'
import Add from './components/add/Add'
import List from './components/list/List'
export default class App extends Component {
    render() {
        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">
                    <Add/>
                    <List/>
                </div>
            </div>
        )
    }
}
src/components/add/Add.jsx内容如下:
import React, {Component} from 'react'
export default class Add extends Component {
    render() {
        return (
            <div className="col-md-4">
                <form className="form-horizontal">
                    <div className="form-group">
                        <label>用户名</label>
                        <input type="text" className="form-control" placeholder="用户名"/>
                    </div>
                    <div className="form-group">
                        <label>评论内容</label>
                        <textarea className="form-control" rows="6" placeholder="评论内容"></textarea>
                    </div>
                    <div className="form-group">
                        <div className="col-sm-offset-2 col-sm-10">
                            <button type="button" className="btn btn-default pull-right">提交</button>
                        </div>
                    </div>
                </form>
            </div>
        )
    }
}
src/components/item/Item.jsx内容如下:
import React, {Component} from 'react'
import './Item.css'
export default class Item extends Component {
    render() {
        return (
            <li className="list-group-item">
                <div className="handle">
                    <a href="#1">删除</a>
                </div>
                <p className="user"><span>xxx</span><span>说:</span></p>
                <p className="centence">React不错!</p>
            </li>
        )
    }
}
src/components/list/List.jsx内容如下:
import React, {Component} from 'react'
import Item from "../item/Item";
import './List.css'
export default class List extends Component {
    render() {
        return (
            <div className="col-md-8">
                <h3 className="reply">评论回复:</h3>
                <h2 style={{display: 'none'}}>暂无评论,点击左侧添加评论!!!</h2>
                <ul className="list-group">
                    <Item/>
                </ul>
            </div>
        )
    }
}
需要注意style内联样式的写法:
style={{display: 'none'}}
public/index.html内容如下:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8"/>
    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1"/>
    <link rel="stylesheet" href="%PUBLIC_URL%/css/bootstrap.css">
    <title>React App</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
完整目录结构如下图:
动态初始化显示
首先实现右侧评论列表的动态显示
用状态来保存右侧的评论数据,由于Add组件与List组件都要用到,那么将此状态写在App上。App.jsx代码如下:
import React, {Component} from 'react'
import Add from './components/add/Add'
import List from './components/list/List'
export default class App extends Component {
    state = {
        comments: [
            {userId: '001', userName: '张三', content: '你好啊,react'},
            {userId: '002', userName: '李四', content: '大家好,我是002'},
            {userId: '003', userName: '周杰伦', content: '麻烦给我的爱人一杯Mojito'},
        ]
    }
    render() {
        let {comments} = this.state
        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">
                    <Add/>
                    <List comments={comments}/>
                </div>
            </div>
        )
    }
}
List.jsx代码如下:
import React, {Component} from 'react'
import Item from "../item/Item";
import './List.css'
export default class List extends Component {
    render() {
        let {comments} = this.props
        return (
            <div className="col-md-8">
                <h3 className="reply">评论回复:</h3>
                <h2 style={{display: 'none'}}>暂无评论,点击左侧添加评论!!!</h2>
                <ul className="list-group">
                    {
                        comments.map((item)=>{
                            return <Item {...item}/>
                        })
                    }
                </ul>
            </div>
        )
    }
}
Item.jsx代码如下:
import React, {Component} from 'react'
import './Item.css'
export default class Item extends Component {
    render() {
        let {userId,userName,content} = this.props
        return (
            <li className="list-group-item">
                <div className="handle">
                    <a href={userId}>删除</a>
                </div>
                <p className="user"><span>{userName}</span><span>说:</span></p>
                <p className="centence">{content}</p>
            </li>
        )
    }
}
实现后效果:
完成评论新增功能
- 1.为
Add.jsx中的提交按钮绑定addComment方法 
import React, {Component} from 'react'
import {v1 as uuid} from 'uuid'
export default class Add extends Component {
    addComment = () => {
        //1.获取填写的内容
        let {userName, content} = this
        userName = userName.value
        content = content.value
        //2.验证内容合法性
        if (userName === '' || content === '') {
            alert('请填写姓名或内容')
            return
        }
        //3生成uuid
        let userId = uuid()
        //4.更新状态
        let {setComments} = this.props
        setComments({userId, userName, content})
        //5.清空输入框里的内容
        this.userName.value = ''
        this.content.value = ''
    }
    render() {
        return (
            <div className="col-md-4">
                <form className="form-horizontal">
                    <div className="form-group">
                        <label>用户名</label>
                        <input type="text" className="form-control" placeholder="用户名" ref={(input) => {
                            this.userName = input
                        }}/>
                    </div>
                    <div className="form-group">
                        <label>评论内容</label>
                        <textarea className="form-control" rows="6" placeholder="评论内容" ref={(input) => {
                            this.content = input
                        }}></textarea>
                    </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.addComment}>提交
                            </button>
                        </div>
                    </div>
                </form>
            </div>
        )
    }
}
注意:uuid使用了第三方组件,需要先使用yarn add uuid安装
- 2.在
App.jsx中的增加更新状态方法,并将该方法传递到Add组件 
import React, {Component} from 'react'
import Add from './components/add/Add'
import List from './components/list/List'
export default class App extends Component {
    state = {
        comments: [
        ]
    }
    setComments = (commentObj) => {
        //获取原评论数据
        let {comments} = this.state
        //插入新评论数据
        comments.unshift({...commentObj})
        //更新状态
        this.setState({comments})
    }
    render() {
        let {comments} = this.state
        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">
                    <Add setComments={this.setComments}/>
                    <List comments={comments}/>
                </div>
            </div>
        )
    }
}
- 3.在
List.jsx里判断评论条数,没有则显示“暂无评论” 
import React, {Component} from 'react'
import Item from "../item/Item";
import './List.css'
export default class List extends Component {
    render() {
        let {comments} = this.props
        return (
            <div className="col-md-8">
                <h3 className="reply">评论回复:</h3>
                <h2 style={{display: comments.length>0 ? 'none' : 'block'}}>暂无评论,点击左侧添加评论!!!</h2>
                <ul className="list-group">
                    {
                        comments.map((item)=>{
                            return <Item key={item.userId} {...item}/>
                        })
                    }
                </ul>
            </div>
        )
    }
}
完成评论删除功能
- 1.在
App.jsx中增加delComments方法用于删除评论 
delComments = (userId) => {
    //获取原评论数据
    let comments = [...this.state.comments]
    //删除指定userId数据
    comments.forEach((item,index)=>{
        if(item.userId===userId){
            comments.splice(index,1)
        }
    })
    //更新状态
    this.setState({comments})
}
在List组件中绑定delComments方法:
<List comments={comments} delComments={this.delComments}/>
- 2.在
List.jsx中的Item组件传递delComments方法 
return <Item key={item.userId} delComments={delComments} {...item}/>
- 3.在
Item.jsx中增加delete方法用于执行删除操作 
delete = () => {
    let {userId,delComments} = this.props
    delComments(userId)
}
<a href="#1" onClick={this.delete}>删除</a>