栏目导航

关于我们 联系我们 在线留言 新闻中心 案例展示 产品展示 www.183388.com www.266555m.com 特码王心 论坛 www.70678d.com
118con118开奖现场

当前位置:主页 > 118con118开奖现场 >

React框架大笔记

发布日期:2022-06-23 11:51   来源:未知   阅读:

  起初facebook在建设instagram(图片分享)的时候嘞,因为牵扯到一个东东叫数据流,那为了处理数据流并且还要考虑好性能方面的问题嘞,Facebook开始对市场上的各种前端MVC框架去进行一个研究,然而并没有看上眼的,于是Facebook觉得,还是自己开发一个才是最棒的,那么他们决定抛开很多所谓的“最佳实践”,重新思考前端界面的构建方式,他们就自己开发了一套,果然大牛创造力还是很强大的。

  基于HTML的前端界面开发正变得越来越复杂,其本质问题基本都可以归结于如何将来自于服务器端或者用户输入的动态数据高效的反映到复杂的用户界面上(dom操作)。而来自Facebook的React框架正是完全面向此问题的一个解决方案,按官网描述,其出发点为:用于开发数据不断变化的大型应用程序(Building large applications with data that changes over time)。相比传统型的前端开发,React开辟了一个相当另类的途径,实现了前端界面的 高性能 (减少dom操作 虚拟dom)高效率(组件开发模块) 开发。

  17 前端框架大范围的推广 前端在开发中地位越来越高  前后端分离          大数据  区款连  人工智能ai

  React不是一个完整的MVC框架,最多可以认为是MVC中的V(View),甚至React并不非常认可MVC开发模式;

  在Web开发中我们总需要将变化的数据实时反应到UI上,这时就需要对DOM进行操作。而复杂或频繁的DOM操作通常是性能瓶颈产生的原因(如何进行高性能的复杂DOM操作通常是衡量一个前端开发人员技能的重要指标)。

  React为此引入了虚拟DOM(Virtual DOM)的机制:在浏览器端用Javascript实现了一套DOM API。基于React进行开发时所有的DOM构造都是通过虚拟DOM进行,每当数据变化时,React都会重新构建整个DOM树,然后React将当前整个DOM树和上一次的DOM树进行对比,得到DOM结构的区别,然后仅仅将需要变化的部分进行实际的浏览器DOM更新。而且React能够批处理虚拟DOM的刷新,在一个事件循环(Event Loop)内的两次数据变化会被合并,例如你连续的先将节点内容从A-B,B-A,React会认为A变成B,然后又从B变成A UI不发生任何变化,而如果通过手动控制,这种逻辑通常是极其复杂的。

  尽管每一次都需要构造完整的虚拟DOM树,但是因为虚拟DOM是内存数据,性能是极高的,部而对实际DOM进行操作的仅仅是Diff分,因而能达到提高性能的目的。这样,在保证性能的同时,开发者将不再需要关注某个数据的变化如何更新到一个或多个具体的DOM元素,而只需要关心在任意一个数据状态下,整个界面是如何Render的。数据驱动,声明式

  我们以前操作dom的方式是通过document.getElementById()的方式,这样的过程实际上是先去读取html的dom结构,将结构转换成变量,再进行操作

  而reactjs定义了一套变量形式的dom模型,一切操作和换算直接在变量中,这样减少了操作真实dom,性能真实相当的高,和主流MVC框架有本质的区别,并不和dom打交道

  react最核心的思想是将页面中任何一个区域或者元素都可以看做一个组件 component

  使用react开发的核心就是将页面拆分成若干个组件,并且react一个组件中同时耦合了css、js、image,这种模式整个颠覆了过去的传统的方式

  其实reactjs的核心内容就是数据绑定,所谓数据绑定指的是只要将一些服务端的数据和前端页面绑定好,开发者只关注实现业务就行了

  在vue中,我们使用render函数来构建组件的dom结构性能较高,因为省去了查找和编译模板的过程,但是在render中利用createElement创建结构的时候代码可读性较低,较为复杂,此时可以利用jsx语法来在render中创建dom,解决这个问题,但是前提是需要使用工具来编译jsx 5. 官网主流的 hb wb atom sub vscode xcode nopad++

  react开发需要引入多个依赖文件:react.js、react-dom.js,分别又有开发版本和生成版本

  在这里一开始,我们先学习es5的组件写法,React.createClass,需要引入的是15+

  浏览器端编译,通过引入browser、babel等对引入的script内的代码做编译

  //render函数和Vue组件里的render完全一样,在vue组件中可以不用编写render函数,这个时候可以使用template模板来编写组件的虚拟dom结构,然后vue组件会自动讲模板compile成虚拟dom结构放入到render中执行,但是react需要编写render函数

  JSX语法不是必须使用的,但是因为使用了JSX语法之后会降低我们的开发难度,故而这样的语法又被成为语法糖

  在不使用JSX的时候,需要使用React.createElement来创建组件的dom结构,但是这样的写法虽然不需要编译,但是维护和开发的难度很高,且可读性很差

  及时使用了JSX语法了之后,也是需要将其编译成原生的createElement的

  JSX就是在js中使用的xml,但是,这里的xml不是真正的xml,只能借鉴了一些xml的语法,例如:

  jsx借鉴xml的语法而不是html的语法原因:xml要比html严谨,编译更方便

  行内样式需要写入一个样式对象,而这个样式对象的位置可以放在很多地方,例如React.createClass的配置项中、render函数里、组件原型上、外链js文件中

  React推荐我们使用行内样式,因为react觉得每一个组件都是一个独立的整体

  其实我们大多数情况下还是大量的在为元素添加类名、id以使用某些样式,但是需要注意的是,class需要写成className(因为毕竟是在写类js代码,会收到js规则的现在,而class是关键字)

  在react中,我们想要给组件的dom添加事件的话,也是 需要在行内添加的方式,事件名字需要写成小驼峰的方式,值利用表达式传入一个函数即可

  给虚拟dom结构中的节点添加样式。在行内添加,写成驼峰形式,值是一个函数名,需要用{}包裹

  组件嵌套的方式就是将子组件写入到父组件的模板中去,且react没有Vue中的内容分发机制(slot),所以我们在一个组件的模板中只能看到父子关系

  React也是基于数据驱动(声明式)的框架,组件中必然需要承载一些数据,在react中起到这个作用的是属性和状态(props & state)

  属性(props) 在组件外部传入,或者内部设置,组件内部通过this.props获得

  状态(state) 在组件内部设置或者更改,组件内部通过this.state获得

  属性一般是外部传入的,组件内部也可以通过一些方式来初始化的设置,属性不能被组件自己更改

  传入数据的时候,除了字符串类型,其他的都应该包上表达式,但是为了规整,所有的数据传递,最好都包上{}

  getDefaultProps的值是函数,这个函数会返回一个对象,我们在这里对象里为组件设置默认属性

  根据属性或状态,我们可以在render中的表达式里做一些逻辑判断,可以使用、三元表达式、子执行函数等等

  状态就是组件描述某种显示情况的数据,由组件自己设置和更改,也就是说由组件自己维护,使用状态的目的就是为了在不同的状态下使组件的显示不同(自己管理)

  在组件中只能通过getInitialState的钩子函数来给组件挂载初始状态,在组件内部通过this.state获取

  this.props和this.state是纯js对象,在vue中,$data属性是利用Object.defineProperty处理过的,更改$data的数据的时候会触发数据的getter和setter,但是react中没有做这样的处理,如果直接更改的话,react是无法得知的,所以,需要使用特殊的更改状态的方法:

  在setState中传入一个对象,就会将组件的状态中键值对的部分更改,还可以传入一个函数,这个回调函数必须返回像上面方式一样的一个对象,函数可以接收prevState和props

  通过ref对dom、组件进行标记,在组件内部通过this.refs获取到之后,进行操作

  相似点:都是纯js对象,都会触发render更新,都具有确定性(状态/属性相同,结果相同)

  react中组件也有生命周期,也就是说也有很多钩子函数供我们使用,下面是生命周期的图示:

  组件是一个构造器,每一次使用组件都相当于在实例化组件,在这个时候,组件就会经历一次生命周期,从实例化实例开始到这个实例销毁的时候,都是一次完整的生命周期

  这个钩子函数只会执行一次,也就是说,只在第一次实例化的时候执行,创建出所有实例共享的默认属性,后面再实例化的时候,不会执行getDefaultProps,直接使用已有的共享的默认属性

  理论上来说,写成函数返回对象的方式,是为了防止实例共享,但是react专门为了让实例共享,只能让这个函数只执行一次

  组件间共享默认属性会减少内存空间的浪费,而且也不需要担心某一个实例更改属性后其他的实例也会更改的问题,因为组件不能自己更改属性,而且默认属性的优先级低。

  执行getInitialState为实例挂载初始状态,且每次实例化都会执行,也就是说,每一个组件实例都拥有自己独立的状态呢

  当组件mount到页面中之后,就进入了运行中阶段,在这里有5个钩子函数,但是这5个函数只有在数据(属性、状态)发送改变的时候才会执行

  当执行的时候,函数接收的参数是子组件接收到的新参数,这个时候,新参数还没有同步到this.props上,多用于判断新属性和原有属性的变化后更改组件的状态

  当属性或状态发送改变后控制组件是否要更新,提高性能,返回true就更新,否则不更新,默认返回true

  接收nextProp、nextState,根据根据新属性状态和原属性状态作出对比、判断后控制是否更新

  componentWillUpdate,在这里,组件马上就要重新render了,多做一些准备工作,千万千万,不要在这里修改状态,否则会死循环 相当于Vue中的beforeUpdate

  当组件被销毁之前的一刹那,会触发componentWillUnmount,临死前的挣扎

  相当于Vue里的beforeDestroy,所以说一般会做一些擦的事情

  Vue在调用$destroy方法的时候就会执行beforeDestroy,然后组件被销毁,这个时候组件的dom结构还存在于页面结构中,也就说如果想要对残留的dom结构进行处理必须在destroyed处理,但是react执行完componentWillUnmount之后把事件、数据、dom都全部处理掉了,所以根本不需要其他的钩子函数了

  react中对于事件进行了处理,解决了一些兼容性问题,react事件对象上面挂载着nativeEvent,这个就是原生的事件对象

  父组件将自己的状态传递给子组件,子组件当做属性来接收,当父组件更改自己状态的时候,子组件接收到的属性就会发生改变

  父组件利用ref对子组件做标记,通过调用子组件的方法以更改子组件的状态,也可以调用子组件的方法..

  父组件将自己的某个方法传递给子组件,在方法里可以做任意操作,比如可以更改状态,子组件通过this.props接收到父组件的方法后调用。

  在react没有类似vue中的事件总线来解决这个问题,我们只能借助它们共同的父级组件来实现,将非父子关系装换成多维度的父子关系

  复杂的非父子组件通信在react中很难处理,多组件间的数据共享也不好处理,所以我们会使用flux、redux来实现这样的功能,解决这个问题

  在vue中我们可以将一些通用的、公用的方法放入到某一个纯js对象中,然后,在需要使用改方法的组件中使用mixins配置(值为对象)将该js对象中的方法注入到组件中,这样就能实现代码复用,便于维护

  在React中曾经也有这样的api,但是在高版本react中推荐我们使用es6中的class来创建组件了,这个时候无法使用mixinsapi,所以mixins被废弃了,如果要使用公用代码抽离,我们可以使用模块化

  我们在react中循环列表数据的时候,需要对循环出来的虚拟jsx节点传入上key这个数据,

  Keys可以在DOM中的某些元素被增加或删除的时候帮助React识别哪些元素发生了变化。因此你应当给数组中的每一个元素赋予一个确定的标识。

  在vue中有一个内容分发叫slot,在react中也有实现,就是可以在使用组件的时候,在组件标签内部放入一些不固定的内容,在该组件的模板中,只有{this.props.children}来表示

  webpack: 是一款模块化打包工具,webpack是基于配置的,通过配置一些选项来让webpack执行打包任务。

  webpack在打包的时候,依靠依赖关系图,在打包的时候需要告知webpack两个概念:入口和出口

  entry配置项目打包的入口,值可以为单个的字符串执行某一个文件的地址,这个时候该文件就是入口文件,webpack会根据入口文件里各模块间的关系形成依赖关系图,然后根据依赖关系图进行打包

  但是有的时候我们需要的是多入口,我们就写成数组的形式,数组里的每一个字符串地址指向的都是一个独立的入口,webpack会将这些入口的依赖打包

  刚才的两种entry配置都只会打包出一个js文件,但是在某一个应用中我们可能需要将js根据依赖关系打包成多个js文件,并且在多页面应用中,我们也确实不可能只使用一个js文件,那么我们就可以使用如下的配置:

  这样,因为filename里写成名字是[name],所以会根据entry的配置的键名来为打包出的js文件命名,hash是每次打包的一个随机的hash值,可以用来做版本控制

  filename可以确定打包出来的文件的名字,在里面我们可以使用[name],[hash]这样的占位符

  在命令行或者终端中执行 webpack --env hello命令,就相当于在打包的时候传入一个参数为hello

  在webpack.config.js中可以暴露出一个函数,这个函数就可以接收到env参数,当然函数就可以根据env参数来有选择的返回某一个或多个配置对象

  在webpack编译用的是loader,但是有一些loader无法完成的任务,交由插件(plugin)来完成,插件的时候需要在配置项中配置plugins选项,值是数组,可以放入多个插件的使用,而一般的插件都是一个构造器,我们只需在plugins数组中放入该插件的实例即可,在实例化插件的时候又可以传入options,对插件的使用进行配置

  这个插件可以选择是否依据模板来生成一个打包好的html文件,在里面可以配置、title、template、filename、minify等选项,详情请查阅文档

  在这个插件里,我们可以使用jade、hbs、ejs等模板引擎来编译成html,这里举例jade的配置:

  webpack相辅相成的有一个server功能工具可以提供开发的热更新服务器

  第一种启动方式: 直接执行webpack-dev-server,如果有需要配置的选项,在后面跟上参数即可。例如

  在webpack中专门有一些东西用来编译文件、处理文件,这些东西就叫loader,loader的使用就是在配置项中,设置modules,在modules中设置rule值为数组,在数组里放入多个匹配规则:

  使用url-loader可以将css中引入的图片(背景图)、js中生成的img图片处理一下,生成到打包目录里

  webpack-dev-server进行了一个优化,在跑起服务的时候,会将编译结果保存在内存里,不会实时的输出的打包结果

  当我们要进行二次配置的时候,需要找到node_modules文件夹里的react-scripts进行配置,但是当我们执行npm run eject就可以将配置文件抽出,方便开发配置

  当我们使用某些组件的时候,发现,该组件不需要拥有自己的状态,只需要接收到外界传入的属性之后做出相应的反应即可

  在2014年,facebook提出了Flux,Flux 是一种架构思想,专门解决软件的结构问题。它跟MVC 架构是同一类东西,但是更加简单和清晰。

  react只是一个视图层的框架,在flux是一个架构思想,我们在做项目的时候使用flux架构的话要比单纯使用react要简单很多,这个时候,react在整个FLUX架构中担任某一个角色的

  Store(数据层):用来存放应用的状态,一旦发生变动,就提醒Views要更新页面

  dispatcher接收到action并根据标识信息判断之后,调用store的更改数据的方法

  store更改状态后事件被触发,该事件的处理程序会通知view去获取最新的数据

  React 只是 DOM 的一个抽象层,并不是 Web 应用的完整解决方案。有两个方面,它没涉及。

  2014年 Facebook 提出了 Flux 架构的概念,引发了很多的实现。2015年,Redux 出现,将 Flux 与函数式编程结合一起,很短时间内就成为了最热门的前端架构。

  简单说,如果你的UI层非常简单,没有很多互动,Redux 就是不必要的,用了反而增加复杂性。

  注意:flux、redux都不是必须和react搭配使用的,因为flux和redux是完整的架构,在学习react的时候,只是将react的组件作为redux中的视图层去使用了。

  Reducer 函数最重要的特征是,它是一个纯函数。也就是说,只要是同样的输入,必定得到同样的输出。

  不能调用Date.now()或者Math.random()等不纯的方法,因为每次会得到不一样的结果

  由于 Reducer 是纯函数,就可以保证同样的State,必定得到同样的 View。但也正因为这一点,Reducer 函数里面不能改变 State,必须返回一个全新的对象,请参考下面的写法。

  最好把 State 对象设成只读。你没法改变它,要得到新的 State,唯一办法就是生成一个新对象。这样的好处是,任何时候,与某个 View 对应的 State 总是一个不变的对象。

  我们可以通过在createStore中传入第二个参数来设置默认的state,但是这种形式只适合于只有一个reducer的时候

  因为一个应用中只能有一个大的state,这样的话reducer中的代码将会特别特别的多,那么就可以使用combineReducers方法将已经分开的reducer合并到一起

  划分多个reducer的时候,默认状态只能创建在reducer中,因为划分reducer的目的,就是为了让每一个reducer都去独立管理一部分状态

  当值为hashHistory的时候,url的变化为hash值的变化,router会去检测hash变化来实现组件的切换

  当值为browserHistory的时候,url的变化为path的变化,需要后端进行配置

  在需要切换路由组件的地方,通过this.props.children来表示对应路由组件

  使用Redirect组件可以做到从一个路由马上重定向到其他路由,利用这样的属性,当我们form设置为*的时候,就可以将匹配不到的路由重定向到某げ路由下

  可以在配置Route的时候给path里加入/:param 才表示此路由需要参数

  可以通过在路由配置上设置 onLeave和onEnter路由钩子来监听路由的变化

  关于React的UI组件库市场上也有很多,在这里我们使用蚂蚁金服开发的AntDesign组件库

  这个库或者说工具是redux的开发者专门为react创建出来的,为我们在react中使用redux提供便利

  只要记住一句话就可以了:UI 组件负责 UI 的呈现,容器组件负责管理数据和逻辑。

  你可能会问,如果一个组件既有 UI 又有业务逻辑,那怎么办?回答是,将它拆分成下面的结构:外面是一个容器组件,里面包了一个UI 组件。前者负责与外部的通信,将数据传给后者,由后者渲染出视图。

  React-Redux 规定,所有的 UI 组件都由用户提供,容器组件则是由 React-Redux 自动生成。也就是说,用户负责视觉层,状态管理则是全部交给它。

  使用Provider组件,包裹在应用的最外层,并为Provider注入store属性,此时,Provider就会将自己的store属性传递给子组件组合中的容器组件

  使用connect函数,可以根据一个现有的UI组件生成一个容器组件,且我们在使用的时候,其实一直在使用的都是容器组件,connect函数执行之后返回一个函数,将返回的函数传入UI组件并执行之后就会生成一个容器组件

  mapStateToProps的作用很简单,就是将redux中的state传递到UI组件的props上,此参数是一个函数,接收到store的state然后再返回一个对象,返回的对象中的属性就会传递到UI组件的属性上

  我们需要将一些复杂的业务逻辑,或者说异步的业务逻辑抽离出来放入到actions里面去,也就是后所mapDispatchToProps里自己创建的只是一些简单的方法就可以了

  其实我们上面创建actions的目的,就是因为ActionCreator不能做复杂的动作,其实我们可以使用redux-thunk来对reducer创建中间件,让actionCreator的方法能返回一个函数,这个函数就可以接收到dispatch,且做出异步操作之后dispatch出action,也就是说,我们不需要再创建actions来分离异步复杂操作,而且直接可以在ActionCreator里写异步方法

  将所有的数据都交由redux管理,这样的话,我们的组件在UI层的逻辑就更纯粹了,而且可以做到数据缓存,比如,A组件获取了数据放入到redux中,当A组件被切换掉之后重新切换回来的时候,数据依然在redux中可以找到,也就是说直接取出来用就ok,不需要重新获取

  请简述对虚拟dom的理解,为什么使用虚拟DOM可以极大的提升react的性能

  虚拟dom是真实dom的js对象映射,使用虚拟dom,避免对原生dom的创建和比对,取而代之的创建和比对的是js对象

  原生dom的创建和比对是非常消耗性能的,而js对象的对比和创建对性能开销很小,从这种方式来提供应用的性能

  请说明在react中ref的作用,并写出使用ref的两种方式,说明哪一种是官方推荐的

  说明react中,父子组件项目传值的方式,并说明在大型项目中为什么要引入flux或者redux这种开发架构 父组件将自己的状态当成属性传递给子组件 父组件将自己的方法传递给子组件,子组件在调用的时候传参 父组件通过ref获取到子组件,调用子组件的方法传参

  react是一款视图层的轻量级前端框架,大量的非父子组件通信、状态共享会导致整个项目数据复杂,难以维护,所以react不适合处理大量的数据通信,为了解决这个问题,引入了FLUX、REDUX这样的数据架构,react结合FLUX或者redux才能实现比较复杂的前端项目

  在react中,列表循环尽量不要使用index作为key值,这和diff算法有关系,请简述diff算法中key值有什么作用,为什么key中使用index值会降低代码性能

  key值是diff算法中对比两个虚拟dom的最重要参考,决定了哪些列表中的组件可以复用,如果使用index作为key中,列表数据改变后,会导致同一个dom元素的key中发送改变,本来可以复用的组件必须重新创建,降低页面性能,除非列表不需要改变,一般情况不使用index作为key值

  通常情况下,action只是一个对象,不能包含异步操作,这导致了很多创建action的逻辑只能写在组件中,代码量较多也不便于复用,同时对该部分代码测试的时候也比较困难,组件的业务逻辑也不清晰,使用中间件了之后,可以通过actionCreator异步编写action,这样代码就会拆分到actionCreator中,可维护性大大提高,可以方便于测试、复用,同时actionCreator还集成了异步操作中不同的action派发机制,减少编码过程中的代码量

  如果某一个组件不是路由组件,却需要使用router相关api,并且还需要使用store中的state的时候,需要在最外层包裹withRouter,里面再使用connect生成容器组件

  (React是一款专注于数据层的前端框架)、react中需要调用setState方法来重置状态、react中的虚拟dom可以提升框架自身的性能、(react是一款符合MVVM设计思想的前端框架)

  前端组件使得复杂的代码得以被更好的划分、组件化的代码设计方式增加了代码的可复用性、(在拆分组件的时候将组件拆分的越小越细越好)、组件化开发是一种设计思想,不是react独享的

  (在打包输出目录中自动生成index.html)、(向打包目录中的index.html文件内插入打包生成的js文件引用)、将js源码中引用的css代码抽离ちゅ单独的css文件并放置到打包输出目录、(像打包输出目录中的index.html文件插入打包生成的css引用)

  a:jsx中可以通过{}来使用js的表达式,b:jsx中可以通过{}来使用js的代码,c:jsx中可以使用style={color:red}来设置元素的样式、d:jsx代码会被解析成一个js对象

  a: 父组件通过属性的方式给子组件传值,b:子组件通过props接收父组件的值,c:state中和页面无关的属性发送变化时,render不会执行,d:shouldComponentUpdate函数的两个参数分别是当前的state和当前的props

  在react组件中,当(props或者state)发送变化的时候,会导致render生命周期函数重新执行

  使用react-redux时,页面上的组件需要被拆分成(容器)组件和(UI)组件,通过使用(connect/mapStateToProps)方法,可以把store中固定state内容映射到组件上

  react中,ref属性的作用是(获取jsx中元素的真实dom节点或子组件)

  这是react-router中设置监听url路径变化的两种方式,hashHistory在切换路由的时候会在url上跟着哈希值,browserHistory通过判断path变化才切换路由,且path变化的时候后端可以接收到请求,需要后端配置忽略掉

  作为一个合格的开发者,不要只满足于编写了可以运行的代码。而要了解代码背后的工作原理;不要只满足于自己的程序...

  包含 react基础 react传值 react路由 和redux管理 和react-redux reactDom...

  [toc] REACT react :1.用来构建用户界面的 JAVASCRIPT 库2.react 专注于视图层...

  一、CMS管理系统功能 CMS是ContentManagementSystem的缩写,意为内容管理系统。 CM...

  任何一个商家,顾客进门要有一种亲切感,亲切的问候,可亲的微笑,融合的气氛,无不给人一种舒服的感觉。当一个商家做到这...

  同事也可以是朋友 在日常工作中,我们接触最多的人应该是同事了,对于同事能不能成为朋友这个话题众说纷纭,大多数人认为...

  她是我的初恋,我们从初二开始恋爱,升高中时,因三分之差我和她一个在城市东边,一个在西边。不同的学校,不同的事...