初学React

6,416 阅读13分钟

一、概览

为什么要学react

  • 原生JS操作DOM频繁,频率低(DOM-API操作UI)
  • 使用JS直接操作DOM,浏览器会进行大量的重绘重排
  • 原生JS没有组件化编码方案,复用率低

React优点

  • 采用组件化模式、声明式编码,提高开发效率及组件复用率。
  • 在React Native中可以使用React语法进行移动端开发。
  • 使用虚拟DOM+优秀的Diffing算法,尽量减少与真实DOM的交互

文件构成

image.png 按需引入image.png 写的是jsx,所以type='text/babel' image.png

关于虚拟DOM

  • 1.本质是Object类型的对象(一般对象)
  • 2.虚拟DOM比较“轻”,真实DOM比较“重”,因为虚拟DOM是React内部在用,无需真实DOM上那么多的属性。
  • 3.虚拟DOM最终会被React转化成真实DOM,呈现在页面上

jsx语法规则

  • 1.定义虚拟DOM时,不要写引号
  • 标签中混入JS表达式要用{} image.png
  • 类名指定不用class,要用className
  • 内联样式,要用style={{key:value}}
  • 只有一个根标签
  • 标签必须闭合
  • 标签首字母
    • (1)若小写字母开头,则将标签转为html中同名元素,若html中无该标签对应的同名元素则报错。
    • (2)若大写字母开头,react就去渲染对应的组件,若组件无定义,则报错。

二、react面向组件编程

组件

函数式--简单组件

用不了state,refs image.png

函数式组件使用props

image.png

类式组件--复杂组件

回归类的基础知识

类的构造器不是必须写的,要对实例进行一些初始化的操作,如添加指定属性时才写。 image.png 类中可以直接写赋值语句,let a = 1报错,这也是初始化的一种方法,可以不用写在构造器中。 image.png super--继承父类的构造器,子类如果写了构造器,必须写super(必须写第一行),不然报错。 image.png 类中所定义的方法,都是放在了类的原型对象上,供实例去使用。

定义类式组件

image.png

类式组件中的props

类中的构造器几乎不用写。构造器是否接收props,是否传递给super,取决于:是否希望在构造器中通过this访问props。(不接收不传递,可以在访问器中访问props,不能访问this.props)

绑定点击事件

之前的原始事件都 要写成驼峰命名法。绑定的回调函数不要写() image.png 类里边定义方法,自动开启局部严格模式 image.png

组件实例三大核心

state

  • 构造器调用一次,render调用n+1一次(n是状态更新的次数,1是初始化),changeWeather点几次调用几次。
  • 使用bind修改this指向为实例
  • 想要修改state的值,需要通过重要的API--setState进行更新 image.png 简化版--赋值语句+箭头函数解决this丢失问题 image.png 总结:state值是对象(可以包含多个key-value组合);组件被称为状态机,通过更新组件的state来更新对应的页面显示

setState的两种形式

setState更改状态的动作是异步的,如果想获取更改后状态的值,需要写在第二个参数--回调函数中。 image.png image.png

props

基本使用--在标签内写key-value。年龄应该写age={19},这样就是number类型,不然是字符串类型 image.png

基础回顾

{...对象} 一层的对象,就是属于深拷贝,多层才是浅拷贝。{...对象,属性:值},复制并更改属性值/增加 image.png image.png

引入PropTypes

image.png 15.5版本以后,直接使用PropTypes.XXX,之前使用react.PropTypes,defaultProps是默认。 image.png 函数类型要写func。 image.png props是只读的 image.png 简写 image.png 总结:每个组件对象都有props属性,组件标签的所有属性都保存在props中。

作用:通过标签属性从组件外部向组件内传递变化的数据。

注意:组件内部不要修改props数据。

refs

字符串形式的refs

不被推荐 image.png

回调形式的refs

ref中自动传递参数:当前节点c,然后通过this.input1=c把它挂载到组件实例上 image.png image.png 第一行是内联模式,第二行是绑定函数的方式 image.png

create Ref

适应几个ref就要创建几个ref(createRef) image.png

