谈谈React组件开发中scope的常见问题。在EMAScript5语法规范中,关于作用域的常见问题如下。(1)在map等方法的回调函数中,必须绑定this的作用域(通过bind方法)。(2)父组件传递给子组件的方法作用域是父组件的实例化对象,不能改变。(3)组件事件回调函数方法的作用域为组件实例化对象(绑定父组件提供的方法为父组件实例化对象),不可更改。在EMAScript6语法规范中,关于作用域的常见问题如下。(1)当使用箭头函数作为map等方法的回调函数时,箭头函数的作用域为当前组件的实例化对象(即箭头函数的作用域为定义的作用域),并且不需要绑定范围。(2)事件回调函数必须绑定到组件作用域。(3)父组件的传递方法必须绑定父组件的作用域。简而言之,在EMAScript6语法规范中,组件方法的范围是可以改变的。描述如何在React中处理事件。为了解决跨浏览器兼容性问题,React中的事件处理程序将传递SyntheticEvent的实例,它是跨浏览器事件的包装器。这些SyntheticEvents具有与您习惯的本机事件相同的界面,并且它们在所有浏览器中都兼容。React实际上并没有将事件附加到子节点本身。相反,使用单个事件侦听器通过事件委托模式在顶层侦听所有事件。这对性能有好处。这也意味着React无需担心在DOM更新时跟踪事件监听器。React的虚拟dom是怎么实现的?首先说一下为什么要使用VirturlDOM,因为操作真实DOM的性能成本太高,所以react内部使用js实现了一套dom结构,在每次操作和真实dom之前,使用实现良好的diff算法比较虚拟dom,递归找出变化的dom节点,然后更新。为了实现虚拟DOM,我们需要将每个节点类型抽象成一个对象。每个节点类型都有自己的属性,即prop。每次执行diff时,react都会首先比较节点类型。如果节点类型不同相同,那么react会直接删除该节点,然后直接新建一个节点插入进去。如果节点类型相同,则比较prop是否更新。如果prop不同,那么react会判断该节点已经更新,然后重新渲染该节点,然后逐层比较它的子节点,直到没有子节点为止React的虚拟DOM和内部实现的差异算法。传统diff算法的时间复杂度为O(n^3),这在前端渲染中是不能接受的。为了降低时间复杂度,react的diff算法做了一些折衷,放弃了最优解,最终将时间复杂度降低到O(n)。那么reactdiff算法做了哪些妥协呢?,参考如下:treediff:只比较同层的dom节点,忽略dom节点的跨层移动。当发现该节点不存在时,该节点及其子节点将被彻底删除,不再用于进一步的比较。这样只需要遍历一次树就可以完成整个DOM树的比较。这意味着如果dom节点跨层移动,react将删除旧节点并生成新节点而不会重复使用。Componentdiff:如果不是同类型的component,则删除旧的component,创建一个新的component。elementdiff:对于同一层级的一组子节点,需要通过唯一的id来区分。如果没有id区分,一旦有插入动作,就会导致插入位置之后的所有列表重新渲染,这就是为什么在渲染列表的时候要用一个唯一的key。reactforcerefreshcomponent.forceUpdate()一个不常用的生命周期方法,它的作用是强制刷新官网解释如下默认情况下,当组件的state或props发生变化时,组件会重新渲染。如果render()方法依赖于其他数据,您可以调用forceUpdate()强制组件重新渲染。调用forceUpdate()将导致组件调用render()方法,该方法会跳过组件的shouldComponentUpdate()。但是,它的子组件会触发正常的生命周期方法,包括shouldComponentUpdate()方法。如果标记发生变化,React仍然只会更新DOM。通常,您应该避免使用forceUpdate()并在render()中使用this.props和this.state。shouldComponentUpdate不会在初始化和forceUpdate的时候执行。在React16.X中,在getDerivedStateFromProps中处理props变化后,将处理哪个生命周期。这个生命周期函数的存在是为了替代componentWillReceiveProps,所以当你需要使用componentWillReceiveProps时,可以考虑使用getDerivedStateFromProps代替。两者的参数不同,getDerivedStateFromProps是静态函数,即这个函数不能通过this访问类的属性,不建议直接访问属性。而是应该通过参数提供的nextProps和prevState进行判断,根据新传入的props映射到state。需要注意的是,如果props传入的内容不需要影响你的state,那么你需要返回一个null。这个返回值是必须的,所以尽量写在函数的末尾:staticgetDerivedStateFromProps(nextProps,prevState){const{type}=nextProps;//当传入的类型改变时,更新状态if(type!==prevState.type){return{type,};}//否则,状态什么都不做returnnull;}参考前端高级面试题详细答案组件是什么?什么是类?什么样的组件被编译成一个类?它指的是页面的一部分。它本质上是一个类,最本质的是一个构造函数。该类被编译成构造函数。React-Router的路由有几种模式?React-Router支持使用hash(对应HashRouter)和browser(对应BrowserRouter)两种路由规则。react-router-dom提供了BrowserRouter和HashRouter两个组件来实现应用UI和URL同步:BrowserRouter创建的URL格式:xxx.com/pathHashRouter创建的URL格式:xxx.com/#/path(1)BrowserRouter使用历史HTML5提供的API(pushState、replaceState和popstate事件)使UI和URL保持同步。由此可见,BrowserRouter使用了HTML5的historyAPI来控制路由跳转:
