react学习

react

框架的选择

低代码、BI

前瞻性


 

bs 架构,网页 客户端去使用

react就是用来代替DOM的,dom操作,构建前端界面的

react-native  直接开发 ios,安卓,原生应用

虚拟dom,操作react,影响dom,中间人

现在的dom 和 当前的dom做比较看哪个发生了变化,做最小的修改

1、虚拟dom

2、兼容性

3、性能好,避免做一些多余的操作

声明式编程:结果为导向

命令式编程:过程为导向

基于组件开发,组件为最小单位  降低代码的耦合

支持服务器渲染,seo优化

快速,简单,易学

html的声明式模板写法,js的可编程能力

组件就是首字母大写的函数

一、第一课  核心库

react.js:核心库  react-dom.js:dom库

const div = React.createElement('div',{},'内容')  //用来创建一个React元素html

const root = ReactDOM.createRoot()

root.render(div)

二、第二课  react元素一旦创建就无法修改,只能通过新创建的元素进行替换,只有创建和替换

createElement() 用来创建一个React元素

参数1:html标签必须是小写

参数2:标签的属性,id,type,设置事件的时候要修改成驼峰命名法,()=>{}   className

参数3:内容

三、第三课  createRoot

createRoot 获取根元素,根元素就是React元素要插入的位置

render 用来将react元素渲染到根元素

       根元素中所有的内容都会被删除,被react元素所替换

       当重复调用render时,会将两次的渲染结果进行比较

           它会确保只修改那些发生变化的元素,对DOM做最少的修改

四、第四课  babel   jsx

script type="text/babel"  js代码被babel代理    babel.min.js

命令式编程

声明式编程:结果导向的编程  jsx需要被翻译成js代码,是React.createElement()的语法糖

jsx注意事项:

1、jsx不是字符串,不用加引号

2、jsx中html标签应该小写,react组件应该大写开头

3、jsx中有且只有一个根标签

4、jsx标签必须正确结束(自结束标签必须写 /)

5、在jsx中可以使用{}嵌入表达式,有值的语句就是表达式,在语句中是可以操作jsx中的

6、如果表达式是空值,布尔值,undefined,将不会显示

7、在jsx中,属性可以直接在标签中设置

      注意:class -> className

           style = {{'background':'red'}}

五、第五课  Dom渲染,diff算法

在react中我们操作的元素被称为react元素,并不是真正的原生DOM元素

每当我们调用root.render时,页面就会发生重新渲染

diff算法比较新元素和旧元素,并只对发生变化的元素进行修改

注意:

开发中一般会采用数据的id作为key

尽量不要使用元素的index作为key,当元素的顺序不会发生变化时,用索引做key也没有什么问题

六、第六课   react-scripts 项目打包

react-scripts:webpack,项目打包,测试服务器,

约定优于配置

public/index.html是首页的模板,webpack在编译文件时,会以index.html为模板生成index.html

import ReactDOM from 'react-dom/client'

npx react-scripts build

npx react-scripts start

七、第七课   函数式组件和类组件

函数式组件:

    函数组件就是一个返回jsx的普通函数

    组件的首字母必须是大写

类组件:

    类组件必须要继承react.component

    必须添加一个render方法

jsx的return写在一行是可以省略括号的,如果多行还是需要加上括号

八、第八课  事件传递

事件:通过属性需要使用驼峰命名法,属性值需要用回调函数

在react中,无法通过return false 取消默认事件,可以通过

event.preventDefault(取消默认行为)  

event.stopPropagation(取消事件的冒泡)

九、第九课   props  父传子

props 传递属性 是只读的,不能修改  上级向下级修改

父组件-》子组件   props

props.children:表示组件的标签体

tolocaleString('zh-CN',{month:'long'}) //2021/11/6   返回的是中文的十一月

十、第十课   useState 

state 组件状态

在react中,当组件渲染完毕之后再修改组件中的变量,不会使组件重新渲染

使用一个特殊变量state,当变量修改时,组件会自动重新渲染

state相当于一个变量,这个变量在react中进行了注册

react会监控这个变量的变化,当state发生变化时,会自动触发组件的重新渲染

