React脚手架

  • 一、使用create-react-app创建react应用
    • 1、react脚手架
    • 2、创建项目并启动
    • 3、react脚手架项目结构
    • 4、功能界面的组件化编码流程(通用)
    • 5、用脚手架写一个简单示例
  • 二、组件的组合使用(综合实例)

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

1、react脚手架

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

2、创建项目并启动

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

实例演示

然后就等待一会儿就创建出来了

如果发现你创建的时间特别长,几分钟甚至十几分钟,那么可能是你的npm没有使用国内镜像,因为在创建react项目的时候,它有许多包需要从外网下载,所以会导致很慢,那怎么解决呢?运行下面两行命令就可以了。

打开你的cmd
首先运行npm config set registry https://registry.npm.taobao.org
然后运行npm config get registry验证是否成功
如果出现https://registry.npm.taobao.org/就表示成功了
然后你重新create-react-app 项目名就发现很快了

安装成功后,启动项目
出现下面这个的同时会自动在浏览器打开一个窗口

3、react脚手架项目结构



index.html页面的解析

<!DOCTYPE html>
<html lang="en"><head><meta charset="utf-8" /><!-- %PUBLIC_URL%代表public文件夹的路径 --><link rel="icon" href="%PUBLIC_URL%/favicon.ico" /><!-- 开启理想视口,用于做移动端网页的适配 --><meta name="viewport" content="width=device-width, initial-scale=1" /><!-- 用于配置浏览器页签+地址栏的颜色(仅支持安卓手机浏览器) --><meta name="theme-color" content="red" /><!-- 网站描述 --><metaname="description"content="Web site created using create-react-app"/><!-- 用于指定网页添加到手机(ios)主屏幕后的图标 --><link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" /><!-- 应用加壳时的配置文件 --><link rel="manifest" href="%PUBLIC_URL%/manifest.json" /><title>React App</title></head><body><!-- 若llq不支持js则展示标签中的内容 --><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body>
</html>

index.js文件解析

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';ReactDOM.render(//在App外侧包裹React.StrictMode,用来检查各个组件是否符合react的规范<React.StrictMode><App /></React.StrictMode>,document.getElementById('root')
);reportWebVitals();

4、功能界面的组件化编码流程(通用)

  1. 拆分组件: 拆分界面,抽取组件
  2. 实现静态组件: 使用组件实现静态页面效果
  3. 实现动态组件
    3.1 动态显示初始化数据
      1) 数据类型
      2) 数据名称
      3) 保存在哪个组件?
    3.2 交互(从绑定事件监听开始)

5、用脚手架写一个简单示例

目录结构

App.jsx

//创建“外壳”组件App
import React,{Component} from 'react'
import Hello from './components/Hello'
import Welcome from './components/Welcome'//创建并暴露App组件
export default class App extends Component{render(){return (<div><Hello/><Welcome/></div>)}
}

index.js

//引入react核心库
import React from 'react'
//引入ReactDOM
import ReactDOM from 'react-dom'
//引入App组件
import App from './App'//渲染App到页面
ReactDOM.render(<App/>,document.getElementById('root'))

Hello 下的index.jsx

import React, { Component } from 'react'
import hello from './index.module.css'export default class Hello extends Component {render () {return (<h1 className={hello.backColor}>hello-react</h1>)}
}

Hello 下的index.module.css
注意:这里这样搞是为了搞css模块化,避免类名相同,引起样式冲突覆盖,也可以直接使用less或者sass写css,也可以避免这样的问题
使用了css模块化就可以这样引入样式
import hello from './index.module.css'

.backColor {background-color: skyblue;
}

Welcome 下的index.jsx

import React, { Component } from 'react'
import './index.css'export default class Hello extends Component {render () {return (<h1 className="backColor">hello-react</h1>)}
}

Welcome 下的index.css

.backColor {background-color: skyblue;
}

二、组件的组合使用(综合实例)

目录结构

效果图

index.js

import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'ReactDOM.render(<App />, document.getElementById('root'))

App.jsx

