React学习(4)脚手架

使用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:评论管理

效果:

完成项目的静态组件

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>

完整DEMO下载

发表评论

邮箱地址不会被公开。 必填项已用*标注