react的基本面试题

1.说说React diff 算法是怎么运作的?从tree层到component层到element层分别讲解。

Real-DOM Diff算法,通常称为Virtual DOM Diff算法,是React使用的一种高效的算法,用于比较两个虚拟DOM树(Virtual DOM Tree)之间的差异,并最小化对实际DOM的更新,从而提高性能。这个算法分为三个层次:Tree层、Component层、Element层。

  1. Tree层:在Tree层,Real-DOM Diff算法比较两个虚拟DOM树的根节点。它首先检查两个根节点是否具有相同的类型(例如,两者都是div元素),如果类型相同,则进一步比较其属性。如果类型和属性都相同,React会认为这两个根节点是相同的,不需要进行任何更新。如果类型不同或属性不同,React将认为需要替换整个根节点,从而触发实际DOM的更新。
  2. Component层:React会比较组件的类型(type)和属性(props)。如果两个组件的类型不同,React会销毁旧组件并创建新组件;如果类型相同,React会比较它们的属性。如果属性不同,React会更新组件的属性,并且递归地进行子组件的比较。
  3. Element层:在Element层,React比较两个虚拟DOM树中的叶子元素(Element)。React会比较元素的类型、属性和文本内容。如果这些都相同,React将认为两个元素是相同的,不需要更新。如果有差异,React将更新实际DOM以反映这些差异。

Real-DOM Diff算法通过这三个层次的比较,可以高效地找到需要更新的部分,并最小化实际DOM的变更。它还可以在Diff过程中生成一系列的DOM操作指令(例如增加节点、删除节点、更新节点属性等),然后将这些指令批量执行,从而进一步提高性能。

总的来说,Real-DOM Diff算法是React的核心之一,它使React能够高效地管理和更新DOM,提供了快速响应用户交互的能力,同时尽可能减少了不必要的DOM操作,提高了性能。

2.说说React 生命周期中有哪些坑?为什么要移除will相关生命周期?

  1. 误解生命周期方法调用时机:每个生命周期方法的调用时机都有其特定的规则。例如,componentDidMount 在组件首次渲染后调用,而 componentDidUpdate 在组件更新后调用。误解这些调用时机可能导致逻辑错误。
  2. 滥用生命周期方法:在某些情况下,开发者可能会过度依赖生命周期方法来处理状态或执行副作用。这可能导致代码难以理解和维护。
  3. 未正确处理异步操作:在生命周期方法中执行异步操作(如网络请求)时,需要特别小心。如果处理不当,可能会导致状态不一致或其他问题。
  4. 组件卸载后的状态更新:在组件卸载后(例如,在 componentWillUnmount 之后)更新状态是没有意义的,因为组件已经不存在了。这可能会导致不必要的计算和内存消耗

3.调和阶段setState干了什么?

在React中,setState 是用来更新组件的状态(state)的方法之一。当调用 setState 时,React 将触发组件的重新渲染,以反映新的状态。React会将新的状态与旧的状态合并,而不是完全替换它。

在React的生命周期中,setState 调用的时机对于组件的更新非常重要。通常,setState 调用会在组件的更新阶段之后触发,而不会立即生效。React会将多个 setState 调用合并成一个更新,以提高性能。

React 的组件更新过程大致如下:

  1. 组件接收到新的 props 或调用了 setState
  2. React 会计划进行一次更新。
  3. React 在下一个“调和阶段”(Reconciliation Phase)中比较虚拟DOM树的差异,以找出需要更新的部分。
  4. React 更新真实DOM以反映新的虚拟DOM。
  5. 组件的生命周期方法被调用(例如,componentDidUpdate)。

在上述过程中,setState 的调用触发了更新,但实际的DOM更新在下一个调和阶段中完成。

这种异步更新的机制是为了提高性能,因为它可以合并多个状态更新,减少不必要的DOM操作。但需要注意,setState 调用并不会立即改变组件的状态,因此如果你想在状态更新后执行某些操作,应该在 componentDidUpdate 生命周期方法中进行。