当state的值是一个对象时,修改时是使用新的对象去替换已有对象,直接修改旧的state对象,由于对象还是那个对象,所以不会生效

在函数组件中,需要使用钩子函数useState  创建state

useState函数:返回一个数组,

     数组中的第一个元素是初始值,直接修改不会触发组件的重新渲染

     数组中的第二个元素是一个函数通常命名为setXxx,调用其修改state后会触发组件的重新渲染,并使用函数中的值作为新的state值

setState() 修改的是组件下一次渲染时的state值,它是异步的,合并执行

           当调用setState()需要用旧的state值时,一定要注意可能出现计算错误的情况,可通过setState()传递回调函数的形式来修改state的值

setState之后发生了什么?

       react会将传入的参数对象和组件当前的状态合并,触发调和过程(reconciliation),经过调和,会根据状态构建react元素树,重新渲染整个UI界面,自动计算新树和老树的差异,进行最小化重新渲染

const [count,setCount] = useState(1)

十一、第十一课   useRef

react中获取原生的DOM对象 useRef():创建一个容器,将容器设置为想要获取DOM对象元素的ref属性

钩子函数的注意事项:

   react的钩子函数只能用于函数组件或自定义钩子

   钩子函数只能直接在函数组件中调用

useRef()  返回的是一个普通的js对象  {current:null}  

我们创建的对象,组件每次重新渲染都会创建一个新对象

useRef()创建的对象,可以确保每次渲染获取到的都是同一个对象

当你需要一个对象不会因为组件的重新渲染而改变时,就可以使用useRef()

const h1Ref = useRef()

<h1 ref={h1Ref}></h1>

类组件  

this.setState() 修改state时,只会修改设置的属性

获取DOM对象:

   React.createRef()  创建属性存储DOM的对象

类组件的方法用箭头函数

十二、第十二课   portal传送门

portal:传送门

默认会作为父组件的后代渲染到页面中

可以将组件渲染到页面中的指定位置

使用方法:

   1、index.html添加一个元素

   2、修改组件的渲染方式  ReactDOM.createPortal() 创建元素

      参数 1、jsx (修改前return后的代码)

           2、目标位置(DOM元素)

十三、第十三课   模块化css 

模块化css

1、XXX.module.css

2、组件中引入css   import classes from './App.module.css'

3、通过classes来设置类

    className = {classes.p1}

   css模块可以动态的设置唯一的class值

设置移动端的适配

  除以几视口的宽度就是多少rem,我们设置视口的总宽度是750rem

十四、第十四课   引入fortawesome

引入fortawesome  

1、引入组件

   import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";

2、引入图标

   import {faPlus} from "@fortawesome/free-solid-svg-icons";

3、使用组件

   <FontAwesomeIcon icon={faPlus}/>

十五、第十五课   context  

context:存储数据,相当于一个公共的存储空间

    可以将多个组件中都需要访问的数据统一存储到一个context中。无需通过props逐层传递,即可访问这些数据

    React.createContext()

使用方法一:

    1、引入context

    2、使用xxx.consumer组件来创建元素

       consumer 标签体需要一个回调函数,通过参数可访问context中存储的数据

使用方法二:

   useContext()

   1、导入context

   2、使用钩子函数useContext()获取到context

          useContext()需要一个context作为参数

*Xxx.Provider,表示生产者,可以使用它来指定context中的数据,通过value来指定context中存储的数据

当通过context访问数据时,会读取离他最近的Provider中的数据,如果没有provider,则读取context中的默认数据


 

十六、第十六课   副作用effect

副作用:Effect

React.strictMode:自动检查react组件是否会产生副作用

React Developer Tool

当我们直接在函数体中调用setState时,就会触发上述错误

setState()的执行流程

   setCount() --> dispatchSetDate()

   --> 会先判断,组件当前处于什么阶段

   如果处于渲染阶段 -> 不会检查state值是否相同,会一直处于重复渲染

   如果不是处于渲染阶段 -> 会检查state值是否相同

       --> 如果不相同,会进行重新渲染

           如果相同,不重新渲染

               --> 如果值相同,react在一些情况下会继续执行当前组件的渲染,但是这个渲染不会触发其子组件的渲染,这次渲染不会产生实际的效果,这种情况通常发生在值第一次相同时

