react脚手架日常学习记录
文章目录
- 一、 初始化React脚手架
- 1、基础相关
- 2、创建项目
- 3、脚手架项目结构
- 4、流程相关
- 二、 规范相关
- 三、 input相关
- 四、 react父子组件传值
- 五、 TodoList案例小总结
- 六、 reduce方法复习
- 八、 react脚手架配置代理
- 1、配置单个代理
- 2、配置多个代理
- 3、react配置完setupProxy.js然后运行项目无法访问
- 九、 消息订阅-发布机制
- 1、下载
- 2、使用
- 十、 Fetch
- 十一、 React路由
- 1、SPA的理解
- 2、路由的基本使用
- 2.1、下载react-router-dom:
- 2.2、组件引入
- 2.3、使用
- 3、路由的相关API
- 3.1、Link
- 3.2、Route
- 3.3、NavLink
- 3.4、Switch
- 3.5、Redirect
- 4、嵌套路由
- 5、向路由组件传递参数数据
- 5.1、params参数
- 5.2、search参数
- 5.3、state参数
- 6、编程式路由导航
- 7、lazyLoad
- 8、BrowserRouter与HashRouter的区别
- 8、其它
- 6.1、Fragment
- 6.2、Context
- 6.3、组件优化
- 6.4、render props
- 6.5、错误边界
- 6.6、封装NavLink
- 6.7、解决样式丢失问题
- 6.8、qs的用法
- 九、antd的按需引入+自定主题
一、 初始化React脚手架
1、基础相关
react提供的脚手架库:create-react-app
项目整体技术架构:react + webpack + es6 + eslint
脚手架开发项目特点:模块化, 组件化, 工程化
2、创建项目
(1)全局安装:
npm i -g create-react-app
(2)切换到需要创建项目的目录后,创建项目文件夹:
create-react-app hello-react
(3)进入项目文件夹:
cd hello-react
(4)启动项目:
npm start
3、脚手架项目结构
public ---- 静态资源文件夹
favicon.icon ------ 网站页签图标
index.html -------- 主页面
logo192.png ------- logo图
logo512.png ------- logo图
manifest.json ----- 应用加壳的配置文件
robots.txt -------- 爬虫协议文件
src ---- 源码文件夹
App.css -------- App组件的样式
App.js --------- App组件
App.test.js ---- 用于给App做测试
index.css ------ 样式
index.js ------- 入口文件
logo.svg ------- logo图
reportWebVitals.js
— 页面性能分析文件(需要web-vitals库的支持)
setupTests.js
---- 组件单元测试的文件(需要jest-dom库的支持)
4、流程相关
1、react通过index.js(入口文件),引入react及react-dom/client库,引入页面组件APP.js,通过ReactDOM.render渲染组件到页面(根组件root,即index.html文件中页面元素)
2、App.js文件中,通过es6中的export default默认导出函数类组件APP
细节:注意类名用className,而不是class
3、APP外侧包裹React.StrictMode,可以帮忙检查代码不合理的地方
4、index.html文件中,%PUBLIC_URL%
代表public这个文件夹的路径
二、 规范相关
1、命名注意事项
(1)、文件夹名字用大写开头
(2)、区分是否是组件js文件还是函数方法js文件:
a. 组件用jsx结尾
b. 组件js文件用大写开头,函数方法js文件用小写开头
2、样式跟其它组件冲突的解决办法
1、css的情况下:样式名称+module命名,接收时import hello from ‘./index.module.css’,使用{hello.title}接收时import
2、使用less,用嵌套即可
.box{.title{}
}
3、生成代码快捷片段
安装ES7+ React/Redux/React-Native snippets插件后
rcc:生成类式组件 --react class component
rfc:生成函数式组件 --react function component
三、 input相关
1、判断input是否是回车按键
event.keyCode === 13
2、input框类型为checkbox时,获取是否选中值
event.target.checked
3、input框类型为text时,获取输入值
event.target.value
4、input框鼠标移入移出事件
鼠标移入:onMouseEnter
鼠标移出:onMouseLeave
四、 react父子组件传值
1、父传子
父组件在绑定的子组件上直接传属性值,注意尽量用{…obj}的形式
子组件用解构赋值取props中对应的值即可
2、子传父
父组件在绑定的子组件绑定的属性上传的为函数
子组件通过this.props.addTodo(todoObj)
给父组件传值,addTodo为父组件中在子组件上绑定的属性名
五、 TodoList案例小总结
1、拆分组件、实现静态组件,注意:className,style的写法
2、动态初始化列表,如何确定将数据放在哪个组件的state中?
--某个组件使用:放在自身的state中
--某些组件使用:放在他们共同的父组件state中(官方称此操作为:状态提升)
3、关于父子组件通信:
1. 【父组件】给【子组件】传递数据:通过props传递
2. 【子组件】给【父组件】传递数据:通过props传递,要求父组件提前给子组件传递一个函数
4、注意 defaultChecked 和 checked 的区别,类似的还有 defaultValue 和 value
5、状态在哪里,操作状态的方法就在哪里
六、 reduce方法复习
array.reduce(function(accumulator, currentValue, currentIndex, array), initialValue)
reduce用法
八、 react脚手架配置代理
1、配置单个代理
在package.json中追加如下配置
"proxy":"http://localhost:5000"
说明:
- 优点:配置简单,前端请求资源时可以不加任何前缀。
- 缺点:不能配置多个代理。
- 工作方式:上述方式配置代理,当请求了3000不存在的资源时,那么该请求会转发给5000 (优先匹配前端资源)
2、配置多个代理
第一步:创建代理配置文件
在src下创建配置文件:src/setupProxy.js
编写setupProxy.js配置具体代理规则:
const proxy = require('http-proxy-middleware')module.exports = function(app) {app.use(proxy('/api1', { //api1是需要转发的请求(所有带有/api1前缀的请求都会转发给5000)target: 'http://localhost:5000', //配置转发目标地址(能返回数据的服务器地址)changeOrigin: true, //控制服务器接收到的请求头中host字段的值/*changeOrigin设置为true时,服务器收到的请求头中的host为:localhost:5000changeOrigin设置为false时,服务器收到的请求头中的host为:localhost:3000changeOrigin默认值为false,但我们一般将changeOrigin值设为true*/pathRewrite: {'^/api1': ''} //去除请求前缀,保证交给后台服务器的是正常请求地址(必须配置)}),proxy('/api2', { target: 'http://localhost:5001',changeOrigin: true,pathRewrite: {'^/api2': ''}})) }
说明:
- 优点:可以配置多个代理,可以灵活的控制请求是否走代理。
- 缺点:配置繁琐,前端请求资源时必须加前缀。
3、react配置完setupProxy.js然后运行项目无法访问
可能会因为版本出现此问题,解决办法为从http-proxy-middleware
单个引入createProxyMiddleware
const { createProxyMiddleware } = require("http-proxy-middleware");
// const proxy = require("http-proxy-middleware");module.exports = function (app) {app.use(createProxyMiddleware("/api1", {target: "http://192.168.1.13:5000",changeOrigin: true,pathRewrite: { "^/api1": "" },}));
};
九、 消息订阅-发布机制
工具库:PubSubJS
作用:可用于组件间传值
1、下载
npm install pubsub-js --save
2、使用
- import PubSub from ‘pubsub-js’ //引入
- PubSub.subscribe(‘delete’, function(data){ }); //订阅
- PubSub.publish(‘delete’, data) //发布消息
- PubSub.unsubscribe(token) //组件销毁时取消订阅消息
例如:兄弟组件传值(Search组件向List组件传值)
注意:一般在组件销毁时需要取消订阅
十、 Fetch
注意:fetch方法返回的为promise对象,且需要用try…catch处理异常情况
特点:etch: 原生函数,不再使用XmlHttpRequest对象提交ajax请求;但兼容性较差,老版浏览器可能不支持
try {const response = await fetch(`/api1/search/users2?q=${keyWord}`)const data = await response.json()PubSub.publish('atguigu', {isLoading: false, users: data.items})
} catch (error) {PubSub.publish('atguigu', {isLoading: false, err: error.message})
}
相关文档:
fetch官方文档
传统Ajax已死,Fetch永生
十一、 React路由
1、SPA的理解
单页Web应用(single page web application,SPA)。
整个应用只有一个完整的页面。
点击页面中的链接不会刷新页面,只会做页面的局部更新。
数据都需要通过ajax请求获取, 并在前端异步展现。
2、路由的基本使用
2.1、下载react-router-dom:
npm install --save react-router-dom
2.2、组件引入
import { Link, Route } from 'react-router-dom'
2.3、使用
1)、在index.html中,引入BrowserRouter,且App外层包裹路由
import {BrowserRouter} from 'react-router-dom'
// import {HashRouter} from 'react-router-dom'const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(<BrowserRouter><App/></BrowserRouter>)
2)、编写路由链接 – 在React中靠路由链接实现切换组件
<Link className="list-group-item" to='/about'>About</Link>
3)、注册路由
<Route path='/about' component={About}/>
3、路由的相关API
3.1、Link
作用: 导航不需要高亮显示
属性:
to:跳转路径
标签体为特殊的属性children
<Link to='/about'>About</Link>
3.2、Route
作用: 注册路由,默认为模糊匹配
属性:
path:组件跳转匹配的路径
component:跳转路径对应的组件
exact:true 开启严格匹配模式(一般不用,会导致二级路由出现问题)
<Route path='/about' component={About}/>
<Route exact path='/about' component={About}/>// 开启严格匹配模式
3.3、NavLink
作用: 导航需要高亮显示,会默认高亮加上active样式,可以通过activeClassName
自定义高亮央视
属性:
to:跳转路径
activeClassName:自定义高亮样式
标签体为特殊的属性children
<NavLink activeClassName='atguigu' to='/about'>About</NavLink>
3.4、Switch
作用: 当一个路径对应两个组件时,会都显示,外层加上Switch可以使路由只显示相同路径下的第一个组件
<Switch><Route path='/home' component={Home}/><Route path='/home' component={Test}/>
</Switch>
3.5、Redirect
作用: 当找不到对应组件时,默认跳转组件路径
属性:
to:组件跳转路径
<Redirect to='/about' />
4、嵌套路由
二级路由要添加上一级路由的路径
// news的上一级路由为home,前面必须加上/home
<NavLink to='/home/news'>News</NavLink>
<Route path='/home/news' component={News} />
5、向路由组件传递参数数据
5.1、params参数
1) 向路由组件传递params参数
<Link to={'/home/message/detail/tom/18'}>标签体内容</Link>
2) 声明接收params参数
<Route path='/home/message/detail/:name/:age' component={Detail}></Route>
3) 路由组件接收参数(this.props.match.params
)
const {name, age} = this.props.match.params
5.2、search参数
1) 向路由组件传递search参数
<Link to={'/home/message/detail/?name=tom&age=18'}>标签体内容</Link>
2)search参数无需声明接收,正常注册路由即可
<Route path='/home/message/detail' component={Detail}></Route>
3) 路由组件接收参数
需要借助qs将拿到的字符串参数改为对象
import qs from 'qs' //安装依赖为npm install qs --saveconst {search} = this.props.location
const {name, age} = qs.parse(search.substring(1)) // 截掉问号
5.3、state参数
1) 向路由组件传递state参数
<Link to={{pathname:'/home/message/detail', state:{name:'tom', age: 18}}}>标签体内容</Link>
2)state参数无需声明接收,正常注册路由即可
<Route path='/home/message/detail' component={Detail}></Route>
3) 路由组件接收参数
const {name, age} = this.props.location.state || {}
6、编程式路由导航
借助this.prosp.history
对象上的API对操作路由跳转、前进、后退
this.prosp.history.push()
this.prosp.history.replace()
this.prosp.history.goBack()
this.prosp.history.goForward()
this.prosp.history.go()
replaceShow = (id,title) => {// replace跳转+携带params参数// this.props.history.replace(`/home/message/detail/${id}/${title}`)// replace跳转 + 携带query参数// this.props.history.replace(`/home/message/detail?id=${id}&title=${title}`)// replace跳转 + 携带state参数this.props.history.replace('/home/message/detail', {id:id, title: title})
}pushShow = (id, title) => {// push跳转+携带params参数// this.props.history.push(`/home/message/detail/${id}/${title}`)// push跳转+携带query参数// this.props.history.push(`/home/message/detail?id=${id}&title=${title}`)// push跳转+携带state参数this.props.history.push('/home/message/detail', {id:id, title: title})
}
7、lazyLoad
//1.通过React的lazy函数配合import()函数动态加载路由组件 ===> 路由组件代码会被分开打包
const Login = lazy(()=>import('@/pages/Login'))//2.通过<Suspense>指定在加载得到路由打包文件前显示一个自定义loading界面
<Suspense fallback={<h1>loading.....</h1>}><Switch><Route path="/xxx" component={Xxxx}/><Redirect to="/login"/></Switch>
</Suspense>
8、BrowserRouter与HashRouter的区别
1.底层原理不一样:
BrowserRouter使用的是H5的history API,不兼容IE9及以下版本。
HashRouter使用的是URL的哈希值。
2.path表现形式不一样
BrowserRouter的路径中没有#,例如:localhost:3000/demo/test
HashRouter的路径包含#,例如:localhost:3000/#/demo/test
3.刷新后对路由state参数的影响
(1).BrowserRouter没有任何影响,因为state保存在history对象中。
(2).HashRouter刷新后会导致路由state参数的丢失!!!
4.备注:HashRouter可以用于解决一些路径错误相关的问题。
8、其它
6.1、Fragment
加上后可以不用必须有一个真实的DOM根标签了,类似于vue中的telement
<Fragment><Fragment>
<></>
6.2、Context
一种组件间通信方式, 常用于【祖组件】与【后代组件】间通信
1、创建Context容器对象
const XxxContext = React.createContext()
2、渲染子组时,外面包裹xxxContext.Provider, 通过value属性给后代组件传递数据
<xxxContext.Provider value={数据}>子组件
</xxxContext.Provider>
在应用开发中一般不用context, 一般都用它的封装react插件
3、后代组件读取数据
//第一种方式:仅适用于类组件 static contextType = xxxContext // 声明接收contextthis.context // 读取context中的value数据//第二种方式: 函数组件与类组件都可以<xxxContext.Consumer>{value => ( // value就是context中的value数据要显示的内容)}</xxxContext.Consumer>
6.3、组件优化
优化点:
1、只要执行setState(),即使不改变状态数据, 组件也会重新render() ==> 效率低
2、只当前组件重新render(), 就会自动重新render子组件,纵使子组件没有用到父组件的任何数据
解决:使用PureComponent,PureComponent重写了shouldComponentUpdate(), 只有state或props数据有变化才返回true
import React, { PureComponent } from 'react'
export default class Parent extends PureComponent {}
6.4、render props
类似于vue中slot
1、children props(组件间无法传递数据)
<A><B>xxxx</B>
</A>
{this.props.children}
2、render props
<A render={(data) => <C data={data}></C>}></A>
A组件: {this.props.render(内部state数据)}
C组件: 读取A组件传入的数据显示 {this.props.data}
6.5、错误边界
错误边界(Error boundary):用来捕获后代组件错误,渲染出备用页面(只能捕获后代组件生命周期产生的错误)
使用:getDerivedStateFromError配合componentDidCatch
// 生命周期函数,一旦后台组件报错,就会触发
static getDerivedStateFromError(error) {console.log(error);// 在render之前触发// 返回新的statereturn {hasError: true,};
}componentDidCatch(error, info) {// 统计页面的错误。发送请求发送到后台去console.log(error, info);
}
6.6、封装NavLink
作用:多个Link有一样样式时,会导致代码冗余,如以下情况
import React, { Component } from 'react'
import { NavLink } from 'react-router-dom'export default class MyNavLink extends Component {render() {// 标签体内容通过this.props.children接收return (<NavLink activeClassName='atguigu' className="list-group-item" {...this.props}/>)}
}
6.7、解决样式丢失问题
index.html文件中,若通过./的方式引入css文件,可能会导致样式丢失
解决办法:
1)、去掉.(推荐)
<link rel="stylesheet" href="/css/bootstrap.css">
2)、使用%PUBLIC_URL%(推荐)
<link rel="stylesheet" href="%PUBLIC_URL%/css/bootstrap.css">
3)、使用HashRouter包裹App(不推荐)
import {HashRouter} from 'react-router-dom'
<HashRouter><App/>
</HashRouter>
6.8、qs的用法
安装: npm install qs --save
引入:import qs from 'qs'
使用:
let obj = {name:'tom', age:18} // key=value&key=value urlencoden编码形式字符串
console.log(qs.stringify(obj)) //name=tom&age=18let str = "carName='奔驰'&price=99"
console.log(qs.parse(str)) // {carName: '奔驰', price: 99}
补充:key=value&key=value
这种格式称之为urlencoden编码字符串
九、antd的按需引入+自定主题
1.安装依赖:
yarn add react-app-rewired customize-cra babel-plugin-import less less-loader
2.修改package.json
"scripts": {"start": "react-app-rewired start","build": "react-app-rewired build","test": "react-app-rewired test","eject": "react-scripts eject"
},
3.根目录下创建config-overrides.js
//配置具体的修改规则
const { override, fixBabelImports,addLessLoader} = require('customize-cra');
module.exports = override(fixBabelImports('import', {libraryName: 'antd',libraryDirectory: 'es',style: true,}),addLessLoader({lessOptions:{javascriptEnabled: true,modifyVars: { '@primary-color': 'green' },}}),
);
4.备注:
1)、不用在组件里亲自引入样式了,即:import 'antd/dist/antd.css’应该删掉
2)、若上述写法报错,则根据官方文档改为最新的按需引入方式即可(或者降低less-loader版本)
官方文档:antd按需引入样式+自定义主题官方文档
react脚手架日常学习记录相关推荐
- 日常学习记录——pycharm+tensorflow简单图像识别
日常学习记录--pycharm+tensorflow简单图像识别 写在前面 1 实验代码 2 实验结果 2.1 测试集的正确率 2.2 单个预测结果 2.3 集体预测结果 总结与标记 写在前面 使用p ...
- 日常学习记录——决策树根节点的选择
日常学习记录--决策树根节点的选择 1 数据集 2 根节点的选择 1 信息增益的计算 2 计算单列属性信息熵 3 计算各属性信息增益 3 存在问题与反思 1 数据集 本例使用的是经过预处理的模糊数据集 ...
- 日常学习记录一_mcufly串口下载
MCUFLY下载 环境是STM32f407 第一部分 操作步骤 板卡部分注意板卡的引脚,boot0接高电平,boot1接低电平. 电脑打开mcufly,电脑通过usb串口线,连接STM32的USART ...
- Java开发指导记录表_java 日常学习记录
前言:记录自己初学java 遇到的问题. 环境(win10 开始安装的IDEA,net 开发者 )学习网址:http://how2j.cn/stage/14.html (不是打广告) 特别是对初学 ...
- 日常学习记录——目前学习记录总结
1 已了解或已实践内容 1. 机器学习算法相关 常用的两个算法库:sklearn.imbalanced-learn. 决策树算法--基于信息熵.基于信息增益.基于Gini指数 模糊决策树算法--决策树 ...
- 日常学习记录——tkinter显示excel表格中的数据
1 场景需求 点击西瓜数据按钮新建一个窗口,该窗口默认读取程序设定好的数据文件,并显示在创建好的表格控件中,如果需要导入新的文件可以通过更改文件按钮进行更改,点击显示按钮会将原来表格控件中的数据清除, ...
- 日常学习记录——使用Visio2019绘制思维导图
需求描述 使用Visio2019绘制如下思维导图: 解决方法: "更多形状" "软件和数据库" "软件" "语言级别形状" ...
- React学习笔记3:React脚手架
使用create-react-app创建react应用 react脚手架 xxx脚手架: 用来帮助程序员快速创建一个基于xxx库的模板项目 包含了所有需要的配置(语法检查.jsx编译.devServe ...
- React脚手架学习笔记
一.前端工程的复杂化 如果我们只是开发几个小的demo程序,那么永远不需要考虑一些复杂的问题: 比如目录结构如何组织划分: 比如如何管理文件之间的相互依赖: 比如如何管理第三方模块的依赖: 比如项目发 ...
最新文章
- mysql密码正确却提示错误, 不输入密码反而能登录
- 网站域名检测是否被QQ/微信拦截工具
- 慕课网vue播放器最新QQ音乐api
- 从社交网络图的edgelist得到adj
- 浅谈 css的zoom属性
- Hadoop2.x与Hadoop3.x的默认端口变化
- 工业机器人协作控制研究
- 马云说:“未来是大数据的时代”
- 转载:关于NERO7刻录软件的使用
- 付费获取密码平台原理
- Android gif 动画
- 【影像组学】CT数据与MRI数据
- java公众号订单查询
- turtle库制作简单动画和总结
- 中国石油大学《客户关系管理》第一次在线作业
- 【大数据人工智能】统计学入门——数据科学领域最需要了解的统计学基础概念
- java发现杯_达内第二届发现杯软件大赛(JAVA A卷)试题.docx
- 高度纹理图像中的mura缺陷——holcon
- 收银台模块php课程设计,【基于PHP+MySQL的美发店收银系统的设计与实现最终版材料】...
- Java工程师修炼之路(校招总结)
热门文章
- QCustomPlot之瀑布图(十五)
- dw连接mysql内部服务器错误_用dw(dreamweaver)开发asp.net,连接数据库时出现“http错误500,服务器内部错误”的解决方法 | 学步园...
- Java的日期与时间java.time.Duration的简介说明
- 简单表单提交php教程,php教程之表单提交实例_PHP教程
- RTSP视频绘图 -- 笔记
- [闪存2.1.3] 固态硬盘闪存的物理学原理_NAND Flash 的读、写、擦工作原理
- 机器学习12:分类 Classification
- JPEG 编解码器 霍夫曼编码
- 常用的邮箱服务器(SMTP、POP3)地址、端口
- msp430f2618写16位双通道 SPI接口DA DAC8552 精确度超高