4.说说css3的新特性有哪些?

  1. 选择器的增强:CSS3引入了众多新的选择器,如通用兄弟选择器(~)、属性选择器([attr])、伪类选择器(:nth-child)、伪元素选择器(::before::after)等。这些选择器提供更多的精确控制和灵活性。

  2. 盒子模型:CSS3引入了box-sizing属性,允许开发者控制盒子模型的计算方式,包括content-boxborder-box

  3. 圆角边框:使用border-radius属性,可以轻松创建圆角边框,而不再需要使用背景图片或其他技巧。

  4. 阴影效果:引入了box-shadow属性,可以为元素添加投影效果。

  5. 渐变:CSS3支持线性渐变(linear-gradient)和径向渐变(radial-gradient),使背景颜色和图片渐变变得更加容易。

  6. 多列布局column-countcolumn-gap等属性允许创建多列布局,使文本流更具吸引力。

  7. 媒体查询:媒体查询允许根据不同的设备、屏幕尺寸和特性来应用不同的CSS样式,从而实现响应式设计。

  8. 动画和过渡:CSS3引入了@keyframes规则和transition属性,用于创建动画和过渡效果,而不需要JavaScript。

  9. 变换(Transforms):CSS3的transform属性允许对元素进行旋转、缩放、倾斜和平移操作。

  10. 过渡(Transitions)transition属性允许在状态改变时平滑地过渡,以实现流畅的效果。

  11. 2D和3D转换:CSS3支持二维和三维的元素变换,包括旋转、缩放、移动和透视。

  12. 字体处理:引入了@font-face规则,允许使用自定义字体。

  13. 多重背景图片:可以为元素添加多个背景图像,通过逗号分隔它们。

  14. 伪类选择器:CSS3引入了众多伪类选择器,如:nth-child:not等,用于选择DOM元素的不同状态或位置。

  15. Grid布局:CSS Grid布局是一个强大的网格系统,用于创建复杂的布局结构。

这些特性使CSS更加强大和灵活,使开发者能够更轻松地实现各种设计和布局效果,同时提高了响应性和性能。不同浏览器对这些特性的支持程度可能有所不同,因此在使用时需要考虑兼容性。

5.说说redux的工作流程。

  1. Action创建:应用的各种操作和事件都会被抽象成一个个叫做"action"的普通JavaScript对象。这些对象描述了发生的事件,通常包括一个type属性来表示事件的类型,以及可选的其他数据。

  2. Dispatch:当应用中的某个部分需要更新状态时,它会创建一个相关的action对象,然后将该对象传递给Redux的store。这是通过调用store.dispatch(action)来完成的。

  3. Reducer处理:Redux的store将接收到的action对象传递给一个叫做"reducer"的纯函数。Reducer会根据action的类型来更新应用的状态。它接收先前的状态和action,然后返回一个新的状态。这一过程是纯函数,不会修改原始状态,而是返回一个新的状态副本。

  4. Store更新:一旦Reducer返回了新的状态,Redux的store将更新应用的状态。

  5. 通知订阅者:Redux支持订阅者模式,因此一旦状态发生变化,所有已注册的监听器(或称为订阅者)都会被通知。这使得应用的各个部分可以监听状态的改变,以做出相应的响应。

  6. View更新:React通常与Redux一起使用,以便将状态映射到UI组件上。当状态发生变化时,React会重新渲染相关的组件,从而更新用户界面。

Redux的工作流程强调了"单一数据源"(Single Source of Truth)的理念,即整个应用的状态被存储在一个单一的状态树中,这使得状态的管理变得可预测和可维护。通过分离状态的修改和UI的呈现,Redux提供了一种可维护和可测试的状态管理方法,特别适用于大型和复杂的应用程序。

6.React合成事件的原理,有什么好处和优势?

原理:

  1. 事件委托:React利用事件委托的原理,将所有事件监听器挂载到顶层容器(通常是document),而不是每个元素上。这样可以减少DOM元素上的事件监听器数量,提高性能。

  2. 事件池:React使用事件池来管理事件对象,这意味着事件对象在事件处理函数执行完毕后会被重用,而不是立即销毁。这减少了垃圾回收的压力,提高了性能。