useEffect()  是一个钩子函数,需要一个函数作为参数

这个作为参数的函数,将会在组件渲染完毕后执行

可以将那些会产生副作用的代码编写到useEffect的回调函数中

可以传递第二个参数,是一个数组,在数组中可以指定effect的依赖项

通常会将effect中使用的所有局部变量设置为依赖项,依赖项发生变化时,会触发effect的执行

useEffect(()=>{},[ctx])

如果依赖项设置了一个空数组,则意味着effect只会在组件初始化时触发一次

第一次点击按钮  count -> 1  执行

第二次点击按钮  count -> 1  执行

第三次点击按钮  count -> 1  不执行

effect的回调函数,可以指定一个函数作为返回值

这个函数可以将其作为清理函数,它会在下次effect执行调用

清除副作用:useEffect(()=>{

   return ()=>{

      //清除副作用

   }

},[])

十七、第十七课   useReducer

reducer: 整合器,对state的一个整合

useReducer:钩子函数   useReducer(reducer,initialArg,init)

  reducer执行时,会收到两个参数

     1、state:当前最新的state

     2、action:需要一个对象,会存储dispatch所发出的指令

参数:

    reducer:函数

    initialArg:初始值,作用和useState里的值一样

返回值:

    数组:

       第一个参数:state 用来获取state的值

       第二个参数:state修改的派发器,通过派发器可以发送操作state的命令,具体的修改行为将会由另外一个函数执行

const [count,countDispatch] = useReducer(()=>{},1)

countDispatch({type:'INC'})

为避免reducer会重复创建,会把reducer放在组件外部

十八、第十八课   React.memo

React.memo  对于没有state等的组件,避免组件重复渲染    Object.is()方法判断两个值是否是相同的值。比较新值和老值

是一个高阶组件,接收另一个组件作为参数,并且会返回一个包装过的新组件

            包装过的组件就会具有缓存功能

                包装过后,只有组件的props发生变化才会触发组件的重新渲染,否则总是返回缓存中的结果

十九、第十九课   useCallback

useCallback:钩子函数,用来创建react中的回调函数

useCallback 创建的回调函数不会总在组件重新渲染时重新创建,多次渲染中缓存函数

   参数1:回调函数

   参数2:依赖数组

         当依赖数组中的变量发生变化时,回调函数才会重新渲染

二十、第二十课   fetch 数据

strapi: api 本地服务

fetch: fetch Api   向服务器发送请求加载数据,是ajax的升级版,参数1、请求地址,2、请求信息  

return res.json() 将响应的json直接转换为js对象

多层传递数据 context

二十一、第二十一课   自定义钩子

钩子函数只能在函数组件或者自定义钩子函数中

自定义钩子:当我们需要将react中钩子函数提取到一个公共区域时,就可以使用钩子函数

自定义钩子是一个普通函数,它的名字需要使用use开头    useFun

二十二、第二十二课   redux  RTK  RTKQ

redux:可预期的状态管理器,reducer和context的结合

redux.js  核心包

网页中使用步骤:

    1、引入核心包

    2、创建reducer整合函数

    3、通过reducer对象创建store   Redux.createStore(reducer,initArg)

    4、将store中的state进行订阅   store.subscribe

    5、通过dispatch派发state的操作指令

用redux带来的问题:

    1、如果state过于复杂,难于维护

           --state分组,创建多个reducer,然后合并成一个

    2、state每次操作,都需要对state进行复制,然后再去修改

    3、case后边的常量维护起来很麻烦

从而引入了RTK

RTK:Redux Toolkit

yarn add react-redux  @reduxjs/toolkit

createSlice 创建reducer的切片

const stuSlice = createSlice({

   name:'',用来自动生成action中的type

   initialState:{

   },//state的初始值

   reducers:{

      setName(state,action){

         //可以通过不同的方法来指定对state的不同操作

         //两个参数,state 是一个代理对象

      }

   }//指定state的各种操作,直接在对象中添加方法

})

切片对象会自动帮助我们生成action,actions中存储的是slice自动生成的action创建器,调用函数后会自动创建action对象

action对象的结构 {type:name/函数名,payload:函数的参数}

const {setName} = stuSlice.actions

创建store对象,需要一个配置对象作为参数

const store = configureStore({

   reducer:{

      student:stuSlice.reducer

   }

})

useSelector(state=>state.student) 用来加载state中的数据

useDispatch() 来获取派发器对象

<Provider store={store}></Provider>


 

RTKQ: 创建api对象,减少请求发送的次数   keepUnusedDataFor,单位秒,默认是60s

createApi() 用来创建RTKQ中的API对象

const studentApi = createApi({

   reducerPath:'',  api的标识,不能和其他的api或reducer重复

   baseQuery:fetchBaseQuery({

      baseUrl:''

   }),//指定查询的基础信息,发送请求使用的工具

   endpoints(build){

      return {

         getStudents:build.query({

            query(){

               return

            }

         })

      }

       

   }//用来指定api中的各种功能,是一个方法,需要一个对象作为返回值

})


 

useQuery 参数:

   可提供一个对象作为第二个参数,通过该对象可以对请求进行配置

   {

      selectFromResult: 用来指定返回的结果

      skip: true 是否跳过当前请求

   }


 

二十三、第二十三课   react-router  version5

reactRouter:客户端路由 version 5

使用步骤:

  1、引入react-router-dom包

  2、在index.js中引入BrowserRouter组件

  3、将BrowserRouter设置为根组件

  使用Route来映射地址和组件

  注意:当Route的路径被访问,其对应的组件就会自动挂载,默认情况不是严格匹配,只要url地址的头部和path一致,组件就会挂载

  exact  是严格匹配

  <Route exact path="/" component={Home} />

BrowserRouter  直接通过url地址进行组件的跳转

HashRouter 会通过url地址中的hash值来对地址进行匹配

当我们通过点击Link构建的链接进行跳转时,跳转并没有经过服务器,所以没有问题

*       但是当我们刷新页面,或通过普通链接进行跳转时,会向服务器发送请加载数据

*           这时的请求并没有经过react router 所以会返回404

* 解决方案:

*   1.使用HashRouter,服务器不会去判断hash值,

*       所以使用HashRouter后请求将会由React Router处理

*   2.修改服务器的配置,将所有请求都转发到index.html

*       location / {

            root   html;

            #index  index.html index.htm;

         try_files $uri /index.html;

        }

       

//render是指定要挂载的组件,需要一个回调函数作为参数,返回值最终被挂载

props:

<Route path="" render={}>  

标签体:

<Route path="" children={<Student />}>

<Route><Student /></Route>


 

当使用react-router时,一定不能使用a标签来创建链接

link:

navLink

二十四、第二十四课   react原生组件 Outlet等

Prompt组件:弹窗提示

Redirect组件:用于跳转页面 <Redirect push from={"/"} to={"/to"} />  push或replace

Outlet组件:表示嵌套路由中的组件,当嵌套路由中的路径匹配成功了,Outlet则表示嵌套路由中的组件

                               当嵌套路由中的路径没有匹配成功,Outlet就什么都不是

Navigate:用来跳转到指定的位置,默认使用push <Navigate to="" replace />

二十五、第二十五课   react-router  version6

router  version6

Routes  是v6中新增加的组件

在v6中,Route的component render children都变了

<Route path="/" element={<Student/>} />

useParams: 可以使用useParams()来获取参数

useLocation: 获取当前的地址信息

useMatch: 用来检查当前url是否匹配某个路由  如果路径匹配,则返回一个对象,不匹配则返回null

useNavigate: 获取一个用于条件页面的函数,可以实现跳转的功能,默认是push,会产生历史记录  useNavigate('/about',{replace:true})则不会产生历史记录

二十六、第二十六课  useMemo

useMemo:每次重新渲染的时候能够缓存计算的结果,在组件顶层或者自定义hook中调用,数据二次处理(消耗非常大的计算的时候用此钩子函数)

   const someEle = useMemo(()=>{

      return <Some />

   },[])

