react面试题(自学记录)

一、什么是React?为什么会出现React这样的框架?

        1.React是一个用于构建用户界面的JavaScript库。

        2.React是Facebook开发的一款JS库,Faccbook认为MVC不适合大规模的应用,当系统中有很多模型和相应的试图时,其复杂程度就会迅速扩大,导致难以理解及调试,特别是模型和视图可能存在双向数据流动。解决方法通过Flux和React。React官网关于React还可以了解到以下四点:

        ①React不是一个MVC框架。

        ②React不使用模板。

        ③响应式更新非常简单。

        ④HTML5仅仅是一个开始。

二、什么是Flux和React?

        1.Flux是一个系统框架,用于推进应用中的数据单向流动。

        2.React是一个JavaScript框架,用于构建“可预测的”和声明式的“Web用户界面”。

三、React的特点是什么?

        1.声明式设计---React采用声明范式,可以轻松描述应用。

        2.高效---React通过对DOM的模拟,最大限度地减少与DOM的交互。

        3.灵活---React可以与一致的库或框架很好地配合。

        4.JSX---JSX是JavaScript语法的扩展。(React开发不一定使用JSX,但是建议使用)

        5.组件---通过React构建组件,使得代码更加容易得到复用,能够很好的应用在大项目的开发中。

        6.单项响应数据流---React实现了单项响应数据流,从而减少了重复代码,这也是它比传统数据绑定更简单的原因。

四、React主要原理是什么?

        1.Virtual DOM(虚拟DOM):Virtual DOM实际上是JS对象,使用React之后我们不直接和DOM API打交道,我们直接访问JS对象比访问DOM API高效的多。我们通过Virtual DOM去更新真实的DOM,由这个Virtual DOM管理真实DOM的更新。

        2.Diff算法:在React中,Diff算法需要与Virtual DOM配合。React会使用Diff算法计算出Virtual DOM中真正发生变化的部分,并且只会针对该部分进行DOM操作,从而避免了对页面进行大面积的更新渲染,减小性能的开销。更新Virtual DOM并不保证马上影响真实的DOM,React会等到时间循环结束利用Diff算法,这也是为什么通过多一层的Virtual DOM操作会更快的原因,通过当前新的DOM表述与之前旧的DOM 作比较,计算出最小的步骤更新DOM。

        3.Components组件:Virtual DOM的节点被称为component,它是一个完整抽象的组件,由components构成。components的存在让计算DOM Diff更高效。

注意:原生HTML元素名以小写字母开头,而自定义的React类名以大写字母开头。除此之外还需要注意组件类只能包含一个顶层标签,否则也会报错。

五、在React中元素(element)和组件(component)有什么区别?

       1.在React中元素(虚拟DOM)是页面中DOM元素的对象表示方式。

       2.在React中组建是一个函数或一个类,它可以接收输入并返回一个元素。

注意:在工作中为了提高开发效率,通常使用JSX语法表示React元素(虚拟DOM)。

六、什么是React的refs?为什么他很重要?

        1.refs允许你直接访问DOM元素或组件的实例。使用时,向组件添加个ref属性。

        2.如果该属性值是一个回调函数,它将接受底层的DOM元素或组件的已挂载实例作为第一个参数,可以在组件中存储它。

export class App extends Component {
    showResult() {
        console.log(this.input.value)
    }
    
    render() {
        return (
            <div>
                <input type="text" ref={input => { this.input = input }/>
                <button onClick={this.showResult.bind(this)}>展示结果</button>
            </div>
            )
        }
    }

注意:如果属性值是一个字符串,React将会在组件实例化对象的refs属性中,存储一个同名的属性,该属性是对这个DOM元素的引用。可以通过原生的DOM API操作它。

export class App extends Component {
      showResult() {
        console.log(this.refs.username.value)
    }
    
