目录
React事件机制:
2、React的事件和普通的HTML有什么不同:
- 事件命名的规则不同,原生事件采用全小写,react事件采用小驼峰
3、React组件中怎么做事件代理?他的原理是什么?
4、React高阶组件、Render props、Hook有什么区别,为什么要不断迭代?
✨HOC(高阶组件):
✨Render props:
✨Hook:
5、React.Component和React.PureComponent的区别
6、关于this指向:
React事件机制:
js的原生事件的绑定有三种:
- HTML标签引入方式
- DOM0级绑定方式(只支持事件冒泡)document.qeuerySelector(“#parent).οnclick=function()
- DOM2级绑定方式(既支持冒泡,有支持捕获)document.querySelector("#parent").addeEventListener('click',function(e){},true)
React事件处理机制:
1️⃣:react对原始事件(冒泡和捕获)进行封装,封装后的事件叫做合成事件。
<button onClick{function(){合成事件1}}></button>
<button onClick{()=>{合成事件1}}></button>
clickBind1(){
log(合成事件2)
}
<button onClick{()=>{clickbind1}}></button>
onClick={this.类中的普通方法}存在this指向问题,需要通过bind改变this指向
合成事件实现原理:
react并不是将是将事件绑定到元素的真实DOM上
- 在react17中,是在根容器(#root)处监听了所有事件,当事件发生并且冒泡到根容器处的时候,React将事件内容封装并且交给真正的处理函数。
- 在react16中,是在document处监听了所有事件,当事件冒泡到document处的收,React将事件内容封装并交由真正的处理函数。
合成事件的目的:
⏩首先抹平了浏览器之间的兼容问题,另外这是一个跨浏览器原生事件包装器
⏩对于原生浏览器事件来说,浏览器会给监听器创建一个事件对象,(1)如果有很多的事件监听,那么就需要分配很多事件对象,造成高额的内存分问题,(2)但是对于合成事件来说,有一个事件池专门来管理他们的创建和销毁,(3)当事件需要被使用时,就会从池子中复用对象,事件用完了,就会销毁事件对象上的属性。
---------------------------------------------------------------------------------------------------------------------------------
2、React的事件和普通的HTML有什么不同:
- 事件命名的规则不同,原生事件采用全小写,react事件采用小驼峰
-对于事件函数处理语法,原生事件为字符串,react为函数
- react不能采用return false来组织默认行为,必须使用e.preventDefault()组织默认行为
---------------------------------------------------------------------------------------------------------------------------------
3、React组件中怎么做事件代理?他的原理是什么?
React基于虚拟Dom实现了一个SyntheicEvent层(合成事件层),定义的事件处理器会接收到一个合成事件的实例对象,该对象符合W3c标准,且与原生浏览器拥有同样的事件接口,支持冒泡机制,所有的事件都自动绑定在最外层(16是绑定在document上,17以后是绑定在根容器root上)
2️⃣:原理:
在React底层,主要对合成事件做了两件事情:
✨ 事件委派:事件委派的机制是将事件处理程序注册到一个父元素上,而不是直接注册到每个子元素上,当子元素触发事件时,事件会向上传播到父元素,父元素在根据事件的类型和目标元素来决定如何处理事件。
✨ 自动绑定:React组件中,每个方法的上下文都会指向该组件的实例,即自动绑定在this所指的当前组件
---------------------------------------------------------------------------------------------------------------------------------
4、React高阶组件、Render props、Hook有什么区别,为什么要不断迭代?
✨HOC(高阶组件):
HOC是React中用于复用组件逻辑的一种高级技巧,具体就是高阶组件是参数为组件,返回值为新组件的函数
语法:
import loadable from 'react-loadable'
function withLoadable(wrapComponent){
return Loadable({
loader:WrapComponent,
loading:()=> </div>,
dely:1000
})
}
export default withLoadable
❗❗❗:HOC缺点:
- HOC传递给被包裹组件的props容易和被包裹后的组件重名,进而被覆盖。
✨Render props:
父组件App.JSX
function App(){
<Son render={data=><p>{data.name}今年{data.age}岁</p>}></Son>
}
子组件 Son.jsx
function Son(){
const data = {name:'CMY',age:18}
return(
<div>
props.render(data)
</div>
)
}
render props指将一个函数组为组件的props传入到子组件中,该函数会在父组件中被调用,并返回一些需要被渲染的内容,子组件在渲染时可以使用该函数返回的内容来动态渲染自己的UI。
❗❗❗: renderprops缺点:
- 会形成嵌套地狱
- 无法在 return
语句外访问数据
✨Hook:
Hook是React16.8的新增特性,它可以让函数组件使用类组件中的state和生命周期函数。通过自定义hook,可以复用代码逻辑。
❗❗❗:缺点:
- hook只能在组件顶层使用,不可以再在分支语句中使用
优点:
解决render props的嵌套地狱问题,解决HOC的prop重命名问题。
5、React.Component和React.PureComponent的区别
✨ React.Component组件的特点是,
- 只要调用setState(),即使state数据没有发生变化,组件依然重新渲染-------->效率低
-只有当前组件重新渲染,子组件跟着一起渲染,纵使子组件没有使用父组件的任何数据------>效率低
原因:因为React.Component中的shouldComponentUpadte()总是返回true,如果我们把组件中的shouldComponentUpdate添加判断条件就可以优化Rreact.component的性能低的问题,
shouldComponentUpdtae(nextProps,nextState){
if(nextProps===this.props) return false
else return true
}
✨PureComponent:
pureComponent重写了shouldComponentUpdate方法进行比较,但是pureComponent是浅比较,也就是说如果props或者state是引用类型的数据,只会比较是不是同一个地址,而不会比较这个地址里面的数据是否一致。例如:
如果state状态中是数组,使用的是pureComponent,需要更改数组中的内容,最好这样子更改,
setState(['添加的新值',...数组])
---------------------------------------------------------------------------------------------------------------------------------
6、关于this指向:
1️⃣:如果定义的是类中的成员方法,this执行改变在两个地方去写:
- 可以在构造函数中写:this.成员方法 = this.成员方法.bind(this)
- 可以在render函数调用的jsx中使用:onClick={this.成员方法.bind(this)}
2️⃣:如果定义在render的函数,函数包括如下
- 定义的是声明式函数只能在调用处使用onClick={声明式函数.bind(this)}
- 定义的是函数表达式,也只能在调用处使用onClick={声明式函数.bind(this)}
3️⃣:改变this指向有三种方式,apply,bind,call
- apply接收三个参数(被劫持的this,[数组])
- call接收三个参数(被劫持的this,值1,值2)
- apply和call是在改变this指向的同时也顺便调用改方法。
- bind(this)只改变this指向,不调用该方法。
✨总结:所以react中不适合apply和call,只适合bind