[React] 尚硅谷 -- 学习笔记(三)

第三章 react应用(基于react脚手架)

使用create-react-app创建react应用
react脚手架
  • xxx 脚手架:用来帮助程序员快速创建一个基于 xxx 库的模板项目

    • 包含了所有需要的配置

    • 指定好了所有的依赖

    • 可以直接安装/编译/运行一个简单效果

  • react 提供了一个用于创建 react 项目的脚手架库:create-react-app

  • 项目的整体技术架构为:react + webpack + es6 + eslint

  • 使用脚手架开发的项目的特点:模块化,组件化,工程化

创建并启动
// 全局安装create-react-app脚手架
npm i -g create-react-app 
// 创建一个react项目,项目名称是hello-react
create-react-app hello-react 
// 进入hello-react
cd hello-react
// 启动项目
npm start 
react脚手架项目结构
  • node_modules – 第三方依赖模块文件夹

  • public

    • index.html – 主页面
  • scripts

    • build.js – build打包引用配置
    • start.js – start运行引用配置
  • src – 源码文件夹

    • components – react组件
    • index.js – 应用入口js
  • .gitignore – git版本管制忽略的配置

  • package.json – 应用包配置文件

  • README.md – 应用描述说明的readme文件

 

案例 – 评论管理
  • 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 {

    //给组件对象指定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
        // splice可以实现增删改
        comments.splice(index, 1)
        // 更新状态
        this.setState({comments})
    }

    render() {

        const {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">
                    <div className="row">
                        <CommentAdd addComment={this.addComment}/>
                        <CommentList comments={comments} deleteComment={this.deleteComment}/>
                    </div>
                </div>
            </div>
        );
    }
}
  • comment-add.jsx
import React,{Component} from 'react'
import PropsTypes from 'prop-types'

export default class CommentAdd extends Component{

    static propsTypes={
        addComment:PropsTypes.func.isRequired
    }

    state = {
        usename:'',
        content:''
    }

    // 点击提交事件
    handleSubmit = (event) => {
        //1. 收集数据,并封装为comment对象
        const comment = this.state
        //2. 更新状态
        this.props.addComment(comment)
        //3.清除数据
        this.setState({
            username:'',
            content:''
        })
        // 阻止事件的默认行为(提交)
        event.preventDefault()
        //数据在那个组件,更新数据的行为就应该在那个组件

    }
    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-4">
                <form className="form-horizontal">
                    <div className="form-group">
                        <label>用户名</label>
                        <input type="text" className="form-control" placeholder="用户名" name="username"
                               value={username} onChange={this.handleNameChange}/>
                    </div>
                    <div className="form-group">
                        <label>评论内容</label>
                        <textarea className="form-control" rows="6" placeholder="评论内容" name="content"
                                  value={content} onChange={this.handleContentChange}></textarea>
                    </div>
                    <div className="form-group">
                        <div className="col-sm-offset-2 col-sm-10">
                            <button className="btn btn-primary pull-right" onClick={this.handleSubmit}>提&nbsp;&nbsp;交</button>
                        </div>
                    </div>
                </form>
            </div>
        );
    }
}
  • comment-item

    • 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
        }
    
    
        handleDelete = () => {
            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">
                        <button className="btn btn-danger" onClick={this.handleDelete}>删除</button>
                    </div>
                    <p className="user"><span>{comment.username}</span>说:</p>
                    <p className="centence">{comment.content}</p>
                </li>
            );
        }
    }
    
    
    • commentItem.css
    li {
        transition: .5s;
        overflow: hidden;
    }
    
    .handle {
        width: 40px;
        border: 1px solid #ccc;
        background: #fff;
        position: absolute;
        right: 10px;
        top: 1px;
        text-align: center;
    }
    
    .handle a {
        display: block;
        text-decoration: none;
    }
    
    .list-group-item .centence {
        padding: 0px 50px;
    }
    
    .user {
        font-size: 22px;
    }
    
  • comment-list

    • comment-list.jsx
    import React, {Component} from 'react'
    import PropTypes from 'prop-types'
    
    import './comment-list.css'
    import CommentItem from "../comment-item/comment-item";
    
    export default class CommentList extends Component {
    
        //给组件类指定属性
        static proTypes = {
            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-8">
                    <h3 className="reply">评论回复:</h3>
                    <h2 style={{display}}>暂无评论,点击上方添加评论!!!</h2>
                    <ul className="list-group">
                        {
                            comments.map((comment, index) => <CommentItem comment={comment} key={index}
                                                                          deleteComment={deleteComment} index={index}/>)
                        }
                    </ul>
                </div>
            );
        }
    }
    
    
    • comment-list.css
    .reply {
        margin-top: 0px;
    }
    
  • 入口文件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="加载中..."/>
                <p className='react_p'>React app组件</p>
            </div>
        );
    }
}
  • index.js
import React from 'react'
import ReactDOM from 'react-dom'
import App from "./compontents/app/app";

ReactDOM.render(<App/>,document.getElementById('root'))

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值