事件处理

  • 1.通过onXxx指定事件处理函数。
    • a.react使用的是二次封装后的事件,不是原生DOM事件--为了更好的兼容性
    • b.事件是通过事件委托方式处理的(委托给组件最外层的元素)--为了高效
  • 2.通过event.target得到发生事件的DOM元素对象--不要过度使用ref 如果触发事件的元素和发生改变的元素是同一个,则可以使用event.target image.png

收集表单数据

非受控组件

现用现取 image.png

受控组件

现在state中设置初始状态(Vue中的双向数据绑定) image.png

优化

高阶函数
  • 常见的高阶函数:Promise/setTimeout/arr.map()等等。
  • 如果一个函数符合2个规范中的任何一个,那么该函数就是高阶函数
    • 若A函数,接受的参数是一个函数
    • 若A函数,调用的返回值依然是个函数

补充:对象[变量名]==>变量值:属性值;折叠不起来就写#region和#endregion image.png 在标签体中绑定事件写了小括号,这个绑定事件的回调是其返回值。把return写成函数形式,可以接收到event,在return后的函数体中写事件逻辑。 image.png

函数的柯里化

函数的柯里化:通过函数调用继续返回函数的方式,实现多次接收参数最后统一处理的函数编码形式。 高阶函数那个案例也是柯里化。 image.png 不使用柯里化的效果 image.png

生命周期

引出

卸载组件API image.png

旧版

走setState那条路就是正常更新,shouldComponentUpdate是控制组件更新的阀门,返回布尔值,默认是true。forceUpdate()强制更新:直接就改,不管阀门shouldComponentUpdate()的false react生命周期(旧).png image.png

  • componentDidMount():一般在这个钩子中做一些初始化的事,例如:开启定时器、发送网络请求、订阅消息。
  • componentWillUnmount():一般在这个钩子中做一些收尾的事,例如:关闭定时器、取消订阅消息。

新版

  • will(除了WillUnmount)要加unsafe_前缀,因为未来要异步渲染,可能会出现矛盾。
  • getDerivedStateFromProps适用于罕见的用例,即state值在任何时候都取决于props。
  • getSnapshotBeforeUpdate image.png react生命周期(新).png image.png

key

image.png

三、脚手架

安装

全局安装脚手架npm i create-react-app -g 创建xxx文件夹create-react-app xxx 安装yarnnpm install -g yarn 降级npm install react@17.x react-dom@17.x --save 18的creatRoot只是和Compont一样是react上的属性,creatRoot是React的属性,可以直接导入也可以像导入Component一样直接导入creatRoot

文件

image.png image.png image.png

四、tolist组件学到的点

  • 组件拆分 class拆成className,style内联样式拆成style={{}}
  • props传递参数时,直接用展开运算符接(两行是一个作用) image.png
  • 默认勾不勾选,只能执行一次(有很多问题) image.png
  • 子传父,在父组件中写回调函数拿到传递的数据 image.png image.png 在子组件 image.png
  • 鼠标移动改变样式 image.png
  • 基础:把b的值改成3 image.png
  • 勾选状态数据流HTML->state,孙给父组件传,孙->子->父。在父组件中写回调: image.png 在子组件中写回调,不要写回调: image.png 在孙组件: image.png
  • 📢注意:状态在哪里,操作状态的方法就在哪里
  • 限制props传递参数的类型
    • 下载库image.png
    • 引入image.png
    • 在子组件中image.png
  • reduce使用 filter过滤,reduce统计 image.png

五、Ajax与react

前置

  1. react本身只关注于页面,并不包含发送Ajax请求的代码
  2. 前端需要通过Ajax请求与后台交互(json数据)
  3. react应用中需要第三方Ajax库、或者自己封装
  4. 常见Ajax请求库:jQuery(比较重),axios(promise风格,可以在浏览器端和node服务器端使用,轻量级)

安装

  • 安装axios image.png

跨域

跨域的本质是Ajax引擎 image.png

解决:

  • 在package.json中配置代理(只能配置一个)优先匹配前端资源,没有再发请求 image.png
  • 推荐:在src下配置文件setupProxy.js可以配置多个代理,灵活控制请求是否走代理。 这里注意一下,高版本的 http-proxy-middleware const {createProxyMiddleware} = require('http-proxy-middleware') image.png image.png
