柳州网站建设公司,.org做商业网站,南通网络科技有限公司,最常用最齐全wordpress插件大全概述下 React 中的事件处理逻辑
抹平浏览器差异#xff0c;实现更好的跨平台。避免垃圾回收#xff0c;React 引入事件池#xff0c;在事件池中获取或释放事件对象#xff0c;避免频繁地去创建和销毁。方便事件统一管理和事务机制。 为了解决跨浏览器兼容性问题#xff0…概述下 React 中的事件处理逻辑
抹平浏览器差异实现更好的跨平台。避免垃圾回收React 引入事件池在事件池中获取或释放事件对象避免频繁地去创建和销毁。方便事件统一管理和事务机制。 为了解决跨浏览器兼容性问题React 会将浏览器原生事件Browser Native Event封装为合成事件SyntheticEvent传入设置的事件处理器中。这里的合成事件提供了与原生事件相同的接口不过它们屏蔽了底层浏览器的细节差异保证了行为的一致性。另外有意思的是React 并没有直接将事件附着到子元素上而是以单一事件监听器的方式将所有的事件发送到顶层进行处理。这样 React 在更新 DOM 的时候就不需要考虑如何去处理附着在 DOM 上的事件监听器最终达到优化性能的目的 React最新的⽣命周期是怎样的
React 16之后有三个⽣命周期被废弃(但并未删除)
componentWillMountcomponentWillReceivePropscomponentWillUpdate
官⽅计划在17版本完全删除这三个函数只保留UNSAVE_前缀的三个函数⽬的是为了向下兼容但是对于开发者⽽⾔应该尽量避免使⽤他们⽽是使⽤新增的⽣命周期函数替代它们。
⽬前React16.8的⽣命周期分为三个阶段分别是挂载阶段、更新阶段、卸载阶段。
挂载阶段
constructor构造函数最先被执⾏我们通常在构造函数⾥初始化state对象或者给⾃定义⽅法绑定thisgetDerivedStateFromPropsstatic getDerivedStateFromProps(nextProps, prevState)这是个静态⽅法当我们接收到新的属性想去修改我们state 可以使⽤getDerivedStateFromPropsrenderrender函数是纯函数只返回需要渲染的东⻄不应该包含其它的业务逻辑可以返回原⽣的DOM、React组件、Fragment、Portals、字符串和数字、 Boolean和null等内容componentDidMount组件装载之后调⽤此时我们可以获取到DOM节点并操作⽐如对canvassvg的操作服务器请求订阅都可以写在这个⾥⾯但是记得在componentWillUnmount中取消订阅
更新阶段
getDerivedStateFromProps: 此⽅法在更新个挂载阶段都可能会调⽤shouldComponentUpdateshouldComponentUpdate(nextProps, nextState)有两个参数nextProps和nextState表示新的属性和变化之后的state返回⼀个布尔值true表示会触发重新渲染false表示不会触发重新渲染默认返回true我们通常利⽤此⽣命周期来优化React程序性能render更新阶段也会触发此⽣命周期getSnapshotBeforeUpdategetSnapshotBeforeUpdate(prevProps, prevState),这个⽅法在render之后componentDidUpdate之前调⽤有两个参数prevProps和prevState表示之前的属性和之前的state这个函数有⼀个返回值会作为第三个参数传给componentDidUpdate如果你不想要返回值可以返回null此⽣命周期必须与componentDidUpdate搭配使⽤componentDidUpdatecomponentDidUpdate(prevProps, prevState, snapshot)该⽅法在getSnapshotBeforeUpdate⽅法之后被调⽤有三个参数prevPropsprevStatesnapshot表示之前的props之前的state和snapshot。第三个参数是getSnapshotBeforeUpdate返回的如果触发某些回调函数时需要⽤到DOM元素的状态则将对⽐或计算的过程迁移⾄getSnapshotBeforeUpdate然后在componentDidUpdate中统⼀触发回调或更新状态。
卸载阶段:
-componentWillUnmount当我们的组件被卸载或者销毁了就会调⽤我们可以在这个函数⾥去清除⼀些定时器取消⽹络请求清理⽆效的DOM元素等垃圾清理⼯作。
总结
componentWillMount在渲染之前执行用于根组件中的 App 级配置componentDidMount在第一次渲染之后执行可以在这里做AJAX请求DOM的操作或状态更新以及设置事件监听器componentWillReceiveProps在初始化render的时候不会执行它会在组件接受到新的状态(Props)时被触发一般用于父组件状态更新时子组件的重新渲染shouldComponentUpdate确定是否更新组件。默认情况下它返回true。如果确定在state或props更新后组件不需要在重新渲染则可以返回false这是一个提高性能的方法componentWillUpdate在shouldComponentUpdate返回true确定要更新组件之前件之前执行componentDidUpdate它主要用于更新DOM以响应props或state更改componentWillUnmount它用于取消任何的网络请求或删除与组件关联的所有事件监听器。
React 中的key是什么为什么它们很重要
key可以帮助 React跟踪循环创建列表中的虚拟DOM元素了解哪些元素已更改、添加或删除。 每个绑定key的虚拟DOM元素在兄弟元素之间都是独一无二的。在 React的和解过程中比较新的虛拟DOM树与上一个虛拟DOM树之间的差异并映射到页面中。key使 React处理列表中虛拟DOM时更加高效因为 React可以使用虛拟DOM上的key属性快速了解元素是新的、需要删除的还是修改过的。如果没有key,Rεat就不知道列表中虚拟DOM元素与页面中的哪个元素相对应。所以在创建列表的时候不要忽略key。
描述事件在 React中的处理方式。
为了解决跨浏览器兼容性问题 React中的事件处理程序将传递 SyntheticEvent的实例它是跨浏览器事件的包装器。这些 SyntheticEvent与你习惯的原生事件具有相同的接口它们在所有浏览器中都兼容。 React实际上并没有将事件附加到子节点本身。而是通过事件委托模式使用单个事件监听器监听顶层的所有事件。这对于性能是有好处的。这也意味着在更新DOM时 React不需要担心跟踪事件监听器。
调用 setState 之后发生了什么 在代码中调用 setState 函数之后React 会将传入的参数与之前的状态进行合并然后触发所谓的调和过程Reconciliation。经过调和过程React 会以相对高效的方式根据新的状态构建 React 元素树并且着手重新渲染整个 UI 界面。在 React 得到元素树之后React 会计算出新的树和老的树之间的差异然后根据差异对界面进行最小化重新渲染。通过 diff 算法React 能够精确制导哪些位置发生了改变以及应该如何改变这就保证了按需更新而不是全部重新渲染。 在 setState 的时候React 会为当前节点创建一个 updateQueue 的更新列队。然后会触发 reconciliation 过程在这个过程中会使用名为 Fiber 的调度算法开始生成新的 Fiber 树 Fiber 算法的最大特点是可以做到异步可中断的执行。然后 React Scheduler 会根据优先级高低先执行优先级高的节点具体是执行 doWork 方法。在 doWork 方法中React 会执行一遍 updateQueue 中的方法以获得新的节点。然后对比新旧节点为老节点打上 更新、插入、替换 等 Tag。当前节点 doWork 完成后会执行 performUnitOfWork 方法获得新节点然后再重复上面的过程。当所有节点都 doWork 完成后会触发 commitRoot 方法React 进入 commit 阶段。在 commit 阶段中React 会根据前面为各个节点打的 Tag一次性更新整个 dom 元素
生命周期调用方法的顺序是什么
React生命周期分为三大周期11个阶段生命周期方法调用顺序分别如下。 1在创建期的五大阶段调用方法的顺序如下。 getDetaultProps定义默认属性数据。 getInitialState初始化默认状态数据。 component WillMount组件即将被构建。 render渲染组件。 componentDidMount组件构建完成
2在存在期的五大阶段调用方法的顺序如下。 componentWillReceiveProps组件即将接收新的属性数据。 shouldComponentUpdate判断组件是否应该更新。 componnent WillUpdate组件即将更新。 render渲染组件。 componentDidUpdate组件更新完成。
3在销毁期的一个阶段调用方法 componentWillUnmount表示组件即将被销毀。
参考 前端进阶面试题详细解答
如何告诉 React 它应该编译生产环境版 通常情况下我们会使用 Webpack 的 DefinePlugin 方法来将 NODE_ENV 变量值设置为 production。编译版本中 React会忽略 propType 验证以及其他的告警信息同时还会降低代码库的大小React 使用了 Uglify 插件来移除生产环境下不必要的注释等信息 setState到底是异步还是同步? 先给出答案: 有时表现出异步,有时表现出同步 setState只在合成事件和钩子函数中是“异步”的在原生事件和setTimeout 中都是同步的setState 的“异步”并不是说内部由异步代码实现其实本身执行的过程和代码都是同步的只是合成事件和钩子函数的调用顺序在更新之前导致在合成事件和钩子函数中没法立马拿到更新后的值形成了所谓的“异步”当然可以通过第二个参数setState(partialState, callback)中的callback拿到更新后的结果setState 的批量更新优化也是建立在“异步”合成事件、钩子函数之上的在原生事件和setTimeout 中不会批量更新在“异步”中如果对同一个值进行多次setStatesetState的批量更新策略会对其进行覆盖取最后一次的执行如果是同时setState多个不同的值在更新时会对其进行合并批量更新
react性能优化是哪个周期函数 shouldComponentUpdate 这个方法用来判断是否需要调用render方法重新描绘dom。因为dom的描绘非常消耗性能如果我们能在shouldComponentUpdate方法中能够写出更优化的dom diff算法可以极大的提高性能 redux的三大原则 单一数据源 整个应用的state被存储在一个object tree中并且这个object tree 之存在唯一一个store中 state是只读的 唯一改变state的方式是触发actionaction是一个用于描述已经发生时间的对象这个保证了视图和网络请求都不能直接修改state相反他们只能表达想要修改的意图 使用纯函数来执行修改state 为了描述action如何改变state tree 需要编写reduce
请说岀 React从 EMAScript5编程规范到 EMAScript6编程规范过程中的几点改变。
主要改变如下。 1创建组件的方法不同。 EMAScript5版本中定义组件用 React.createClass。EMAScript6版本中定义组件要定义组件类并继承 Component类。 2定义默认属性的方法不同。 EMAScript5版本中用 getDefaultProps定义默认属性。EMAScript6版本中为组件定义 defaultProps静态属性来定义默认属性。 3定义初始化状态的方法不同。EMAScript5版本中用 getInitialState定义初始化状态。EMAScript6版本中在构造函数中通过this. state定义初始化状态。 注意构造函数的第一个参数是属性数据一定要用 super继承。 4定义属性约束的方法不同。 EMAScript5版本中用 propTypes定义属性的约束。 EMAScript6版本中为组件定义 propsTypes静态属性来对属性进行约束。 5使用混合对象、混合类的方法不同。 EMAScript5版本中通过mixins继承混合对象的方法。 EMAScript6版本中定义混合类让混合类继承 Component类然后让组件类继承混合类实现对混合类方法的继承。 6绑定事件的方法不同。 EMAScript5版本中绑定的事件回调函数作用域是组件实例化对象。 EMAScript6版本中绑定的事件回调函数作用域是null。 7父组件传递方法的作用域不同。 EMAScript5版本中作用域是父组件。 EMAScript6版本中变成了null。 8组件方法作用域的修改方法不同。 EMAScript5版本中无法改变作用域。 EMAScript6版本中作用域是可以改变的。
setState到底是异步还是同步
先给出答案: 有时表现出异步有时表现出同步。
setState只在合成事件和钩⼦函数中是“异步”的在原⽣事件和setTimeout中都是同步的setState的“异步”并不是说内部由异步代码实现其实本身执⾏的过程和代码都是同步的只是合成事件和钩⼦函数的调⽤顺序在更新之前导致在合成事件和钩⼦函数中没法⽴⻢拿到更新后的值形成了所谓的“异步”当然可以通过第⼆个参数setState(partialState, callback)中的callback拿到更新后的结果setState的批量更新优化也是建⽴在“异步”合成事件、钩⼦函数之上的在原⽣事件和setTimeout中不会批量更新在“异步”中如果对同⼀个值进⾏多次 setStatesetState的批量更新策略会对其进⾏覆盖取最后⼀次的执⾏如果是同时setState多个不同的值在更新时会对其进⾏合并批量更新。
在生命周期中的哪一步你应该发起 AJAX 请求 我们应当将AJAX 请求放到 componentDidMount 函数中执行主要原因有下 React 下一代调和算法 Fiber 会通过开始或停止渲染的方式优化应用性能其会影响到 componentWillMount 的触发次数。对于 componentWillMount 这个生命周期函数的调用次数会变得不确定React 可能会多次频繁调用 componentWillMount。如果我们将 AJAX 请求放到 componentWillMount 函数中那么显而易见其会被触发多次自然也就不是好的选择。如果我们将AJAX 请求放置在生命周期的其他函数中我们并不能保证请求仅在组件挂载完毕后才会要求响应。如果我们的数据请求在组件挂载之前就完成并且调用了setState函数将数据添加到组件状态中对于未挂载的组件则会报错。而在 componentDidMount 函数中进行 AJAX 请求则能有效避免这个问题
React中Diff算法的原理是什么
原理如下。 1节点之间的比较。 节点包括两种类型一种是 React组件另一种是HTML的DOM。 如果节点类型不同按以下方式比较。 如果 HTML DOM不同直接使用新的替换旧的。如果组件类型不同也直接使用新的替换旧的。 如果 HTML DOM类型相同按以下方式比较。 在 React里样式并不是一个纯粹的字符串而是一个对象这样在样式发生改变时只需要改变替换变化以后的样式。修改完当前节点之后递归处理该节点的子节点。 如果组件类型相同按以下方式比较。 如果组件类型相同使用 React机制处理。一般使用新的 props替换旧的 props并在之后调用组件的 componentWillReceiveProps方法之前组件的 render方法会被调用。 节点的比较机制开始递归作用于它的子节点。 2两个列表之间的比较。 一个节点列表中的一个节点发生改变 React无法很妤地处理这个问题。循环新旧两个列表并找出不同这是 React唯一的处理方法。 但是有一个办法可以把这个算法的复杂度降低。那就是在生成一个节点列表时给每个节点上添加一个key。这个key只需要在这一个节点列表中唯一不需要全局唯一。 3取舍 需要注意的是上面的启发式算法基于两点假设。 类型相近的节点总是生成同样的树而类型不同的节点也总是生成不同的树 可以为多次 render都表现稳定的节点设置key。 上面的节点之间的比较算法基本上就是基于这两个假设而实现的。要提高 React应用的效率需要按照这两点假设来开发。
使用箭头函数(arrow functions)的优点是什么
作用域安全在箭头函数之前每一个新创建的函数都有定义自身的 this 值(在构造函数中是新对象在严格模式下函数调用中的 this 是未定义的如果函数被称为“对象方法”则为基础对象等)但箭头函数不会它会使用封闭执行上下文的 this 值。简单箭头函数易于阅读和书写清晰当一切都是一个箭头函数任何常规函数都可以立即用于定义作用域。开发者总是可以查找 next-higher 函数语句以查看 this 的值
高阶组件的应用场景
权限控制
利用高阶组件的 条件渲染 特性可以对页面进行权限控制权限控制一般分为两个维度页面级别 和 页面元素级别
// HOC.js
function withAdminAuth(WrappedComponent) { return class extends React.Component { state { isAdmin: false, } async componentWillMount() { const currentRole await getCurrentUserRole(); this.setState({ isAdmin: currentRole Admin, }); } render() { if (this.state.isAdmin) { return WrappedComponent {...this.props} /; } else { return (div您没有权限查看该页面请联系管理员/div); } } };
}// 使用
// pages/page-a.js
class PageA extends React.Component { constructor(props) { super(props); // something here... } componentWillMount() { // fetching data } render() { // render page with data }
}
export default withAdminAuth(PageA); 可能你已经发现了高阶组件其实就是装饰器模式在 React 中的实现通过给函数传入一个组件函数或类后在函数内部对该组件函数或类进行功能的增强不修改传入参数的前提下最后返回这个组件函数或类即允许向一个现有的组件添加新的功能同时又不去修改该组件属于 包装模式(Wrapper Pattern) 的一种。
什么是装饰者模式在不改变对象自身的前提下在程序运行期间动态的给对象添加一些额外的属性或行为
可以提高代码的复用性和灵活性。
再对高阶组件进行一个小小的总结
高阶组件 不是组件是 一个把某个组件转换成另一个组件的 函数高阶组件的主要作用是 代码复用高阶组件是 装饰器模式在 React 中的实现
封装组件的原则
封装原则
1、单一原则负责单一的页面渲染
2、多重职责负责多重职责获取数据复用逻辑页面渲染等
3、明确接受参数必选非必选参数尽量设置以_开头避免变量重复
4、可扩展需求变动能够及时调整不影响之前代码
5、代码逻辑清晰
6、封装的组件必须具有高性能低耦合的特性
7、组件具有单一职责封装业务组件或者基础组件如果不能给这个组件起一个有意义的名字证明这个组件承担的职责可能不够单一需要继续抽组件直到它可以是一个独立的组件即可
react旧版生命周期函数
初始化阶段
getDefaultProps:获取实例的默认属性getInitialState:获取每个实例的初始化状态componentWillMount组件即将被装载、渲染到页面上render:组件在这里生成虚拟的DOM节点componentDidMount:组件真正在被装载之后
运行中状态
componentWillReceiveProps:组件将要接收到属性的时候调用shouldComponentUpdate:组件接受到新属性或者新状态的时候可以返回false接收数据后不更新阻止render调用后面的函数不会被继续执行了componentWillUpdate:组件即将更新不能修改属性和状态render:组件重新描绘componentDidUpdate:组件已经更新
销毁阶段
componentWillUnmount:组件即将销毁
如何有条件地向 React 组件添加属性
对于某些属性React 非常聪明如果传递给它的值是虚值可以省略该属性。例如
var InputComponent React.createClass({render: function () {var required true;var disabled false;return input typetext disabled{disabled} required{required} /;},
});渲染结果
input typetext required另一种可能的方法是
var condition true;
var component div valuefoo {...(condition { disabled: true })} /;为什么不直接更新 state 呢 ?
如果试图直接更新 state 则不会重新渲染组件。
// 错误
This.state.message Hello world;需要使用setState()方法来更新 state。它调度对组件state对象的更新。当state改变时组件通过重新渲染来响应
// 正确做法
This.setState({message: ‘Hello World’});hooks 为什么不能放在条件判断里
以 setState 为例在 react 内部每个组件(Fiber)的 hooks 都是以链表的形式存在 memoizeState 属性中 update 阶段每次调用 setState链表就会执行 next 向后移动一步。如果将 setState 写在条件判断中假设条件判断不成立没有执行里面的 setState 方法会导致接下来所有的 setState 的取值出现偏移从而导致异常发生。
文章转载自: http://www.morning.nnqrb.cn.gov.cn.nnqrb.cn http://www.morning.qmnjn.cn.gov.cn.qmnjn.cn http://www.morning.dmthy.cn.gov.cn.dmthy.cn http://www.morning.xgzwj.cn.gov.cn.xgzwj.cn http://www.morning.sfnr.cn.gov.cn.sfnr.cn http://www.morning.nxcgp.cn.gov.cn.nxcgp.cn http://www.morning.lylkh.cn.gov.cn.lylkh.cn http://www.morning.dnwlb.cn.gov.cn.dnwlb.cn http://www.morning.jgttx.cn.gov.cn.jgttx.cn http://www.morning.qgxnw.cn.gov.cn.qgxnw.cn http://www.morning.yrms.cn.gov.cn.yrms.cn http://www.morning.dtlnz.cn.gov.cn.dtlnz.cn http://www.morning.banzou2034.cn.gov.cn.banzou2034.cn http://www.morning.mngh.cn.gov.cn.mngh.cn http://www.morning.bytgy.com.gov.cn.bytgy.com http://www.morning.hytr.cn.gov.cn.hytr.cn http://www.morning.ghkgl.cn.gov.cn.ghkgl.cn http://www.morning.yjknk.cn.gov.cn.yjknk.cn http://www.morning.clhyj.cn.gov.cn.clhyj.cn http://www.morning.mnclk.cn.gov.cn.mnclk.cn http://www.morning.bkfdf.cn.gov.cn.bkfdf.cn http://www.morning.nlhcb.cn.gov.cn.nlhcb.cn http://www.morning.dnphd.cn.gov.cn.dnphd.cn http://www.morning.hrjrt.cn.gov.cn.hrjrt.cn http://www.morning.qgjp.cn.gov.cn.qgjp.cn http://www.morning.thbqp.cn.gov.cn.thbqp.cn http://www.morning.kbynw.cn.gov.cn.kbynw.cn http://www.morning.ksgjn.cn.gov.cn.ksgjn.cn http://www.morning.ltfnl.cn.gov.cn.ltfnl.cn http://www.morning.pxlql.cn.gov.cn.pxlql.cn http://www.morning.drkk.cn.gov.cn.drkk.cn http://www.morning.mslsn.cn.gov.cn.mslsn.cn http://www.morning.caswellintl.com.gov.cn.caswellintl.com http://www.morning.lqzhj.cn.gov.cn.lqzhj.cn http://www.morning.xfcjs.cn.gov.cn.xfcjs.cn http://www.morning.pyncm.cn.gov.cn.pyncm.cn http://www.morning.jqtb.cn.gov.cn.jqtb.cn http://www.morning.lmjkn.cn.gov.cn.lmjkn.cn http://www.morning.pqxjq.cn.gov.cn.pqxjq.cn http://www.morning.hqgxz.cn.gov.cn.hqgxz.cn http://www.morning.ndmh.cn.gov.cn.ndmh.cn http://www.morning.monstercide.com.gov.cn.monstercide.com http://www.morning.klzdy.cn.gov.cn.klzdy.cn http://www.morning.lbrwm.cn.gov.cn.lbrwm.cn http://www.morning.hmfxl.cn.gov.cn.hmfxl.cn http://www.morning.qxycf.cn.gov.cn.qxycf.cn http://www.morning.lqlfj.cn.gov.cn.lqlfj.cn http://www.morning.qdxtj.cn.gov.cn.qdxtj.cn http://www.morning.pyncm.cn.gov.cn.pyncm.cn http://www.morning.nspbj.cn.gov.cn.nspbj.cn http://www.morning.nqbpz.cn.gov.cn.nqbpz.cn http://www.morning.jfmjq.cn.gov.cn.jfmjq.cn http://www.morning.mqffm.cn.gov.cn.mqffm.cn http://www.morning.jfcbz.cn.gov.cn.jfcbz.cn http://www.morning.fprll.cn.gov.cn.fprll.cn http://www.morning.yxbrn.cn.gov.cn.yxbrn.cn http://www.morning.hkshy.cn.gov.cn.hkshy.cn http://www.morning.tgydf.cn.gov.cn.tgydf.cn http://www.morning.mspqw.cn.gov.cn.mspqw.cn http://www.morning.rdnpg.cn.gov.cn.rdnpg.cn http://www.morning.wbhzr.cn.gov.cn.wbhzr.cn http://www.morning.gnghp.cn.gov.cn.gnghp.cn http://www.morning.qztdz.cn.gov.cn.qztdz.cn http://www.morning.lnwdh.cn.gov.cn.lnwdh.cn http://www.morning.djxnw.cn.gov.cn.djxnw.cn http://www.morning.pjtw.cn.gov.cn.pjtw.cn http://www.morning.bgkk.cn.gov.cn.bgkk.cn http://www.morning.jyzxt.cn.gov.cn.jyzxt.cn http://www.morning.xrnh.cn.gov.cn.xrnh.cn http://www.morning.dmsxd.cn.gov.cn.dmsxd.cn http://www.morning.wxccm.cn.gov.cn.wxccm.cn http://www.morning.xclgf.cn.gov.cn.xclgf.cn http://www.morning.yjfzk.cn.gov.cn.yjfzk.cn http://www.morning.hhmfp.cn.gov.cn.hhmfp.cn http://www.morning.zmbzl.cn.gov.cn.zmbzl.cn http://www.morning.fgppj.cn.gov.cn.fgppj.cn http://www.morning.gmrxh.cn.gov.cn.gmrxh.cn http://www.morning.jbtlf.cn.gov.cn.jbtlf.cn http://www.morning.mlpmf.cn.gov.cn.mlpmf.cn http://www.morning.slwqt.cn.gov.cn.slwqt.cn