使用create-react-app创建react应用

react脚手架

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

    • 包含了所有需要的配置(语法检查、jsx编译、devServer…)
    • 下载好了所有相关的依赖
    • 可以直接运行一个简单效果
  • react提供了一个用于创建react项目的脚手架库: create-react-app
  • 项目的整体技术架构为: react + webpack + es6 + eslint
  • 使用脚手架开发的项目的特点: 模块化, 组件化, 工程化

创建项目并启动

  • 第一步,全局安装:npm i -g create-react-app
  • 第二步,切换到想创项目的目录,使用命令:create-react-app hello-react
  • 第三步,进入项目文件夹:cd hello-react
  • 第四步,启动项目:npm start

react脚手架项目结构

功能界面的组件化编码流程

  1. 拆分组件: 拆分界面,抽取组件
  2. 实现静态组件:使用组件实现静态页面效果
  3. 实现动态组件
    • 动态显示初始化数据

      • 数据类型
      • 数据名称
      • 保存在哪个组件?
    • 交互(从绑定事件监听开始)

组件的组合使用-TodoList

TodoList演示项目的效果图如下所示:

根据上图所示,将该项目分为四个组件,分别为App组件、Header组件、Footer组件、List组件以及Item组件。其中,App组件是最外层的组件,负责管理所有其他组件,Header组件是输入文本框相关功能,Footer组件是底部的相关功能,List组件是数据列表相关的功能,Item组件是List列表中每行的功能。

App组件代码