const proxy = require('http-proxy-middleware')

const {createProxyMiddleware} = require('http-proxy-middleware')

module.exports = function (app) {

app.use(

createProxyMiddleware('/api1',{

target:'http://localhost:5000',

changeOrigin:true,

pathRewrite:{'^/api1':''}

}),

createProxyMiddleware('/api2',{

target:'http://localhost:5001',

changeOrigin:true,

pathRewrite:{'^/api2':''}

})

)

}

六、github组件学到的点

  • 解构幅值的连续写法--获取this.keyWordElement.value image.png 连续解构幅值并重命名image.png
  • 没有跨域问题,已经用cors解决了 image.png
  • 子组件改变父组件的很多状态,父组件写一个函数,子组件通过解构幅值传递改变。 子组件: image.png 父组件: image.png
  • 三元表达式连写 image.png

消息订阅与发布--兄弟组件间通信

下载及引入

image.png image.png 谁需要谁订阅: image.png 取消订阅: image.png 发布('发布名',发布内容): image.png

fetch

不用下载,原生函数 image.png

七、react路由

SPA:单页面多组件。

什么是路由?

路由就是一个key-value映射关系,key为路径,value可能是function或component

路由分类

  1. 后端路由:
    • value是function,用来处理客户端提交的请求
    • 注册路由:router.get(path,function(req,res))
    • 工作过程:当node接收到一个请求时,根据请求路径找到匹配的路由,调用路由中的函数来处理请求,返回响应数据
  2. 前端路由:
    • 浏览器路由,value是component,
    • 注册路由<Route path='/test' component={Test}>
    • 工作过程:当浏览器的path变为/test时,当前路由组件就会变成Test组件
    • 前端路由实现的基石:BOM 身上的history image.png

安装和引入

5版本npm i react-router-dom@5

使用

在index里包裹 <BrowserRouter> image.png 在APP中 image.png PS:也可以使用带#的HashRouter image.png

路由组件和一般组件

image.png 路由组件的三个固定属性 image.png

点击加类名高亮

引入 image.png 默认加active,所以active时可以省略activeClassName image.png

封装MyNavLink

标签体内容其实也通过props传递过去了 image.png image.png 封装的MyNavLink image.png

Switch

引入Switch image.png

刷新样式丢失问题

1.使用绝对路径 image.png 2.把.给删掉(常用) image.png

模糊匹配和严格匹配

默认开启模糊匹配

顺序也要一致 image.png

严格匹配exact

可直接写exact,也可以写exact={true}====>尽量不要开启 image.png

重定向Redirect

引入 image.png 使用:写在所有路由的最下方,所有路由匹配不上时,就去重定向的to image.png

push模式和replace模式

push模式默认开启,即有痕模式。replace模式写replace,无痕模式

多级路由/嵌套路由/二级路由

要带着前面的父级路由 image.png

参数类型

ajax:

  • query
  • params
  • body
    • urlencode
    • json

路由组件传参

传递params参数

导航区 image.png 路由子组件 image.png

传递search参数

qs

路由子组件import qs from 'qs'老版本import qs from 'querystring'

对象和urlencoded相互转换 image.png

使用

导航区 image.png 路由子组件 image.png

传递state参数

传递的参数地址栏中隐藏

导航区 image.png 路由子组件 image.png

总结

state清除浏览器缓存会丢掉参数 image.png

编程式路由导航

image.png image.png image.png

一般组件使用路由组件的API

引入 image.png 使用 image.png

BrowserRouter和HashRouter

image.png

路由的懒加载

image.png

八、UI组件库

🔗

ant.design/index-cn image.png

下载及引入

image.png

引入(自己找一下路径,不同版本都不一样)image.png

按需引入

跟着官网指示 image.png

九、redux

是什么?

image.png

什么时候使用?

image.png

原理图

redux原理图.png

三个核心概念

image.png image.png

应用

下载4.0.5版本image.png

精简版

提示createStore弃用的,改用import { legacy_createStore as createStore} from 'redux' 就没有提示了。 image.png image.png 在组件中 引入 image.png image.png 可以在组件写subscribe image.png 也可以在index中写 image.png 总结 image.png

