React 脚手架
脚手架:用来帮助程序员快速创建一个基于某种库的模板项目。其包括:
- 所有需要的配置
- 指定的所有的依赖
- 可以直接安装/编译/运行的简单效果
React 提供了用于创建react项目的脚手架库:create-react-app,使用这个脚手架开发项目具有“模块化、组件化、工程化”特点。
**工程化:**例如通过一个命令就能对项目进行打包、编译,从而提升效率。
通常项目的整体技术架构:react+webpack+es6+eslint(代码检查工具)
**package.json:**描述当前项目(应用)相关信息的文件。
关注3点:
- 包的标识
- 当前应用涉及到的依赖
- 当前应用是如何运行与打包
dependencies :运行时依赖 devDependencies:开发时依赖,编译打包时需要,运行时不需要
**react-scripts 😗*将架构家所有编译打包等的命令都封装在这个文件中,包括webpack。
官方脚手架创建与启动项目命令:
npm install -g create-react-app create-react-app my-app cd my-app npm start
npm root -g 查看全局下载根目录
主要在目录下的src文件夹进行开发。
- start 编译并启动项目
- bulid 生成打包文件(构建)
- 入口文件 index.js
默认暴露:export default xxx ,import引入时不需要加花括号{}
重写一个简单demo,把src目录下的文件删除,只保留logo.svg文件
表单练习-拆分组件与实现静态组件,写一个评论管理
步骤:
1、拆分组件,将每个组件命名,如app.jsx,comment-add.jsx,comment-list.jsx,comment-item.jsx
2、然后创建一个文件夹component,里面再新建每个组件的文件夹,在每个组件的文件夹下放.jsx,与.css文件。
如图所示:
然后就可以在这些文件夹中写静态组件。
3、实现静态组件
index.js
import React from 'react'; import ReactDOM from 'react-dom'; import App from './components/app/app'; ReactDOM.render(<App />, document.getElementById('root'));
app.jsx
import React, { Component } from 'react' import CommentAdd from '../component-add/component-add' import CommentList from '../component-list/component-list' class App extends Component { //给组件对象添加指定的state属性 state = { comments:[ {username: 'tom',content : 'React哈哈哈'}, {username: 'yue',content : 'React啊啊啊'}, {username: 'kang',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; 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={this.state.comments} deleteComment={this.deleteComment}/> </div> </div> ) } } export default App
comment-add.jsx
import React, { Component } from 'react' import PropTypes from 'prop-types' class CommentAdd extends Component { //给组件类添加属性 static propTypes = { addComment: PropTypes.func.isRequired } //给组件对象添加属性 state = { username: '', content: '' } //使用箭头函数,监听时不用进行bind() handleSubmit = () => { //搜集数据,并封装为comment对象 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"> <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="评论内容" onChange={this.handleContentChange} value={content}></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.handleSubmit}>提交</button> </div> </div> </form> </div> ) } } export default CommentAdd
comment-list.jsx
import React, { Component } from 'react' import PropTypes from 'prop-types' import CommentItem from '../component-item/component-item' import './commentList.css' class ComponentList extends Component { //给组件类添加属性 static protoTypes = { 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"> <h3 className="reply">评论回复:</h3> <h2 style={{display}}>暂无评论,点击左侧添加评论!!!</h2> <ul className="list-group"> { comments.map((c,index)=><CommentItem comment={c} key={index} deleteComment={deleteComment} index={index}/>) } </ul> </div> ) } } export default ComponentList
commentList.css
.reply { margin-top: 0px; }
component-item.jsx
import React, {Component} from 'react' import PropTypes from 'prop-types' import './componentitem.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"> <a href="javascript:;" onClick={this.handleDelete}>删除</a> </div> <p className="user"><span >{comment.username}</span><span>说:</span></p> <p className="centence">{comment.content}</p> </li> ) } }
componentitem.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; }