好处和优势:

  1. 性能优化:React合成事件的事件委托和事件池机制有助于减少内存和性能开销。通过减少事件监听器数量和减少垃圾回收,提高了应用程序的性能。

  2. 跨浏览器兼容性:React合成事件屏蔽了不同浏览器之间的差异,使开发者不必担心浏览器兼容性问题。React会处理不同浏览器的事件差异,以确保一致的行为。

  3. 事件委托:React的事件委托机制允许你在组件树中处理事件,而不必在每个组件上都添加事件监听器。这样可以更容易管理事件处理逻辑,减少重复的代码。

  4. 性能监测和调试:React提供了开发者工具,可以用于监测和调试合成事件。你可以查看事件的详细信息,包括事件类型、事件目标和事件处理函数,以便更容易调试和分析应用程序的行为。

总的来说,React合成事件提供了一种高性能、一致性和易于调试的事件处理机制,使开发者可以更专注于应用程序的逻辑,而不必过多关注浏览器差异和性能优化。这有助于提高React应用程序的开发效率和用户体验。

7.为什么 react 元素会有一个$$type属性?

React使用$$type属性来表示元素的类型,通常是一个字符串,表示HTML元素的标签名(如divp等)或React组件的类型(如自定义组件)。这有助于React在虚拟DOM的比较过程中快速确定元素的类型,以便进行高效的更新和渲染。

应用程序代码通常不需要访问或使用$$type属性,因为它是React内部的实现细节。开发者应该专注于使用React提供的公共API来创建、更新和渲染元素,而不必担心$$type属性。

在React的官方文档中,$$type属性是私有的,并没有被正式记录在文档中,因此不建议开发者在自己的应用程序代码中使用它。如果你需要获取元素的类型,可以使用type属性或element.type来访问。

8.React有哪些优化性能的手段?

React提供了多种性能优化的手段,以确保应用程序在大型和复杂的场景下也能保持高性能。以下是一些React性能优化的常见手段:

  1. 使用合成事件:React的合成事件系统能够提高性能,因为它使用事件委托,将事件监听器挂载在顶层容器上,而不是每个DOM元素上。这减少了事件监听器的数量,从而减小了内存和性能开销。

  2. 使用组件级别的shouldComponentUpdate或React.memo:通过shouldComponentUpdate方法或React.memo函数,可以控制组件的更新过程。这允许你避免不必要的重新渲染,只有在状态或属性发生实际变化时才重新渲染组件。

  3. 使用React的虚拟DOM:React使用虚拟DOM来比较前后两个状态树,从而最小化对实际DOM的操作。这减少了DOM操作的次数,提高了性能。

  4. 使用列表和键(Keys):在渲染列表时,使用唯一的键来标识每个列表项,以帮助React识别添加、删除或重新排序的操作。这有助于React更有效地管理列表的更新。

  5. 避免深层次的嵌套:过多的嵌套组件可能会导致性能问题。尽量保持组件层次扁平,只嵌套必要的组件。

  6. 使用React的Context API:Context API允许跨组件层次传递数据,而不必一层层地通过属性传递。这有助于避免不必要的属性传递,提高了代码的可维护性。

  7. 使用懒加载和代码拆分:将应用程序代码拆分成小块,按需加载,以减小初始加载时间。React懒加载的React.lazy()Suspense功能可用于按需加载组件。

  8. 使用生命周期方法或副作用钩子:合理使用componentDidMountcomponentDidUpdatecomponentWillUnmount等生命周期方法,以及useEffect等副作用钩子,以执行异步操作、订阅和取消订阅等操作。

  9. 使用生产模式:在生产环境中,确保使用React的生产模式版本,以去除开发模式下的额外检查和警告,提高性能。

  10. 性能监测和分析工具:使用性能监测工具,如React DevTools、Chrome DevTools的性能面板等,来识别和解决性能问题。

这些是一些通用的React性能优化手段,但具体的优化方法可能取决于应用程序的结构和需求。在实际开发中,可以使用这些方法来提高React应用的性能并确保良好的用户体验。