import React, { Component } from 'react'
import './App.css'import Header from './components/Header'
import List from './components/List'
import Footer from './components/Footer'
export default class App extends Component {state = {todos: [{ id: 1, name: '吃饭', done: true },{ id: 2, name: '睡觉', done: true },{ id: 3, name: '敲代码', done: false }]}addTodo = (todoObj) => {const { todos } = this.stateconst newTodos = [todoObj, ...todos]this.setState({ todos: newTodos })}updateTodo = (id, done) => {const { todos } = this.stateconst newTodos = todos.map(item => {if (id === item.id) {return { ...item, done: done }} else {return item}})this.setState({ todos: newTodos })}deleteTodo = (id) => {const { todos } = this.stateconst newTodos = todos.filter(item => {return id !== item.id})this.setState({ todos: newTodos })}checkedAll = (doneStatu) => {const { todos } = this.stateconst newTodos = todos.map((item) => {return { ...item, done: doneStatu }})this.setState({ todos: newTodos })}deleteChecked = () => {const { todos } = this.stateconst newTodos = todos.filter(item => {return item.done === false})this.setState({ todos: newTodos })}render () {const { todos } = this.statereturn (<div className="todo-container"><div className="todo-wrap"><Header addTodo={this.addTodo} /><List todos={todos} updateTodo={this.updateTodo} deleteTodo={this.deleteTodo} /><Footer todos={todos} checkedAll={this.checkedAll} deleteChecked={this.deleteChecked} /></div></div>)}
}

App.css