    render() {
        return (
            <div>
                <input type="text" ref="username"/>
                <button onClick={this.showResult.bind(this)}>展示结果</button>
            </div>
            )
        }
    }

七、Vue和React的共同点和区别是什么?

        1.共同点:

        ①都使用了虚拟DOM。

        ②都提供了响应式和组件化的视图组件。

        ③都有全局状态管理的库。(vue-router、vuex、react-router、redux等)

        2.区别:

        ①Vue是双向绑定,采用template;React是单项的,采用jsx。

        ②性能方面:当组件的状态发生变化时,React的机制会触发整个组件树的重新渲染,Vue提供了优化的重新渲染,其中系统在渲染过程中跟踪依赖关系并相应地工作。

八、React Diff原理

        1.把树形结构按照层次分解,只比较同级元素。

        2.给列表结构的每个单元添加唯一的key属性,方便比较。

        3.React只会匹配相同class的component(class指的是组件的名字)

        4.合并操作,调用component的setState方法的时候,React将其标记为dirty到每一个事件循环,React检查所有标记dirty的component重新绘制。

        5.选择性子树渲染。开发人员可以重写shouldComponentUpdate提高Diff的性能。

九、React中的组件传参。

        1.父传子:将父组件中的属性传入子组件,子组件可以用props直接接受并使用。

        2.子传父:子组件调用父组件中传来的方法来改变父组件中的值。

        3.兄弟间:找到二者共同的父节点,结合上面两种方式由父节点转发信息进行通信。

        4.跨层级:使用context上下文,通过使用context.Provider数据提供者来实现全局的数据共享。

        5.发布订阅模式:通过引入event模块进行通信。

        6.全局状态管理工具:借助Redux或者Mobx等全局状态管理工具进行通信。

十、React中class定义的组件生命周期钩子函数(初始化阶段、运行中阶段、销毁阶段)

        1.初始化阶段

        ①设置组件的初始化状态:constructor()

        ②组件在挂载之前触发,这时可向开启定时器或向服务器发送请求:componentWillMount()

        ③组件渲染:render()

        ④组件渲染完毕,此时可执行DOM的相关操作:componentDidMount()

        2.运行中阶段

        ①组件接收到新的属性时触发:componentWillReceiveProps()

        ②组件接收新属性或组件状态发生改变时触发(首次渲染不触发):shouldComponentUpdate()

        ③组件更新前触发:componentWilllUpdate()

        ④组件更新完毕,页面产生新的DOM,可进行DOM操作:componentDidUpdate()

        3.销毁阶段

        组件销毁前触发,可做清理操作(清除定时器):componentWillUnMount()

十一、React中Hooks是如何模拟组件的生命周期的?

        1.componentDidMount

function Example() {
    useEffect(() => console.log('mounted'),[]);
    return null;
    }

        2.componentDidUpdate

function Example() {
    useEffect(() => console.log('count update'),[count]);
    return null;
    }

        3.componentWillUnmount

function Example() {
    useEffect(() => {
        return () => {
            console.log('will unmount');
         }
        },[]);
    }

十二、React中class定义的组件和function定义的组件的区别?

        1.function定义的组件没有this指向的问题。

        2.class定义的组件有自己的局部状态(this.state)和自己的生命周期函数。

        3.function定义的组件是无状态组件,在16.8之后可以用Hooks(useEffect)来模拟组件的局部状态和生命周期。

十三、谈谈你对React中的高级组件的了解。

        1.高阶组件就是一个没有副作用的纯函数。

        2.高阶组件是把一个组件当做参数,返回值作为新组件的函数。

        3.高阶组件实际上就是高阶函数,如map、forEach。

        4.常用的高阶组件:withRouter(路由中的),connect(reduct-redux中的)。

十四、Redux的理解。

        1.Redux是一个全局状态管理插件,用来操作数据的,可以结合任何一个js库来使用。

        2.Redux是单向数据流,view通过dispatch来派发一个action改变数据,数据改变之后,页面重新渲染。

