react
基础语法
1.初始化项目-脚手架
1.打开终端
2.输入 npx create- react-app 项目名
3.cd 项目名 进入项目目录
4.npm start 启动项目
5.打开浏览器查看
2.文件目录
两个关键词库,react reactDOM
调用reactDOM的create创建实例,然后调用render函数进行渲染
strictmode是严格模式,可以进行功能审查和排错
根组件
主推函数式
3.jsx语法
js结合html
3.1换行时,小括号一定要有,建议一直加上不论多少行
3.2只能有一个根元素
解决:
1.多包一层容器
2.使用jsx提供的空标签
3.3 html标签一定要正确闭合
不论单标签还是双标签
4.插值
插值可以用在:标签内容和标签属性
举例:
注意此时title不能加双引号,不然会变成纯文本
4.1条件渲染
传统结构创建写法:
无法正常实现
jsx正确写法:
4.2列表渲染
箭头函数简写了,用map比较多,因为有返回值
修改如下:
Fragment标签
针对循环生成时有多个根标签的情况,这样写才能加key,如果用空标签是不可以的
5.事件
jsx中属性通常以驼峰形式命名
如果要获取事件相关信息,可以在函数接收e参数,然后内部即可使用,跟dom操作非常类似
6.useState状态处理
内容无法更改
函数式组件无法直接响应式
要用useState,是一个函数
先传入初始值,然后可以解构出来两个值
6.1对象形式的状态
对象形式不可以直接渲染
下面是一种错误写法:
setData是把传入的值直接替换旧值,而不是局部替换
进行对象更新,需要全部写全:
优化写法:使用展开运算符
但注意新属性要写在后面,不然会被覆盖
6.2 数组的状态操作
其实跟对象一样
删除id为2的元素,要用js处理
2.组件通信与插槽
组件通信
react组件两种类型:dom组件,react组件
dom组件:react支持的所有html和svg标签
类似react属性的功能在react中称为props
1.1为dom组件设置props
props:属性,道具
dom组件的类属性
类名设置:className
不可以直接写class
dom组件的style属性
注意是两个花括号
可以把里面的对象当成一整个变量值来理解
带-的要写成驼峰
更好的写法:
新的用法:
- jsx的展开语法
所有属性预制为一个对象
img一定要设置alt,所有alt不能提出来
注意:这个展开操作并不是es6的展开运算符
大括号是jsx的语法,告诉编译器:这里面的内容是js,需要执行后再渲染
是将当前对象的键值放到位置上,不能在一个没有容器的地方直接使用
就是展开一定要包一个花括号在外面
就是把一个对象的属性拿出来,然后又放到一个对象字面量中,组成一个新的对象
1.2 react组件
1.父向子props传值
固定内容
对组件内容进行定制,父组件请求数据,创建子article组件,传入数据给子组件
组件会自动接收几个参数,第一个就是props,也就是从父组件传递过来的信息
解构写法更简洁:
以及可以传类似状态值到子组件进行渲染,在这里写active默认为true,不写就是false
2.react组件中展开props
请求拿过来的时候做一个分级
然后传值过来,这里articledata写错了,应该直接解构detaildata
3.将jsx作为props传递(组件插槽)
子组件封装的时候预留了一个值叫children,父组件直接传递,就会直接拿到子组件开始和结束标签内的所有内容,进行渲染
- 进阶:向多个位置传递jsx
footer给一个默认值,因为如果这个值可选,然后没有传值进来,会报错的
传值进来,依次接收即可
这种有点类似具名插槽
注意:所有props都是单向的,父组件传递过来的值对于子组件来说都只是可读的,不要直接修改
如果子组件要向父组件传递数据
- 子组件向父组件传值
在父组件定义自定义属性---事件
同级组件进行传值
借助父组件进行中转
1.使用Context进行多级组件传值
usecontext可以找到createcontext的值
一层一层往上找
第一级section把修改的值传给了第二级section,以此类推
3.React hooks
useReducer
Reducer用于统一管理状态的操作方式
写一个reducer函数,两个参数,第一个state函数表示当前reducer函数要管理的状态是哪一个,第二个action 表示要对这个状态进行一些什么操作
不用state而改用reducer
userreducer传入两个参数,第一个是reducer函数,第二个是状态的默认值
解出来两个参数,类似usestate
第一个是状态当前值, 第二个是用来进行状态修改的一个触发器,是一个函数值
此时dispatch里面传入的就是action
2.useRef
1记录状态变更之前的上一个值
不是给本身赋值,而是对useref返回的对象的current属性进行赋值
普通变量的生命周期与单次渲染绑定,所以使用普通变量接收会导致每次count值改变,普通变量的值就会跟着刷新。而useRef的值是与组件的整个生命周期绑定,所以不会刷新
2可以用ref来引用页面中的标签乃至其他组件
引用组件:
此时子组件不能通过普通函数定义,比如function child
要用函数表达式的方式来进行定义, 并且要用一个react的方法forwardref来包裹
子组件接收参数,参数二进行ref的一些设置
父组件调用子组件的方法,需要提前useimperativehandle
3.useEffect
副作用函数
react要求所有的函数式组件都是纯函数,同样的输入应该有同样的输出
默认在组件渲染重新执行
使用第二个参数设置什么状态重新执行副作用函数
传空数组意味着无论什么状态都不再重新触发
当传入count,count变化时,副作用函数会重新执行
4.useMemo -use memory
用于数据缓存
点击更新count值, dosomemath会打印,但是内部的值没有变化,也就是-3不变,经过复杂计算的数据也不变
外部变更导致内部计算重新执行。这样的变更毫无意义
此时使用usememo,只有依赖的值发生变化,函数才会执行,也就是说类似于计算属性
5.useCallback
缓存的是函数
父组件操作导致了子组件的重新渲染:
react自己的memo方法,可以把一个组件变为一个记忆组件
如果向子组件传入 的props没有出现变化,那么将不会受 到父组件更新的影响
但此时这样还无法实现
因为onclick函数
当父组件重新渲染,handleclick变成了一个新函数,函数之间如果不是相同引用,js认为是新的函数
如果能在父组件重新渲染时,handleclick不被重新创建,即传入给子组件的函数prop不变化是同一个,那么子组件就不会被重新渲染
缓存函数:usecallback
两个参数,第二个参数是依赖数组