完整版

ES6补充

想要返回一个对象,不能直接写=>{...},这样会默认是函数,返回undefined,要用小括号包裹 image.png

应用

文件构成image.png 防止写错单词 image.png image.png image.png image.png

同步和异步action

返回object类型是同步,返回function类型的是异步。

中间件下载image.png

在store中引入image.png store的dispatch方法会判断:传入值是函数还是对象,如果是函数,那就给这个函数传参数,参数是store的dispatch方法并且执行这个函数。在action文件中:异步action调用同步action: image.png 组件中: image.png 总结: image.png

十、react-redux

原理图

react-redux模型图.png

下载及引入

下载image.png image.png APP中,引入容器 image.png UI组件 image.png image.png image.png 容器组件 image.png connect和谁做关联就传什么UI,第一个参数传递状态,第二个参数传递方法 image.png

总结

image.png

优化

从代码角度优化

image.png

从API角度优化

mapDispatchToProps可以返回一个函数,也可以返回一个对象。对象值是action,react-redux自动帮你dispatch image.png index不用开启检测,connect自动检测。使用provider可以不用在APP中一个一个的传store。 image.png image.png APP image.png

从文件角度优化

把UI组件和容器组件合成一个jsx,UI组件直接定义类,然后在容器组件中使用。 image.png 文件构成 image.png

总结

image.png

多组件共享状态

文件构成

image.png store中汇总,合并后的状态是个对象!!! image.png count组件内用person的状态 image.png image.png 注意:如果用preState.push方法,redux检测不到变化,因为是浅比较,引用地址值没变(比较的是两个对象的存储位置,也就是浅比较法,所以,当我们 reducer 直接返回旧的 state 对象时,Redux 认为没有任何改变,从而导致页面没有更新。) image.png

多个组件时文件构成

都在store中引入reducer太多了,新建一个index文件汇总,KV一致省略 image.png store image.png

纯函数

image.png 回顾一下高阶函数 image.png

redux 开发者工具

下载image.png 在store中 image.png

十一、打包

image.png

小服务器npm i serve -g 启动image.png 以xxx文件为根目录启动一台服务器,serve xxx

十二、hooks

16.8版本之后,函数式组件新出的功能。 image.png

Sate Hook

调用1+n(状态更新的次数)次。 image.png

effect Hook

image.png 不写[]就是检测所有状态,相当于didmount,didupdate.[]写谁就检测谁,不写就是didmount image.png

useRef Hook

专人专用 image.png image.png image.png image.png

十三、Fragment

类似vue中的template.也可以直接写空标签<></>(不能写任何属性)。fragment可以写key属性。 image.png

十四、context

一种组件间通信的方式,常用于祖组件后代组件间通信

使用

一般不用,一般都用它封装的插件 image.png image.png image.png

十五、组件优化

component

image.png image.png 引用地址没有变,PureComponent是浅对比,检测不到,同理unshift之类操作原数组的也检测不到。 image.png

十六、render props

回顾:标签体内容传递到chilren里,直接写不显示 image.png 就是Vue的插槽技术 image.png image.png

十七、Error Boundary

写在父组件中 image.png

十八、组件间通信总结

image.png

十九、React Router6

一些改变

navigate image.png image.png image.png 自定义类名高亮不能直接写了 image.png

路由表

在src下创建一个文件夹routers/index.js image.png image.png image.png

二级路由

image.png image.png end image.png

传参

params参数

路由表中占位 image.png 传参 image.png 接收参数--新hook image.png 也可以用useMatch(url)获得

search

不需要占位 image.png 传参 image.png 接收参数--新hook:注意获得的是数组类型,第一个参数.get解构幅值,第二个参数负责更新数据(用的很少) image.png 也可以用useLocation()获得

state

不需要占位

传参 image.png 接收参数--useLocation(),解构幅值的连续写法 image.png

编程式导航

image.png 只能写state,params和search不能写 image.png 前进和后退 image.png

useInRouterContext()

image.png

useNavigationType()

image.png

uesOutlet()

image.png

useResolvedPath()

image.png