9.说说你对fiber架构的理解?解决了什么问题?

  1. 渲染中断和调度优先级:传统的React调度算法是递归的,当组件树很深或组件数量很多时,可能导致渲染操作阻塞主线程,引起页面卡顿。React Fiber引入了可中断的渲染,将渲染过程分解为多个小任务,每个任务都有一个优先级。这样可以更好地控制渲染的优先级,允许浏览器在渲染期间响应用户交互。

  2. 增量更新:传统的React在更新时会进行完整的虚拟DOM比较,然后更新整个组件树。React Fiber引入了增量更新的能力,使得React可以只更新发生变化的部分,从而减少不必要的工作,提高性能。

  3. 并行处理:React Fiber引入了并行处理的概念,允许React在多个任务之间切换,从而更充分地利用多核CPU。这可以加速渲染操作,特别是在处理大型应用程序或复杂组件树时。

  4. 可终止和可恢复的渲染:Fiber允许React在渲染任务中间被终止,而不会破坏整个渲染过程。这对于处理大型列表或复杂UI场景非常有用。一旦浏览器有时间,React可以继续之前被中断的渲染任务。

  5. 更好的动画支持:React Fiber提供了更好的动画支持,可以更精确地控制动画和布局过程。这有助于创建流畅的用户体验。

  6. 自定义渲染器:Fiber的架构允许开发者创建自定义渲染器,以适应不同的平台和环境,如React Native、VR应用等。

总的来说,React Fiber的目标是改进React的渲染性能,使其更适用于大型和复杂的应用程序,提供更好的用户体验,同时提高了React的可扩展性,以适应各种不同的应用场景。这一架构的引入使得React更灵活、高效和强大。

10.说说你对redux中间件的理解?常用的中间件有哪些?实现原理?

redux是一个针对于JavaScript所建立的框架而搭建的第三方数据存储空间,其效果类似于vue中的vuex,其中可以根据数据不同,拆分成不同的文件进行存储,数据是单向数据流,保障了数据的稳定,并且其修改数据需要通过定义函数的方式进行修改,使得数据可以以一种可预测的方式,进行修改操作

11.如何使用css实现一个三角形,写出两种以上方案得满分。

.triangle {
width: 0;
height: 0;
border-left: 50px solid transparent; /* 左侧透明 /
border-right: 50px solid transparent; /
右侧透明 /
border-bottom: 100px solid #f00; /
底部实色 /
}
.triangle {
width: 0;
height: 0;
border-style: solid;
border-width: 50px 50px 0 50px; /
上、右、下、左 /
border-color: #00f transparent transparent transparent; /
颜色、透明、透明、透明 */
}

12.断轮询、长轮询和websocket的区别?

  1. 短轮询(Short Polling)

    • 工作原理:客户端定期向服务器发送HTTP请求,询问是否有新数据可用。
    • 应用场景:适用于需要实时数据更新,但对延迟和网络带宽要求不高的应用。通常会产生频繁的HTTP请求。
    • 优点:简单,适用于大多数浏览器和服务器。不需要特殊的协议支持。
    • 缺点:产生较多的网络流量,可能会导致高延迟。
  2. 长轮询(Long Polling)

    • 工作原理:客户端向服务器发送一个HTTP请求,服务器保持请求打开,直到有新数据可用时才响应,然后客户端会立即发送下一个请求。
    • 应用场景:适用于需要较低延迟但不能支持WebSocket的应用。减少了HTTP请求次数,但仍然会有一些延迟。
    • 优点:较短轮询来说,减少了不必要的HTTP请求。
    • 缺点:服务器需要保持连接打开,浏览器需要等待响应,可能会导致资源占用和连接限制。
  3. WebSocket

    • 工作原理:WebSocket是一种双向通信协议,允许服务器主动向客户端发送数据,而不需要客户端发起请求。通信始终是活跃的连接。
    • 应用场景:适用于需要实时、低延迟通信的应用,如聊天应用、实时游戏等。
    • 优点:实时、低延迟,减少了不必要的HTTP请求。双向通信使服务器可以主动推送数据。
    • 缺点:需要浏览器和服务器支持WebSocket协议,可能需要额外的配置和安全考虑。

