![](https://img-blog.csdnimg.cn/20210922214031373.jpg?x-oss-process=image/resize,m_fixed,h_224,w_224)
react系列(2)
文章平均质量分 85
从jsx到react实战
coderlin_
幸运=99%的努力+1%的运气
展开
-
ZF_react hooks useState的实现 useCallback useMemo useReducer useContext
useStatehooks可以在不使用类组件的情况下使用state。useState可以在函数组件中添加一些state,react会在重复渲染时保留这个state。useState的第二个返回值setxxx类似于类组件的this.setState(xx),但他不会把新的statae与旧的state合并,而是会直接替代。setState会接受一个新的state的值并将组建的一次重新渲染加入队列。因为我们没有引用fiber,所以组件的状态全部保存到一个全局变量上。定义全局状态hook原创 2021-10-26 23:27:03 · 427 阅读 · 0 评论 -
typescript 高级
1 类型推断从右向左流动:// let a: number 类型从右向左流动 let a = 1;通过return关键字推断返回值的类型 底部流出 function add(a: number) { return a; }从左向右: //从左向右 type S = (a: number) => void; const s: S = (a) => { // parameter) a: number console.log(a); };原创 2022-02-09 13:49:42 · 908 阅读 · 0 评论 -
typescript 基础
基础ts1 普通枚举enum Gender { GIRL = "d", BOY = "e",}console.log(Gender.GIRL);编译成 var Gender;(function (Gender) { Gender[Gender["GIRL"] = 'd'] = "GIRL"; // Gender[d] = GIRL Gender['GIRL'] = 'd'(默认是0) Gender[Gender["BOY"] = 'e'] = "BOY";}原创 2022-02-09 13:48:43 · 810 阅读 · 0 评论 -
一文搞懂react的Schedule调度系统
Schedulereact有一套基于Fiber架构的调度系统,这套调度系统的基本功能包括:1 更新具有不同的优先级2 一次根因可能涉及多个组件的render,这些render可能分配到多个宏任务中执行(即时间切片)3 搞优先级更新打断低优先级更新实现第一版的调度系统,如图:(图借于魔术师卡颂)可以看到是同步的,workList存放所有的work,然后schedule取出后,给perform执行,执行完后继续执行schdeule,递归直到所有work执行完毕。// 用work原创 2022-02-08 19:27:49 · 1343 阅读 · 1 评论 -
自顶而下学习react源码 (3)架构篇 commit阶段
commit阶段在rootFiber.firstEffect上保存了一条需要执行副作用的Fiber节点的单向链表effectList,这些Fiber节点的updateQueue中保存了变化的props。这些副作用对应的dom操作在commit阶段执行,除此之外,一些生命周期钩子如componentDidXXX,useEffect需要在commit阶段执行。commit阶段的工作主要分为三个部分:before mutation阶段(执行DOM操作前)mutation阶段(执行DOM操作)layou原创 2022-02-08 14:35:22 · 656 阅读 · 0 评论 -
自顶而下学习react源码 (2)架构篇 render阶段
架构Reconciler工作的阶段属于render阶段,Renderer工作的阶段属于commit阶段。render与commit阶段统称为work,即React在工作中。相对应的,如果任务正在Scheduler内调度,就不属于work。render阶段 分为递归两个阶段。递阶段递阶段是深度优先遍历,为遍历到的每个fiber节点调用beginWork方法。该方法会根据传入的fiber节点创建子fibei节点,并且将fiber节点连接起来(不会创建dom)。当遍历到叶子节点的时候,该叶子节点完成递阶原创 2022-02-03 13:28:06 · 1203 阅读 · 0 评论 -
自顶而下学习react源码 (1) 理念篇
理念篇快速响应的瓶颈之一就是cpu限制,浏览器的js线程与gui渲染线程互斥,一旦js执行过长,就会导致卡顿。 解决这个问题的关键就是:在浏览器每一帧的时间中,预留一些时间给JS线程,React利用这部分时间更新组件 解决CPU瓶颈的关键是实现时间切片,而时间切片的关键是:将同步的更新变为可中断的异步更新。瓶颈之二就是IO的瓶颈: React实现了[Suspense ]功能及配套的hook——useDeferredValue为了支持这些特性,同样需要将同步的更新变为可中断的异步更新。原创 2022-02-03 13:22:55 · 892 阅读 · 0 评论 -
基于react16.8创建自己的react
基于这个网站实现的一个简易版reacthttps://pomb.us/build-your-own-react/学完之后大概能懂得react的一个工作原理。附代码如下:const TEXT_ELEMENT = "TEXT_ELEMENT";// 第一步 完成creaateElementfunction createElement(type, props, ...children) { return { type, props: { ...props,原创 2022-01-31 22:31:16 · 674 阅读 · 0 评论 -
react 从0搭配react项目2上拉加载,下拉刷新,手撕虚拟列表
声明非代码模块动画效果声明非代码模块在ts中,无法识别非代码资源。所以需要.d.ts文件来声明类型项目编译过程中会自动读取.d.ts这种类型的文件,所以不需要我们手动去加载他们。.d.ts文件也必须被ts编译,所以应该放置在tsconfig.json的includes里面。动画效果使用Transition去包裹。他会给你一个状态,表示进入中,进入后,退出中,退出后四个状态,让你可以根据四个状态定义不同的style。一般正常只有显示和隐藏两个状态,这个组件可以给你提供四个状态。.原创 2021-11-16 21:39:05 · 1627 阅读 · 1 评论 -
react 从0搭配react项目
安装依赖npm init -ycnpm install react react-dom @types/react @types/react-dom react-router-dom @types/react-router-dom antd redux react-redux @types/react-redux react-thunk redux-logger @types/redux-logger redux-promise @types/redux-promise connected-react原创 2021-11-10 22:23:52 · 705 阅读 · 0 评论 -
项目创建——代码规范prettier, commitlint
preitter首先安装运行后应该是这样prettierrc就是用来写规则的文件,ignore顾名思义就是忽略哪些文件。第二,预提交钩子执行npx mrm lint-staged。它会在代码每次提交之前,进行格式化。对所有js css md ts tsx文件都会使用piettier格式化代码。兼容eslintprettier工作的时候跟eslint有一些冲突,所以我们要安装这个。再在eslint的规则后面加上prettier,表示eslint工作的时候用prettier的一些规原创 2021-11-10 07:47:17 · 221 阅读 · 0 评论 -
react umi实战
umiumiJs是一个类Next.JS的react开发框架它基于一个约定,即pages目录下的文件即路由,而文件则导出react组件。然后打通从源码到产物的每个阶段,并配以完善的插件体系,让我们能把umi的产物部署到各个场景里面初始化项目npm i umi -gumi g page index dev也是基于webpack-dev-server启动的。约定式路由。跳转全局layout约定src/layouts/index.js为全局组件,返回一个React组件,通过pr原创 2021-11-08 21:57:18 · 934 阅读 · 0 评论 -
react dva实现
dvadva是一个基于redux和redux-saga的数据流方案,然后为了简化开发体验,dva额外内置了react-router,fetch,可以激烈为一个轻量级的应用框架。使用dva定义一个模型,有点像redux-toolkit。使用connect连接像redux的connect一样连接。启动。然后如何派发action。通过对应的指令找到对印的reducer,派发。dva的基本操作就是这样,使用起来比较轻便。实现dva...原创 2021-11-07 21:03:33 · 1759 阅读 · 0 评论 -
react redux Reduc-saga实现(1) take put takeEvery createSagaMiddleware等
工作原理sages采用Generator函数来yield Effects(包含指令的文本对象)Generator函数的作用可以暂停执行,再次执行的时候从上次暂停的地方继续执行Effect是一个简单的对象,该对象包含一些给Middleware解释执行的信息。你可以通过使用effects API如 frok, call, put,cancel等来创建Effect。Reduc-saga分类worker saga做左右的工作比如调用api,进行异步请求。获取异步封装结果。wather sage监原创 2021-11-04 23:57:42 · 901 阅读 · 1 评论 -
ZF_react redux connected-react-router将路由与redux连接起
connected-react-router需要依赖这个库,连接路由和仓库作用:通过派发action动作去修改路劲看基本使用:第一个用来代替Router,第二个是个中间件,第三个是用来创建reducer的。第四个是跳转动作,用来返回一个action创建路由state以及改造dispatch。通过dispatch派发Push返回的action正常跳转。打印一下Push返回的action,如上。现在实现一下这个库。connected-react-router的实现一共需要四原创 2021-11-03 22:15:47 · 305 阅读 · 0 评论 -
ZF_react redux 中间件thunk promise logger applyMiddleware 中间件级联实现
redux设计思想Redux是将整个应用状态存储到一个地方,称为store。里面保存一颗状态数state tree。组件可以派发dispatch行为action给store,而不是直接通知其他组件。其他组件可以通过订阅store中的状态来刷新视图。Redux三大原则:整个应用的state被存储在一颗object tree中,并且这个object tree只存在于唯一一个store.state是只读的,唯一可以改变state的方法就是触发action.action是一个用于描述已发生事件的普原创 2021-11-02 08:48:29 · 207 阅读 · 0 评论 -
ZF_react react-router prompt lazy的实现
prompt的实现可以看到Prompt接受两个入参,一个是when,一个是Message,用来提示,其实就是在当前页面退出去的时候拦截一下,alert一个东西。实现思路:在生命周期的时候处理,然后push的时候进行拦截。使用一个组件LifeCyclle创建的时候执行block(message),销毁的时候执行销毁函数,这个block是在history拿到的,所以我们必须在histoy定义。定义一个全局变量在每次push的时候拦截判断就可以了,看效果:通过定义全局变量存放mes原创 2021-10-31 16:07:05 · 238 阅读 · 0 评论 -
ZF_react react-router 使用正则匹配路由,Switch路由,嵌套路由的实现 路由保护 NavLink withRouter
正则匹配路由这样的设计不太合理。path-to-regexp使用这个库可以将路劲转化为正则。可以通过第二个参数keys获取到params的数组,然后抽离出来。再利用match匹配到的数组,去取出对应的数据。如z最后拿到的对象就是我们要的。match对象的实现Route对象有三个Porps,history,match,location。我们已经实现了location,history。现在实现match通过这个函数拿到Match。借助刚才那个path-to-regexp的库,将Ro原创 2021-10-30 23:48:00 · 825 阅读 · 0 评论 -
ZF_react react-router起步 React路由原理 简单实现Router Route createHashRouter createBrowserRouter。
React路由原理原创 2021-10-30 11:56:11 · 2566 阅读 · 0 评论 -
ZF_react hooks useEffect的实现 useRef useImperativeHandle的实现,react整体功能实现完毕
useEffect的实现(纯函数:不能修改参数,不能修改函数作用域外的变量),除此之外都是副作用在函数组件主体内(React渲染阶段)改变DOM,添加订阅,设置定时器,记录日志以及其他包含副作用的操作都是不被允许的,因为这会产生莫名其妙的bug并破坏UI的一致性。使用useEffect完成副作用操作,useEffect会在当前组件渲染到dom之后执行。可以把effect看作从React的纯函数式世界通往命令式世界的逃生通道。如本质想让他一秒加一次1,但是结果却都是1,为什么?因为react渲原创 2021-10-27 23:22:40 · 446 阅读 · 0 评论 -
ZF_react 高阶组件 多个context的实现 render props Purcomponent的实现 React.memo的实现
高阶组件高阶组件就是一个函数,传给她一个组件,它返回一个新的组件。高阶组件的作用其实就是为了组件之前的代码复用。高阶组件的用处,属性代理, 方向继承属性代理像之前实现的redux的connext就是使用高阶组件的写法。通过高阶组件传入了一个title属性,如果所有组件都需要这个属性,只需要使用这个高阶函数代理一下即可。使用装饰器的写法会报错,因为它不支持。所以我们安装一个plugin.然后在babel.config.js文件进行配置在书写一个jsconfig.json文件这样原创 2021-10-25 23:25:54 · 495 阅读 · 0 评论 -
ZF_react dom-diff 新的生命周期,context上下文实现
dom-diff算法如ABCDEFG=>ACDBG首先会有一个oldMap对象,存储老的键值对。然后会有一个变量 lastPlaceIndex,表示上一个不需要移动的节点的位置(用来判断是否移动节点)遍历新的虚拟DOM数组。首先新的虚拟dom第一个A,在oldMap中找到,位置为0,lastPlaceIndex标记为0,接着第二个C,在oldMap中找到,位置为2,lastPlaceIndex标记为2.依次类推打B的时候,因为B在老的位置为1,跟LastPlaceIndex相比原创 2021-10-24 20:04:58 · 120 阅读 · 0 评论 -
ZF_react ref的实现 生命周期的实现
ref的实现类组件可以通过ref来获取原生dom,获取类组件,并且可以通过forwardRef转发函数组件来传递ref。原生dom ref的实现实现收集第一二个输入框的值相加并且展现在第三个输入框上。首先先实现简单的React.createRef函数该函数很简单,返回一个拥有current属性的对象,重点是赋值,因为拿到的是原生dom,所以肯定是在创建的时候赋值。在创建vdom的时候先对ref做处理,因为是特殊属性。接着,原生dom只需要在创建的时候赋值即可。在createDom函数里面原创 2021-10-20 08:32:01 · 326 阅读 · 0 评论 -
ZF_react 类组件状态的使用 实现组件的更新,合成事件,批量更新
类组件状态的使用类组件的数据来源有两个地方,父组件传过来的属性以及自己内部的状态。属性和状态发生变化后组件都会更新。state的更新可能是异步,出于性能考虑可能会把多个setState合并到一起使用。连续两个this.setState({})在第二个state不能拿到最新的值。他们会被合并。可以使用this.setState(pre=>({…pre}))传入函数的形式来返回一个新值,这样下一个setState就能拿到最新的值。这些setState还是会异步执行。怎样同步执行呢?在react原创 2021-10-03 21:50:05 · 408 阅读 · 0 评论 -
ZF_react中的jsx丶实现原生dom的渲染丶函数组件丶类组件的首次渲染实现
jsxjsx在babel的帮助下可以转换为react.createElement方法的调用,如PURE是treeshaking的时候用的,标志这是个纯函数。新老版本的区别在17之前,我们需要显示引入React,然后Babel转化为React.CreateElement方法,而新的版本中不需要显示引入React,react会自动转化为(Object.s_jsx)方法。JSX只是react提供的一个语法糖,react元素是构建react应用的最小 单位。如,let elemtn = < d原创 2021-09-25 21:21:23 · 424 阅读 · 0 评论