/*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;
}

Header中的index.jsx

import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { nanoid } from 'nanoid'
import './index.css'export default class Header extends Component {static propTypes = {addTodo: PropTypes.func.isRequired}handleKeyUp = (event) => {console.log("ddd");const { keyCode, target } = eventif (keyCode !== 13) returnif (target.value.trim() === '') {alert('输入不能为空')return}//准备好一个todo对象const todoObj = { id: nanoid(), name: target.value, done: false }//将todoObj传递给Appthis.props.addTodo(todoObj)target.value = ''}render () {return (<div className="todo-header"><input type="text" placeholder="请输入你的任务名称,按回车键确认" onKeyUp={this.handleKeyUp} /></div>)}
}

Header中的index.css

/*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);
}

List中的index.jsx

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((item) => {return <Item key={item.id} {...item} updateTodo={updateTodo} deleteTodo={deleteTodo} />})}</ul>)}
}

List中的index.css

/*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;
}

Item中的index.jsx

import React, { Component } from 'react'import './index.css'export default class Item extends Component {state = {mouse: false}handleMouse = (flag) => {return () => {console.log(flag)this.setState({ mouse: flag })}}handleChecked = (id) => {return (event) => {this.props.updateTodo(id, event.target.checked)}}deleteTodo = (id) => {if (window.confirm('确定删除吗?')) {this.props.deleteTodo(id)}}render () {console.log(this.props);const { mouse } = this.stateconst { id, name, done } = this.propsreturn (<li style={{ backgroundColor: mouse ? '#ddd' : 'white' }} onMouseEnter={this.handleMouse(true)} onMouseLeave={this.handleMouse(false)}><label><input type="checkbox" checked={done} onChange={this.handleChecked(id)} /><span>{name}</span></label><button onClick={() => this.deleteTodo(id)} className="btn btn-danger" style={{ display: mouse ? 'block' : 'none' }}>删除</button></li>)}
}

Item中的index.css

/*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;
}

Footer中的index.jsx

import React, { Component } from 'react'import './index.css'export default class Footer extends Component {checkedAll = (event) => {console.log(event.target.checked);this.props.checkedAll(event.target.checked)}deleteSelected = () => {this.props.deleteChecked()}render () {const { todos } = this.props// const newTodos = todos.filter(item => {//   return item.done === true// })// const selectCount = newTodos.lengthconst doneCount = todos.reduce((pre, current) => {if (current.done === true) {return pre + 1} else {return pre + 0}}, 0)const sum = todos.lengthreturn (<div className="todo-footer"><label><input type="checkbox" checked={doneCount === sum && sum !== 0 ? true : false} onChange={this.checkedAll} /></label><span><span>已完成{doneCount}</span> / 全部{sum}</span><button className="btn btn-danger" onClick={this.deleteSelected}>清除已完成任务</button></div>)}
}

Footer中的index.css

/*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;
}

案例总结以及注意点

1.拆分组件、实现静态组件,注意:className、style的写法

2.动态初始化列表,如何确定将数据放在哪个组件的state中?

1)、某个组件使用:放在其自身的state中
2)、某些组件使用:放在他们共同的父组件state中(官方称此操作为:状态提升)

3.关于父子之间通信:
1).【父组件】给【子组件】传递数据:通过props传递
2).【子组件】给【父组件】传递数据:通过props传递,要求父提前给子传递一个函数

4.注意defaultChecked 和 checked的区别,类似的还有:defaultValue 和 value

input的checked和defaultChecked的区别,defaultChecked只在第一次有效,如果页面初始化之后,需要进行一些操作(例如勾选未勾选的复选框,当全部已经勾选的时候,希望这个全部的复选框也勾选,这个时候就不能使用defaultChecked,因为defaultChecked只在页面初始化时起作用)
但是用了checked就必须用onChange

5.状态在哪里,操作状态的方法就在哪里

下一篇 脚手架配置代理在这里
脚手架配置代理

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

  1. React学习笔记三 脚手架生成的index.js内容简介

    React脚手架生成的index.js内容简介 import React from 'react'; import ReactDOM from 'react-dom'; import App from ...

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

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

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

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

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

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

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

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

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

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

  7. React学习笔记 - 组件Props

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

  8. React学习(十)-React中编写样式CSS(styled-components)

    虽互不曾谋面,但希望能和你成为笔尖下的朋友 以读书,技术,生活为主,偶尔撒点鸡汤 不作,不敷衍,意在真诚吐露,用心分享 点击左上方,可关注本刊 撰文 | 川川 VX-ID:suibichuanji 点 ...

  9. React学习(六)-React中组件的数据-state

    虽互不曾谋面,但希望能和你成为笔尖下的朋友 以读书,技术,生活为主,偶尔撒点鸡汤 不作,不敷衍,意在真诚吐露,用心分享 点击左上方,可关注本刊 撰文 | 川川 ID:suibichuanji 点击下方 ...

最新文章

  1. 各种经典透镜投影模型
  2. lucene DocValues——没有看懂
  3. Socket编程(C语言实现)—— 为什么流式传输类似于管道?不区分边界?
  4. canva画图 图片居中裁剪_Canvas裁剪图片(截选框可拖拽)
  5. office word 开发
  6. DES和RSA算法的java实现
  7. 计算机一级应用考试题,办公软件应用计算机一级考试试题
  8. UI设计师必知:link和@import引用css文件方法的区别
  9. Linux中对进程的管理
  10. window.location和document.location的区别分析
  11. Trie树的C++实现
  12. [RK3399][Android7.1] Pinctrl的默认配置
  13. 五个金念什么_5个火读什么???还有5个水 5个木 5个土 5个金
  14. SpringBoot项目整合JasperReport报表生成PDF并下载
  15. 10只狗怎么来判断1000瓶药水中哪个有毒
  16. 【大数据】Hadoop 体系(五)
  17. #踩过的坑# 企业微信被封了怎么办?
  18. Vim指令对应的英语全称
  19. pytorch 支持amd显卡吗_2020-06-12 ubuntu系统下,pytorch安装
  20. 程序员的回忆录(1)-起点

热门文章

  1. 数学基础差真的没救了吗?
  2. 我最怕30岁以后,还要靠投简历找工作
  3. 研发游戏引擎那么难,为什么还应该砸钱去干?
  4. 53套免费的扁平化Icon设计
  5. k8s部署kube-prometheus
  6. element ui 图片加载失败_解决Element UI - el-image 图片初始化加载失败问题
  7. 给路由器配置Telnet远程登录
  8. 数据化运营19 传播(上):如何打造千万级的私域运营体系?
  9. 将一个数组每三个分成一组
  10. android armv8 手机,智能手机已经将Arm的Armv8架构用于其处理器