样式
/*base*/
body {background: #fff;
}.btn {display: inline-block;padding: 4px 12px;margin-bottom: 0;font-size: 14px;line-height: 20px;text-align: center;vertical-align: middle;cursor: pointer;box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);border-radius: 4px;
}.btn-danger {color: #fff;background-color: #da4f49;border: 1px solid #bd362f;
}.btn-danger:hover {color: #fff;background-color: #bd362f;
}.btn:focus {outline: none;
}.todo-container {width: 600px;margin: 0 auto;
}
.todo-container .todo-wrap {padding: 10px;border: 1px solid #ddd;border-radius: 5px;
}
js代码
import React, { Component, useEffect } from 'react'import Header from './components/Header'
import List from './components/List'
import Footer from './components/Footer'import './App.css';
export class App extends Component {state = {todos: [{ id: '001', name: '学习', done: true },{ id: '002', name: '游戏', done: true },{ id: '003', name: '打麻将', done: false },{ id: '004', name: '看电影', done: true }]}addTodo = (todoObj) => {const { todos } = this.statethis.setState({ todos: [todoObj, ...todos] });}/*** 用于更新一个todo对象* * @param {*} id * @param {*} done */updateTodo = (id, done) => {//获取状态中的todosconst { todos } = this.stateconst newTodos = todos.map((todoObj) => {if (todoObj.id === id) {return { ...todoObj, done }} else {return todoObj}})this.setState({ todos: newTodos })}/*** 删除选中的todo对象* * @param {*} id */deleteTodo = (id) => {const { todos } = this.stateconst newTodos = todos.filter((todoObj) => {return todoObj.id !== id})this.setState({ todos: newTodos })}checkAllTodo = (done) => {const { todos } = this.stateconst newTodos = todos.map((todoObj) => {return { ...todoObj, done }})this.setState({ todos: newTodos });}clearAllDone = () => {const { todos } = this.stateconst newTodos = todos.filter((todoObj) => {return !todoObj.done})this.setState({ todos: newTodos });}render() {const { todos } = this.statereturn (<div><div className="todo-container"><div className="todo-wrap"><Header addTodo={this.addTodo} /><Listtodos={todos}updateTodo={this.updateTodo}deleteTodo={this.deleteTodo}/><Footertodos={todos}checkAllTodo={this.checkAllTodo}clearAllDone={this.clearAllDone}/></div></div></div>)}
}export default App

Header组件代码

样式
/*header*/
.todo-header input {width: 560px;height: 28px;font-size: 14px;border: 1px solid #ccc;border-radius: 4px;padding: 4px 7px;}.todo-header input:focus {outline: none;border-color: rgba(82, 168, 236, 0.8);box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);}
js代码
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import './index.css'
import { nanoid } from 'nanoid'export default class Header extends Component {// 对接收的props进行:类型、必须要性的限制static propTypes = {addTodo: PropTypes.func.isRequired}/*** 键盘事件的回调* * @param {*} event */handleKeyUp = (event) => {const { keyCode, target } = event//判断是否是回车按键if (keyCode !== 13) returnif (target.value.trim() === '') {alert("输入不能为空")return}//定义一个todo对象const todoObj = { id: nanoid(), name: target.value, done: false }this.props.addTodo(todoObj)target.value = ''}render() {return (<div className="todo-header"><inputtype="text"placeholder="请输入你的任务名称,按回车键确认"onKeyUp={this.handleKeyUp}/></div>)}
}

Footer组件代码

样式
/*footer*/
.todo-footer {height: 40px;line-height: 40px;padding-left: 6px;margin-top: 5px;}.todo-footer label {display: inline-block;margin-right: 20px;cursor: pointer;}.todo-footer label input {position: relative;top: -1px;vertical-align: middle;margin-right: 5px;}.todo-footer button {float: right;margin-top: 5px;}
js代码
import React, { Component} from 'react'
import './index.css'export default class Footer extends Component {handleCheckAll = (event) => {this.props.checkAllTodo(event.target.checked)}handleClearAllDone = () => {this.props.clearAllDone()}render() {const { todos } = this.propsconsole.log(todos)const doneTotal = todos.reduce((pre, todo) => pre + (todo.done ? 1 : 0), 0)const total = todos.lengthreturn (<div className="todo-footer"><label><inputtype="checkbox"onChange={this.handleCheckAll}checked={doneTotal === total && total !== 0 ? true : false}/></label><span><span>已完成{doneTotal}</span> / 全部{total}</span><buttonclassName="btn btn-danger"onClick={this.handleClearAllDone}>清除已完成数据项</button></div>)}
}

Item组件代码

样式
/*item*/
li {list-style: none;height: 36px;line-height: 36px;padding: 0 5px;border-bottom: 1px solid #ddd;
}li label {float: left;cursor: pointer;
}li label li input {vertical-align: middle;margin-right: 6px;position: relative;top: -1px;
}li button {float: right;display: none;margin-top: 3px;
}li:before {content: initial;
}li:last-child {border-bottom: none;
}
js代码
import React, { Component } from 'react'
import './index.css'export default class Item extends Component {//标识鼠标移入、移出state = { mouse: false }/*** 鼠标移入、移出的回调* @param {*} flag */handleMouse = (flag) => {return () => {this.setState({ mouse: flag })}}/*** 勾选、取消勾选某一个todo的回调* * @param {*} id */handleCheck = (id) => {return (event) => {this.props.updateTodo(id, event.target.checked)}}/*** 删除一个todo的回调*  * @param {*} id */handleDelete = (id) => {if (window.confirm('确定删除吗?')) {this.props.deleteTodo(id)}}render() {const { id, name, done } = this.propsconst { mouse } = this.statereturn (<listyle={{ backgroundColor: mouse ? '#ddd' : 'white' }}onMouseEnter={this.handleMouse(true)}onMouseLeave={this.handleMouse(false)}><label><inputtype="checkbox"checked={done}onChange={this.handleCheck(id)}/><span>{name}</span></label><buttononClick={() => this.handleDelete(id)}className="btn btn-danger"style={{ display: mouse ? 'block' : 'none' }}>删除</button></li>)}
}

List组件代码

样式
/*main*/
.todo-main {margin-left: 0px;border: 1px solid #ddd;border-radius: 2px;padding: 0px;}.todo-empty {height: 40px;line-height: 40px;border: 1px solid #ddd;border-radius: 2px;padding-left: 5px;margin-top: 10px;}
js代码
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import Item from '../Item'
import './index.css'export default class List extends Component {static propTypes = {todos: PropTypes.array.isRequired,updateTodo: PropTypes.func.isRequired,deleteTodo: PropTypes.func.isRequired}render() {const { todos, updateTodo, deleteTodo } = this.propsreturn (<ul className="todo-main">{todos.map(todo => {return (<Itemkey={todo.id}{...todo}updateTodo={updateTodo}deleteTodo={deleteTodo}/>)})}</ul>)}
}

该演示项目的完整代码详见:todo演示代码

React学习笔记3:React脚手架相关推荐

  1. React学习笔记一(React入门+JSX+脚手架)

    文章目录 1. React介绍和特点 1.1 React是什么 1.2 React的特点 2. React的开发依赖 2.1 React的三个依赖 2.2 Babel和React的关系 2.3 Rea ...

  2. React学习笔记六 React拓展 - SetState

    React拓展 - setState setState更新状态的两种写法 1.setState({}, [callback]) export default class Test extends Co ...

  3. react学习笔记1--基础知识

    什么是react A JAVASCRIPT LIBRARY FOR BUILDING USER INTERFACES[React是一个用于构建用户界面的JavaScript库.] React之所以快, ...

  4. react render没更新_web前端教程分享React学习笔记(一)

    web前端教程分享React学习笔记(一),React的起源和发展:React 起源于 Facebook 的内部项目,因为该公司对市场上所有 JavaScript MVC 框架,都不满意,就决定自己写 ...

  5. react组件卸载调用的方法_好程序员web前端培训分享React学习笔记(三)

    好程序员web前端培训分享React学习笔记(三),组件的生命周期 React中组件也有生命周期,也就是说也有很多钩子函数供我们使用, 组件的生命周期,我们会分为四个阶段,初始化.运行中.销毁.错误处 ...

  6. React学习笔记:入门案例

    React学习笔记:入门案例 React 起源于 Facebook 内部项目,因为市场上所有 JavaScript MVC 框架都不令人满意,公司就决定自己写一套,用来架设 Instagram 的网站 ...

  7. React学习笔记(五) 状态提升

    状态提升究竟是什么东西呢?别急,下面让我们一步一步来看看究竟要怎么使用状态提升 假设我们有这样一个需求,提供两个输入框(分别属于两个组件),保证输入框里面的内容同步 好,下面我们先来封装一个输入框组件 ...

  8. React学习笔记 - 组件Props

    React Learn Note 4 React学习笔记(四) 标签(空格分隔): React JavaScript 三.组件&Props 组件可以将UI切分成一些独立的.可复用的部件,这样你 ...

  9. React学习手册 React学习手册中文版 React学习手册pdf React学习手册中文版pdf

    React学习手册,React学习手册PDF React学习手册中文版,React学习手册中文版PDF React学习手册,React学习手册pdf,React学习手册-14393339,React学 ...

最新文章

  1. 4.事务提交过程,事务基本概念,Oracle中的事务生命周期,保存点savepoint,数据库的隔离级别
  2. 六年级计算机课学什么时候,六年级信息技术《进一步了解计算机》教学设计
  3. 2021年3月15日_读书|总结笔记目录
  4. Linux性能调优、Linux集群与存储等
  5. pip与conda简述
  6. 平衡二叉树操作的演示
  7. Linux下使用SSH连接远端服务器技术总结
  8. CS229学习笔记(2)多变量线性回归
  9. oracle+快速客户端安装方法,ORACLE简易客户端安装与使用方法
  10. 进入大厂的面试经验详细总结(P7 拿 offer)
  11. java mvc 登陆_SpringMVC实现用户登录实例
  12. paip.截屏功能流程说明
  13. 微擎支付返回商户单号_易宝支付哪个平台扣的,被易宝支付扣款怎么办
  14. 【Mac】Mac 键盘快捷键大全
  15. python分离gif_python图片合成与分解gif方法
  16. 识别合格ToB产品经理
  17. 历史大盘跌停记录,2016大盘跌停原因
  18. python中average什么意思,Python3——numpy中mean和average的区别
  19. vue手动封装分页组件
  20. 端口隔离是什么?为什么需要端口隔离、如何实现端口隔离?一文解惑

热门文章

  1. Java开发四年的程序员想再学习一门语言,该选着C还是Python呢?
  2. hooks 使用dva_Taro3 中使用dva
  3. Python绘制桑基图
  4. docker用gpu的参数_从零开始入门 K8s | GPU 管理和 Device Plugin 工作机制
  5. PTA基础编程题目集-6-1 简单输出整数
  6. 背包模型dp1:01背包,完全背包,多重背包的两大优化的详解
  7. map std 浮点数索引_std:map中的浮点键
  8. lookup函数和vlookup_5个实用案例告诉你,为什么说Lookup函数比vlookup更简单
  9. 解题报告(一)B、(CF453D) Little Pony and Elements of Harmony(FWT经典套路 + 任意模数 k 进制FWT + 快速幂)(2)
  10. 【网络流24题】B、太空飞行计划问题(最大权闭合图转最小割、最小割方案输出)