        3.Redux分为三部分:state用来存储数据,所有的数据改变都在reducer中进行,redux中还有一个action,用来组织数据。

十五、Redux遵循的三原则

        1.单一事件来源:整个应用的状态存储在单个store中的对象/状态树里。

        注:单一状态树可以更容易地跟随时间变换,并调试和检查程序。

        2.状态是只读的:改变状态的唯一方法是去触发一个动作。

        3.使用纯函数进行更改:指定状态树如何通过操作进行转换。

        注:纯函数指返回值仅取决于其参数值的函数。

十六、Redux组件组成

        1.View—只显示Store提供的数据

        2.Store—整个程序的状态/对象树保存在Store中。

        注:Store是一个JS对象,它可以保存程序的状态,并提供方法来访问状态、调度操作和注册侦听器。我们可以将中间件传递到Store来处理数据,并记录改变存储状态的各种操作。所有操作都通过Reducer返回一个新状态。

        3.Reducer—确定状态如何变化。

        注:Reducers是纯函数,他规定应用程序的状态怎样因响应Action改变。Reducers通过接受先前的状态和Action来工作,然后返回一个新状态。根据操作类型确定需要执行哪种更新,然后返回新的值。若不需要完成任务,返回原来的状态。

        4.Action—用来描述发生什么的事情的对象

        注:Action必须有type属性,该属性是指示正在执行的Action的类型。必须将它们定义为字符串常量,并且还可以向其添加更多的属性。

function addTodo(text) {
    return {
            type:ADD_TODO,
                 text
    }
}

十七、Redux的优点是什么?

        1.结果的可预测性—存在真实来源Store

        2.可维护性—具有可预测的结果和严格的结构

        3.服务器端渲染—优化应用性能,对初渲染友好,从而提供更好的用户体验

        4.开发人员工具—从操作到状态更改,开发人员可以实时跟踪应用中发生的所有事情

        5.易于测试—Redux的代码主要小巧、纯粹和独立的功能

        6.组织—Redux准确的说明了代码的组织方式

        7.社区和生态系统——Redux背后有一个巨大的社区

十八、React中的错误边界

        1.React16.X中引入了错误边界(Error Boundaries)概念。

        2.以React组件的形式实现,可以捕获它的子组件中产生的错误,类似于try-catch。

        3.有了错误边界,即使某个组件有错误,整个程序仍然完全正常运行,只有出错的组件会显示一个后备界面。

        4.只有类组件才可以成为错误边界。componentDidcatch()函数使用方法与JS中catch{}代码块类似,但只能用于组件。

        5.componentDidcatch()函数内部将hasError状态设置为true:如果出错状态为true,就渲染后备界面;如果是false就是将想渲染的React组件界面当做子组件界面渲染出来。

        6.无法捕获的错误Error Boundaries:

        ①事件错误。

        ②Error Boundaries本身错误。

        ③异步代码。

十九、对React router的理解

        1.React路由是构建在React之上的强大路由库,有助于向应用程序添加新的屏幕和流,使URL与网页上显示的数据保持同步,用于开发单页面Web页面。

        2.React Router的优点:

        ①在React Router v4中,API是'All About Components'。可以将 Router 可视化为单个根组件其中我们将特定的子路由()包起来。

        ②无需手动设置历史值:在 React Router v4 中,我们要做的就是将路由包装在 组件中。

        ③包是分开的:共有三个包,分别用于 Web、Native 和 Core,基于类似的编码风格很容易进行切换。

        3.当想要仅显示要在多个定义的路线中呈现的单个路线时,可以使用'switch'关键字。其会按顺序将已定义的URL与已定义的路由进行匹配。找到第一个匹配项后,渲染指定路径,从而绕过其他路线。

<switch>
    <route exact="" path="'/'" component="{Home}/">
    <route path="'/posts/:id'" component="{Newpost}/">
    <route path="'/posts'" component="{Post}/">
</route></route></route></switch>

二十、React中react-router和react-router-dom的区别