总结,短轮询、长轮询和WebSocket都是用于实现实时通信的技术,但它们在性能、延迟、复杂性和应用场景上有不同的权衡。选择哪种技术取决于你的应用需求和支持情况。WebSocket通常是最佳选择,因为它提供了双向通信和低延迟,但如果无法使用WebSocket,则长轮询或短轮询可能是备选方案。

13.前端跨域的解决方式?

  1. JSONP(JSON with Padding)

    • JSONP是一种跨域请求的方法,它通过动态添加<script>标签来获取数据。服务器返回的数据包装在回调函数中,然后在页面中执行该回调函数,以获取数据。
    • 优点:简单易用,可以在不支持CORS的老浏览器上使用。
    • 缺点:不支持POST请求,存在安全风险,只能用于获取数据。
  2. CORS(跨域资源共享)

    • CORS是一种官方的跨域解决方案,需要服务器设置响应头中的Access-Control-Allow-Origin等相关字段,以允许特定域名的请求。
    • 优点:安全且强大,支持各种HTTP方法,适用于现代浏览器。
    • 缺点:需要服务器端支持,不适用于旧版本浏览器。
  3. 代理服务器

    • 前端可以使用自己的服务器作为代理,将跨域请求发送给自己的服务器,然后由服务器代为向目标服务器请求数据,最后将数据传递给前端。这种方式可以绕过浏览器的同源策略。
    • 优点:适用于所有浏览器,可以处理复杂的跨域请求。
    • 缺点:需要自己的服务器,并且可能会增加服务器负担。
  4. 跨文档消息传递(Window.postMessage)

    • 使用postMessage API可以在不同窗口或iframe之间进行跨域通信。前端可以将消息发送到另一个窗口,然后在接收窗口中处理消息。
    • 优点:安全,适用于多窗口通信。
    • 缺点:需要对方窗口的协助。
  5. JSON Web Tokens(JWT)

    • JWT是一种用于在不同域之间进行安全身份验证和授权的标准。它可以在不同域之间传递数据,并验证数据的真实性。
    • 优点:安全,适用于身份验证和授权。

选择哪种跨域解决方案取决于你的应用需求和目标,以及你的控制权和能力。通常,CORS是最常见和最强大的解决方案,但其他方法也有其用途,根据具体情况选择最适合的方案。

14.说说你对@reduxjs/toolkit的理解?和react-redux有什么区别?

@reduxjs/toolkit是一个Redux官方推荐的工具集,它的主要目的是简化和加速Redux开发流程,提供了一组工具和约定,以减少样板代码和提高开发效率。下面是我对@reduxjs/toolkit的理解以及它与react-redux之间的区别:

@reduxjs/toolkit的特点和理解

  1. Redux简化@reduxjs/toolkit减少了编写Redux的样板代码的工作,包括定义action和reducer,以及配置store。它提供了一个更简洁的方式来创建和组织Redux相关的代码。

  2. 包含Redux工具@reduxjs/toolkit内置了许多有用的Redux工具,如createSlice用于创建Redux模块、configureStore用于配置Redux store,以及createAsyncThunk用于处理异步操作。

  3. 不需要手动处理不变性@reduxjs/toolkit内部使用了Immer库,允许你编写可变的Redux reducer代码,而不需要手动处理深层复制和不变性。这简化了Reducer的编写。

  4. 默认配置@reduxjs/toolkit为你提供了一个合理的默认配置,减少了配置和样板代码的需要。你可以根据需要自定义配置。

  5. 强调最佳实践@reduxjs/toolkit鼓励使用最佳实践,如组织代码、分割reducers、使用异步action等。

区别

  • @reduxjs/toolkit是Redux的辅助工具集,用于简化和加速Redux开发,但它仍然是Redux的一部分。它并不是独立于Redux的状态管理库。

  • react-redux是React应用程序中与Redux集成的库,它提供了React组件和Redux store之间的连接机制,允许你将Redux store中的状态传递给React组件,以及将Redux action派发给Redux store。react-redux是与React紧密集成的,而@reduxjs/toolkit与Redux本身更相关。

  • @reduxjs/toolkit通常用于简化Redux的配置和开发过程,而react-redux用于在React应用中连接React组件与Redux store。这两者通常一起使用,但它们有不同的目的和关注点。

