文章目录

  • 一、 初始化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"

说明:

  1. 优点:配置简单,前端请求资源时可以不加任何前缀。
  2. 缺点:不能配置多个代理。
  3. 工作方式:上述方式配置代理,当请求了3000不存在的资源时,那么该请求会转发给5000 (优先匹配前端资源)

2、配置多个代理

  1. 第一步:创建代理配置文件

    在src下创建配置文件:src/setupProxy.js
    
  2. 编写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': ''}}))
    }
    

说明:

  1. 优点:可以配置多个代理,可以灵活的控制请求是否走代理。
  2. 缺点:配置繁琐,前端请求资源时必须加前缀。

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、使用

  1. import PubSub from ‘pubsub-js’ //引入
  2. PubSub.subscribe(‘delete’, function(data){ }); //订阅
  3. PubSub.publish(‘delete’, data) //发布消息
  4. 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脚手架日常学习记录相关推荐

  1. 日常学习记录——pycharm+tensorflow简单图像识别

    日常学习记录--pycharm+tensorflow简单图像识别 写在前面 1 实验代码 2 实验结果 2.1 测试集的正确率 2.2 单个预测结果 2.3 集体预测结果 总结与标记 写在前面 使用p ...

  2. 日常学习记录——决策树根节点的选择

    日常学习记录--决策树根节点的选择 1 数据集 2 根节点的选择 1 信息增益的计算 2 计算单列属性信息熵 3 计算各属性信息增益 3 存在问题与反思 1 数据集 本例使用的是经过预处理的模糊数据集 ...

  3. 日常学习记录一_mcufly串口下载

    MCUFLY下载 环境是STM32f407 第一部分 操作步骤 板卡部分注意板卡的引脚,boot0接高电平,boot1接低电平. 电脑打开mcufly,电脑通过usb串口线,连接STM32的USART ...

  4. Java开发指导记录表_java 日常学习记录

    前言:记录自己初学java 遇到的问题. 环境(win10  开始安装的IDEA,net 开发者  )学习网址:http://how2j.cn/stage/14.html (不是打广告) 特别是对初学 ...

  5. 日常学习记录——目前学习记录总结

    1 已了解或已实践内容 1. 机器学习算法相关 常用的两个算法库:sklearn.imbalanced-learn. 决策树算法--基于信息熵.基于信息增益.基于Gini指数 模糊决策树算法--决策树 ...

  6. 日常学习记录——tkinter显示excel表格中的数据

    1 场景需求 点击西瓜数据按钮新建一个窗口,该窗口默认读取程序设定好的数据文件,并显示在创建好的表格控件中,如果需要导入新的文件可以通过更改文件按钮进行更改,点击显示按钮会将原来表格控件中的数据清除, ...

  7. 日常学习记录——使用Visio2019绘制思维导图

    需求描述 使用Visio2019绘制如下思维导图: 解决方法: "更多形状" "软件和数据库" "软件" "语言级别形状" ...

  8. React学习笔记3:React脚手架

    使用create-react-app创建react应用 react脚手架 xxx脚手架: 用来帮助程序员快速创建一个基于xxx库的模板项目 包含了所有需要的配置(语法检查.jsx编译.devServe ...

  9. React脚手架学习笔记

    一.前端工程的复杂化 如果我们只是开发几个小的demo程序,那么永远不需要考虑一些复杂的问题: 比如目录结构如何组织划分: 比如如何管理文件之间的相互依赖: 比如如何管理第三方模块的依赖: 比如项目发 ...

最新文章

  1. mysql密码正确却提示错误, 不输入密码反而能登录
  2. 网站域名检测是否被QQ/微信拦截工具
  3. 慕课网vue播放器最新QQ音乐api
  4. 从社交网络图的edgelist得到adj
  5. 浅谈 css的zoom属性
  6. Hadoop2.x与Hadoop3.x的默认端口变化
  7. 工业机器人协作控制研究
  8. 马云说:“未来是大数据的时代”
  9. 转载:关于NERO7刻录软件的使用
  10. 付费获取密码平台原理
  11. Android gif 动画
  12. 【影像组学】CT数据与MRI数据
  13. java公众号订单查询
  14. turtle库制作简单动画和总结
  15. 中国石油大学《客户关系管理》第一次在线作业
  16. 【大数据人工智能】统计学入门——数据科学领域最需要了解的统计学基础概念
  17. java发现杯_达内第二届发现杯软件大赛(JAVA A卷)试题.docx
  18. 高度纹理图像中的mura缺陷——holcon
  19. 收银台模块php课程设计,【基于PHP+MySQL的美发店收银系统的设计与实现最终版材料】...
  20. Java工程师修炼之路(校招总结)

热门文章

  1. QCustomPlot之瀑布图(十五)
  2. dw连接mysql内部服务器错误_用dw(dreamweaver)开发asp.net,连接数据库时出现“http错误500,服务器内部错误”的解决方法 | 学步园...
  3. Java的日期与时间java.time.Duration的简介说明
  4. 简单表单提交php教程,php教程之表单提交实例_PHP教程
  5. RTSP视频绘图 -- 笔记
  6. [闪存2.1.3] 固态硬盘闪存的物理学原理_NAND Flash 的读、写、擦工作原理
  7. 机器学习12:分类 Classification
  8. JPEG 编解码器 霍夫曼编码
  9. 常用的邮箱服务器(SMTP、POP3)地址、端口
  10. msp430f2618写16位双通道 SPI接口DA DAC8552 精确度超高