useImperativeHandle: 能自定义由ref暴露出来的句柄,场景:1、向父组件暴露子组件的方法  2、控制子组件的动画或转换效果 3、集成第三方库的方法  4、封装原生 DOM 元素的方法

   无法直接获取react组件的dom对象,react也不知道要给你谁

   React.forwardRef()    ref={ref}   外层组件可以通过 ref 直接控制内层组件或元素的行为

   useImperativeHandle(ref,()=>{

      retun changeInpVal(val){}

   })

useEffect:绘制屏幕之后,组件渲染之后执行,其余情况用useeffext

useLayoutEffect:dom改变,组件渲染之前执行,修改样式可以用

useInsertionEffect:dom改变之前执行,添加元素可以用

useDebugValue: React 开发工具 中为自定义 Hook 添加标签

useDeferredValue:延迟更新 UI 的某些部分,当设置了延迟值后,每次state修改时都会触发了两次重新的渲染,这两次执行对于其他部分没有区别,但是延迟值两次执行的值是不同的,第一次执行时 延迟值是state的旧值,第二次执行时,延迟值是state的新值,延迟值总会比原版的state值慢一步更新

     当多个组件使用同一个state时,组件可能会互相影响,一个组件卡顿,会导致另一个组件卡顿

useTransition:是一个帮助你在不阻塞 UI 的情况下更新状态的 React Hook。

   startTransition 的回调函数中设置setState会在其他的setState生效后执行

   const [isPending,startTransitions] = useTransition

useId:可以生成传递给无障碍属性的唯一 ID


 

二十七、第二十七课  组件通信 

lodash:数据处理排序库

classnames: 优化类名控制

父 -> 子通信:props

子 -> 父:在子组件中调用父组件的函数并传递参数

兄弟组件通信:子A -> 父  父 -> 子B  

跨级组件:context    createContext  provider  useContext

二十八、第二十八课  一些好用的第三方工具

json-server  数据服务

redux devtools

normalize.css 初始化css

路径解析配置  插件craco  别名@

source-map-explorer  包体积分析  source-map-explorer "build/static/js/*.js"

二十九、第二十九课  主题定制及项目目录结构

主题定制:全局定制和局部定制

:root:root{

   --adm-color-primary:#dddd

}

.purple-theme{

   --adm-colot-primary:#ddd

}

目录结构:

apis       接口

assets     静态资源

components 通用组件

pages      页面级组件  

router     路由

store      redux状态

hooks      自定义的钩子函数

utils      工具函数   axios的封装处理

三十、第三十课  项目打包

useSearchParamms()

setFieldsValue()  -> 简单json

打包:

1、项目打包:npm run build

2、本地预览:在本地通过静态服务器模拟生产服务器运行项目的过程  

   npm run build

   npm install -g serve

   serve -s build

路由懒加载: 目的是为了优化项目首次打开的时间

1、把路由修改为React提供的lazy函数进行动态导入

2、使用React内置的suspense组件包裹路由中element选项对应的组件


 

三十一、第三十一课  zustand

zustand:极简的状态管理工具   set

切片模式:create((...a)=>{})  功能比较大的时候需要做拆分

三十二、第三十二课  React+Ts

React + Ts  vite   npm init vite@latest my-vue-app -- --template react-ts

1、语法: useState<User>()  泛型参数

2、children:

   type Props = {

      className:string,

      children:React.ReactNode  //支持多种类型,是react的内置类型

   }

3、事件prop  

   type Props = {

      onGetMsg?:(msg:string)=>void

   }

4、useRef<HTMLInputElement>

dangerouslySetInnerHTML = {{

   __html:detail?.content

}}

三十三、第三十三课  next.js 服务端渲染

next.js:服务端渲染  ssr

三十四、react的渲染过程

render(reconcile的过程) + commit(执行增删改dom和effect、生命周期函数的执行,ref的更新等)

render 阶段实现 vdom 转 fiber 的 reconcile

commit 阶段执行增删改 dom,更新 ref、调用 effect 回调和生命周期函数等。

  • 19
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值