15.React render方法的原理,在什么时候会触发?

React render方法的原理

  1. 虚拟DOM(Virtual DOM)render方法并不直接操作真实的DOM,而是返回一个虚拟的React元素。这个虚拟DOM是对真实DOM的一种抽象,它包含了创建、更新和删除真实DOM节点所需的所有信息。
  2. Diffing算法:当组件的状态或属性发生变化时,React会重新调用render方法生成新的虚拟DOM。然后,React会使用一个高效的Diffing算法(差异化算法)来比较新旧两个虚拟DOM的差异。这个算法会找出需要更新的最小DOM子集,并生成一个更新指令集。
  3. 更新DOM:最后,React会根据更新指令集来更新真实的DOM,只改变需要改变的部分,从而实现高效的用户界面更新。

React render方法的触发时机

  1. 组件首次挂载:当组件首次挂载到DOM树上时,会触发render方法的调用。
  2. 状态更新:当组件的状态(state)发生变化时,会触发render方法的重新调用。这通常发生在调用this.setState()方法后。
  3. 属性更新:当组件的属性(props)发生变化时,也会触发render方法的重新调用。这通常发生在父组件的状态或属性发生变化,导致子组件需要重新渲染时。
  4. 强制更新:在某些情况下,可以使用React.forceUpdate()方法来强制触发组件的render方法调用。但这种方法通常不推荐使用,因为它会跳过React的Diffing算法,可能导致性能问题。

需要注意的是,render方法应该是一个纯函数,即对于相同的输入,它应该总是返回相同的结果,并且不应该直接修改组件的状态或属性。这样可以确保React能够正确地比较新旧虚拟DOM的差异,并生成正确的更新指令集。

16.Redux中同步 action 与异步 action最大的区别?

同步Action

  • 同步action是指立即执行的操作,不涉及任何异步操作。
  • 同步action的动作创建函数(action creator)会立即返回一个包含动作类型和数据的action对象,通常使用dispatch函数触发。
  • 同步action用于处理立即执行的操作,例如用户点击按钮、输入框变化等。
  • 由于同步action是立即执行的,所以它们通常用于处理简单的状态变更,不需要等待异步操作的结果。
const increment = () => ({
  type: 'INCREMENT',
});
dispatch(increment()); // 触发同步action

异步Action

  • 异步action是指涉及异步操作的动作,需要等待异步操作的结果,例如网络请求或定时任务。
  • 异步action的动作创建函数通常会返回一个函数,而不是一个包含动作对象的函数。这个返回的函数通常接受dispatchgetState作为参数,允许在异步操作完成后触发一个或多个同步action。
  • 异步action用于处理需要等待异步操作结果的情况,例如从服务器获取数据后更新应用状态。
const fetchData = () => (dispatch, getState) => {
 dispatch({ type: 'FETCH_DATA_REQUEST' });
 // 异步操作,例如发起网络请求
 api.fetchData().then(
   (data) => {
     dispatch({ type: 'FETCH_DATA_SUCCESS', payload: data });
   },
   (error) => {
     dispatch({ type: 'FETCH_DATA_FAILURE', error });
   }
 );
};
dispatch(fetchData()); // 触发异步action

总之,同步action用于立即触发状态变更,而异步action用于处理需要等待异步操作结果的情况。在Redux中,通常使用异步action来处理网络请求、定时任务等涉及异步操作的情况,以确保应用程序状态的一致性。同步action通常用于处理用户的交互操作和状态变更,它们不需要等待异步结果。

17.React的props.children使用map函数来遍历会收到异常显示,为什么?应该如何遍历?

如果你的props.children包含单个React元素或组件,map函数将无法直接使用,因为它期望一个数组来进行映射操作。如果你只有一个子元素,你可以将其包装在一个数组中,然后使用map函数遍历,如下所示:

import React from 'react';

function MyComponent(props) {
  const childrenArray = React.Children.toArray(props.children);

  return (
    <div>
      {childrenArray.map((child, index) => (
        <div key={index}>
          {child}
        </div>
      ))}
    </div>
  );
}

在上面的示例中,React.Children.toArray(props.children)props.children转换为一个数组,然后你可以使用map函数来遍历子元素。