        1.API

        ①React-router:提供了路由的核心API。如Router、Route、Switch等,但没有提供有关DOM操作进行路由跳转的API。

        ②React-router-dom:提供了BrowserRouter、Route、Link等API,可以通过DOM操作触发事件控制路由。

        Link组件:渲染一个a标签。

        BrowserRouter组件:使用pushState和popState时间构建路由。

        HashRouter组件:使用hash和hashchange事件构建路由。

        2.动态路由跳转

        ①React-router:(router4.0以上) this.props.history.push('/path')

                                    (router3.0以上) this.props.router.push('/path')

        ②React-router-dom:this.props.history.push('/path')

        3.使用区别

        ①React-router-dom:在React-router的基础上扩展了可操作DOM的API。

        ②直接npm安装react-router-dom,可使用react-router的API。

        ③Swith和Route都是从react-router中导入了相应的组件并重新导出。

import { Switch, Route, Router } from 'react-router';
import { Switch, Route, BrowserRouter, HashHistory, Link } from 'react-router-dom';

二十一、Hooks的优缺点

        1.优点

        ①更容易复用代码

        ②清爽的代码风格:函数式编程风格,函数式组件、状态保存在运行环境、每个功能都包裹在函数中,整体风格更优雅、清爽。

        ③代码量更少:props或状态取值更方便,从父级作用域直接取。更改状态也变得更加简单。

        ④更容易发现无用的状态和函数。

        ⑤更容易拆分组件

        2.缺点:

        ①部分代码从主动变成响应式 

        ②状态不同步

二十二、React常用的Hooks,及使用场景

        1.useState:使用useState来定义函数组件的状态

        ①引入

        ②接受一个参数作为初始值

        ③返回一个数组,第一个值为状态,第二个值为改变状态的函数

        2.useEffect(副作用Hooks):给没有生命周期的组件,添加结束渲染的信号。在渲染结束之后执行。

        ①第一个参数,接受一个函数作为参数

        ②第二个参数,接受[依赖列表],只有依赖更新时,才会执行函数

        注:①如果不接受第二个参数,那么每次更新渲染页面都会调用useEffect的回调函数

        ②如果第二个参数传入一个数组,这个数组表示在更新执行所依赖的列表,只有依赖列表改变时,才会触发回调函数。

        ③如果第二个参数传入一个空数组[ ],useEffect只运行一次,以获取页面的初始数据

        ③返回一个函数,先执行返回函数,在执行参数函数

        注:副作用是指数据获取,数据订阅,以及手动更改React组件中的DOM

        3.useLayoutEffect:在DOM更新完成之后执行某个操作(有DOM操作的副作用Hooks)

        注:useLayoutEffect会比useEffect先执行

        4.useMemo:组件中的函数跟随状态更新(优化函数组件的功能函数)

        ①接受一个函数作为参数

        ②同样接受第二个参数作为依赖列表(对比useEffect、useLayoutEffect)

        ③返回一个值。(返回值类型不限)

        5.useCallback:让某些操作、方法跟随状态的更新去执行。返回一个函数。(对比useMemo学习)

        6.useRef:用于长久的保存数据,返回一个子元素索引。

        注:保存的对象发生改变,不通知,属性变更不会重新渲染。

        7.useContext:子组件之间共享父组件传入状态。

二十三、Real DOM和Virtual DOM的区别

Real DOM(真实DOM)Virtual DOM(虚拟DOM)
1.更新缓慢。1.更新更快。
2.可以直接更新HTML。2.无法直接更新HTML。
3.元素更新,创建新DOM。3.元素更新,更新JSX。
4.DOM操作代价高。4.DOM操作简单。
5.消耗内存多。5.很少的内存消耗。

        

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值