另一种常见情况是props.children包含多个子元素,每个子元素都有自己的类型。在这种情况下,你可以使用React.Children.map来处理props.children,它会为你处理各种类型的子元素,如下所示:

import React from 'react';

function MyComponent(props) {
  return (
    <div>
      {React.Children.map(props.children, (child, index) => {
        return (
          <div key={index}>
            {child}
          </div>
        );
      })}
    </div>
  );
}

使用React.Children.map可以避免一些潜在的异常,因为它会处理各种类型的子元素,包括字符串、数字和React元素。如果props.children包含非React元素,直接使用map函数可能会导致异常。

需要注意的是,遍历props.children时要为每个子元素指定一个唯一的key属性,以帮助React进行有效的更新和重渲染。

18.React 组件之间如何通信?

react的组件通信主要有四点
1、props:父组件可以通过将所传递的信息绑定到子组件标签中的方式,将信息传递给子组件,而子组件可以将这些信息通过props的方式将其内容进行接收。
2、回调函数:子组件想要将内容进行传递,需要在父组件中定义一个回调函数,这个回调函数通过子组件标签发送给子组件,子组件将所需要传递的信息通过触发该回调函数的方式将其传递给父组件,父组件可以将该信息进行赋值接收使用。
3、上下文(Context)**:React的上下文机制允许你在组件层次结构中的祖先组件和后代组件之间共享数据,而不必手动传递props。这对于全局状态管理非常有用。

4、状态管理库**:对于大型应用程序,你可以使用状态管理库(如Redux、Mobx、或React的useContextuseReducer)来管理应用的状态,以便多个组件可以访问和修改共享的状态。

  1. 事件总线:你可以创建一个事件总线对象,允许组件订阅和触发事件,以便它们可以相互通信。这在某些特定情况下很有用,但要小心不要滥用它,以避免代码变得难以维护。

这些方法可以根据你的应用程序需求来选择和组合使用。通常,使用props传递数据是最常见的方式,但在某些情况下,使用上下文或状态管理库可能更合适。

19.说说你对受控组件和非受控组件的理解?应用场景?

受控组件,可以将变量的值通过value的方式绑定给某个输入框,然后通过onchange的事件,对该值进行实时的更新,实现类似于双向绑定的效果,常用于搜索框,下拉框,单选框,多选框,按钮等情况下,直接对该值进行使用或者修改。
非受控组件,非受控组件是通过ref的方式,在标签中绑定该ref的方式,可以使得通过ref的方式获取到该标签的所有信息,并且可以通过ref来修改该标签的样式和该标签的内容,应用场景就是在需要修改样式或者不是绑定的信息进行修改的时候,对其进行直接修改。

20.说说javascript内存泄漏的几种情况?

JavaScript内存泄漏是指应用程序中的内存不再被使用,但没有被正确释放,导致内存占用不断增加,最终可能导致应用程序性能下降或崩溃。以下是一些常见的导致JavaScript内存泄漏的情况:

  1. 未被释放的引用:当一个对象仍然存在对其他对象的引用,即使你不再需要这个对象,它也不会被垃圾回收。这种情况通常发生在事件处理程序、闭包或全局变量中。
  2. 定时器未清理:如果你创建了定时器(setTimeoutsetInterval)但没有清理它们,它们会一直运行,即使不再需要。这会导致函数和相关数据一直存在于内存中。
  3. DOM引用未清理:在JavaScript中,如果你保留对DOM元素的引用,而这些元素被删除或替换,那么对这些引用的引用仍然存在于内存中,导致内存泄漏。
  4. 循环引用:循环引用是指两个或多个对象相互引用,而没有其他引用指向它们,垃圾回收器无法检测到它们不再被使用。这通常发生在对象之间的互相引用,比如父子关系或闭包
    1. 内存泄漏工具不足:有时,内存泄漏可能是由于工具或框架本身的问题,例如浏览器或第三方库的内存泄漏。

解决JavaScript内存泄漏的方法包括及时释放不再需要的引用、手动清理定时器和事件处理程序、避免循环引用、使用内存泄漏检测工具和定期检查和分析内存占用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值