React面试题(超详细,附答案)
<h2 class="md-end-block md-heading"><span class="md-plain">生命周期</span></h2><ul class="ul-list" data-mark="*">
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">组件将要挂载时触发的函数:<span><code>componentWillMount</code></span></span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">组件挂载完成时触发的函数:<span><code>componentDidMount</code></span></span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">是否要更新数据时触发的函数:<span><code>shouldComponentUpdate</code></span></span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">将要更新数据时触发的函数:<span><code>componentWillUpdate</code></span></span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">数据更新完成时触发的函数:<span><code>componentDidUpdate</code></span></span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">组件将要销毁时触发的函数:<span><code>componentWillUnmount</code></span></span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">父组件中改变了props传值时触发的函数:<span><code>componentWillReceiveProps</code></span></span></p>
</li>
</ul>
<h2 class="md-end-block md-heading"><span><code>shouldComponentUpdate</code><span class="md-plain md-expand"> 的作用?</span></span></h2>
<blockquote>
<p class="md-end-block md-p"><span><code>shouldComponentUpdate</code><span class="md-plain"> 允许我们手动地判断是否要进行组件更新,根据组件的应用场景设置函数的合理返回值能够帮我们避免不必要的更新</span></span></p>
</blockquote>
<h2 class="md-end-block md-heading"><span class="md-plain">React 中 keys 的作用是什么?</span></h2>
<blockquote>
<p class="md-end-block md-p"><span><code>Keys</code><span class="md-plain">是 <span><code>React</code><span class="md-plain"> 用于追踪哪些列表中元素被修改、被添加或者被移除的辅助标识</span></span></span></span></p>
</blockquote>
<ul class="ul-list" data-mark="*">
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">在开发过程中,我们需要保证某个元素的 <span><code>key</code><span class="md-plain"> 在其同级元素中具有唯一性。在 <span><code>React Diff</code><span class="md-plain"> 算法中<span><code>React</code><span class="md-plain"> 会借助元素的 <span><code>Key</code><span class="md-plain"> 值来判断该元素是新近创建的还是被移动而来的元素,从而减少不必要的元素重渲染。此外,React 还需要借助 <span><code>Key</code><span class="md-plain"> 值来判断元素与本地状态的关联关系,因此我们绝不可忽视转换函数中 <span><code>Key</code><span class="md-plain"> 的重要性</span></span></span></span></span></span></span></span></span></span></span></span></span></p>
</li>
</ul>
<h2 class="md-end-block md-heading"><span class="md-plain">(组件的)状态(state)和属性(props)之间有何不同?</span></h2>
<ul class="ul-list" data-mark="*">
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">State 是一种数据结构,用于组件挂载时所需数据的默认值。State 可能会随着时间的推移而发生突变,但多数时候是作为用户事件行为的结果</span></p>
</li>
</ul>
<ul class="ul-list" data-mark="*">
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">Props(properties 的简写)则是组件的配置。props 由父组件传递给子组件,并且就子组件而言,props 是不可变的(immutable)。组件不能改变自身的 props,但是可以把其子组件的 props 放在一起(统一管理)。Props 也不仅仅是数据--回调函数也可以通过 props 传递。</span></p>
</li>
</ul>
<h2 class="md-end-block md-heading"><span class="md-plain">何为受控组件(controlled component)?</span></h2>
<blockquote>
<p class="md-end-block md-p"><span class="md-plain">在 HTML 中,类似 <span><code><input/></code><span class="md-plain">, <span><code><select></code><span class="md-plain"> 和 <span><code><textarea></code><span class="md-plain"> 这样的表单元素会维护自身的状态,并基于用户的输入来更新。当用户提交表单时,前面提到的元素的值将随表单一起被发送。但在 React 中会有些不同,包含表单元素的组件将会在 state 中追踪输入的值,并且每次调用回调函数时,如 <span><code>onChange</code><span class="md-plain"> 会更新 state,重新渲染组件。一个输入表单元素,它的值通过 React 的这种方式来控制,这样的元素就被称为"受控元素"。</span></span></span></span></span></span></span></span></span></p>
</blockquote>
<h2 class="md-end-block md-heading"><span class="md-plain">展示组件(Presentational component)(也叫 <span><code>UI</code><span class="md-plain"> 组件)和容器组件(Container component)(负责应用逻辑处理)之间有何不同</span></span></span></h2>
<ul class="ul-list" data-mark="*">
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">展示组件(<span><code>UI</code><span class="md-plain"> 组件)</span></span></span></p>
<ul class="ul-list" data-mark="*">
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">负责展示 <span><code>UI</code><span class="md-plain">,也就是组件如何渲染,具有很强的内聚性</span></span></span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">只关心得到数据后如何渲染</span></p>
</li>
</ul>
</li>
</ul>
<ul class="ul-list" data-mark="*">
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">容器组件(逻辑组件)</span></p>
<ul class="ul-list" data-mark="*">
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">负责应用逻辑处理,发送网络请求,处理返回数据,将处理过的数据传递给展示组件</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">也提供修改数据源的方法,通过展示组件的props传递给展示组件</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">当展示组件的状态变更引起源数据变化时,展示组件通过调用容器组件提供的方法同步这些变化</span></p>
</li>
</ul>
</li>
</ul>
<h2 class="md-end-block md-heading"><span class="md-plain">react-router的原理</span></h2>
<ul class="ul-list" data-mark="*">
<li class="md-list-item">
<p class="md-end-block md-p"><span><code>BrowserRouter</code><span class="md-plain"> 或 <span><code>HashRouter</code><span class="md-plain"> 用来渲染Router所代表的组件</span></span></span></span></p>
<ul class="ul-list" data-mark="*">
<li class="md-list-item">
<p class="md-end-block md-p"><span><code>BrowserRouter</code><span class="md-plain"> --浏览器路由(属于后端路由) 会有一个#,通过这个# HTML 5 History进行前端跳转他的感觉像锚点</span></span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span><code>HasRouter</code><span class="md-plain"> --前端has路由(属于前端路由)很简洁没有#,但是需要 server 端支持</span></span></p>
</li>
</ul>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span><code>Route</code><span class="md-plain"> 用来匹配组件路径并且筛选需要渲染的组件</span></span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span><code>Switch</code><span class="md-plain"> 用来筛选需要渲染的唯一组件</span></span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span><code>Link</code><span class="md-plain"> 直接渲染某个页面组件</span></span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span><code>Redirect</code><span class="md-plain"> 类似于Link,在没有Route匹配成功时触发</span></span></p>
</li>
</ul>
<h2 class="md-end-block md-heading"><span class="md-plain">何为高阶组件(HOC)?</span></h2>
<blockquote>
<p class="md-end-block md-p"><span class="md-plain">高阶组件 其实就是一个函数而已,只不过参数是一个组件而已,返回了一个新的组件</span></p>
<p class="md-end-block md-p"><span class="md-plain">复用组件的业务逻辑 <span><code>react-redux</code><span class="md-plain"> <span><code>connect</code><span class="md-plain"> 其实就是一个高阶组件</span></span></span></span></span></p>
<p class="md-end-block md-p"><span class="md-plain">HOC 是纯函数,没有副作用 ------纯函数:输入确定,输出就一定确定</span></p>
</blockquote>
<h2 class="md-end-block md-heading"><span class="md-plain">了解 <span><code>redux</code><span class="md-plain"> 么,说一下 <span><code>redux</code></span></span></span></span></h2>
<ul class="ul-list" data-mark="*">
<li class="md-list-item">
<p class="md-end-block md-p"><span><code>redux</code><span class="md-plain"> 是一个应用数据流框架,主要是解决了组件间状态共享的问题,原理是集中式管理</span></span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">主要有三个核心方法,<span><code>action</code><span class="md-plain">,<span><code>store</code><span class="md-plain">,<span><code>reducer</code></span></span></span></span></span></span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">工作流程是 view 调用 store 的 dispatch 接收 action 传入 store,reducer 进行 state 操作,view 通过 store 提供的 <span><code>getState</code><span class="md-plain"> 获取最新的数据</span></span></span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">新增 state,对状态的管理更加明确,通过 redux,流程更加规范了,减少手动编码量,提高了编码效率,同时缺点时当数据更新时有时候组件不需要,但是也要重新绘制,有些影响效率。一般情况下,我们在构建多交互,多数据流的复杂项目应用时才会使用它们</span></p>
</li>
</ul>
<h2 class="md-end-block md-heading"><span><code>redux</code><span class="md-plain">中间件的理解,以及用过哪些中间件</span></span></h2>
<ul class="ul-list" data-mark="*">
<li class="md-list-item">
<p class="md-end-block md-p"><span><code>redux-thunk</code><span class="md-plain">:处理异步操作</span></span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span><code>redux-saga</code><span class="md-plain">:处理异步操作</span></span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span><code>redux-promise</code><span class="md-plain">:处理异步操作,<span><code>actionCreator</code><span class="md-plain"> 的返回值是promise</span></span></span></span></p>
</li>
</ul>
<h2 class="md-end-block md-heading"><span><code>Redux</code><span class="md-plain"> 遵循的三个原则是什么?</span></span></h2>
<ul class="ul-list" data-mark="*">
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">单一事实来源:整个应用程序的状态存储在单个存储中的对象/状态树中</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">状态是只读的:更改状态的惟一方法是触发一个动作</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">使用纯函数来修改state:为了描述 action 如何改变 state tree ,你需要编写reducers</span></p>
</li>
</ul>
<h2 class="md-end-block md-heading"><span><code>React</code><span class="md-plain"> , <span><code>redux</code><span class="md-plain"> 可以运行在服务端吗?有什么优势</span></span></span></span></h2>
<ol class="ol-list">
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">利于 <span><code>SEO</code></span></span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">提高首屏渲染速度</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">同构直出,使用同一份 <span><code>JS</code><span class="md-plain"> 代码实现,便于开发和维护</span></span></span></p>
</li>
</ol>
<h2 class="md-end-block md-heading"><span class="md-plain">react性能优化方案</span></h2>
<ul class="ul-list" data-mark="*">
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">重写<span><code>shouldComponentUpdate</code><span class="md-plain">来避免不必要的 <span><code>dom</code><span class="md-plain"> 操作</span></span></span></span></span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">使用 <span><code>production</code><span class="md-plain"> 版本的<span><code>react.js</code></span></span></span></span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">使用<span><code>key</code><span class="md-plain">来帮助<span><code>React</code><span class="md-plain">识别列表中所有子组件的最小变化</span></span></span></span></span></p>
</li>
</ul>
<h2 class="md-end-block md-heading"><span class="md-plain">说说你用react有什么坑点?</span></h2>
<ul class="ul-list" data-mark="*">
<li class="md-list-item">
<p class="md-end-block md-p"><span><code>JSX</code><span class="md-plain"> 做表达式判断时候,需要强转为boolean类型</span></span></p>
</li>
</ul>
<ul class="ul-list" data-mark="*">
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">尽量不要在 <span><code>componentWillReviceProps</code><span class="md-plain"> 里使用 <span><code>setState</code><span class="md-plain">,如果一定要使用,那么需要判断结束条件,不然会出现无限重渲染,导致页面崩溃</span></span></span></span></span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">遍历子节点的时候,不要用 index 作为组件的 key 进行传入</span></p>
</li>
</ul>
<h2 class="md-end-block md-heading"><span class="md-plain">react 的虚拟 <span><code>dom</code><span class="md-plain"> 是怎么实现的?</span></span></span></h2>
<blockquote>
<p class="md-end-block md-p"><span class="md-plain">首先说说为什么要使用<span><code>Virturl DOM</code><span class="md-plain">,因为操作真实<span><code>DOM</code><span class="md-plain">的耗费的性能代价太高,所以<span><code>react</code><span class="md-plain">内部使用<span><code>js</code><span class="md-plain">实现了一套 <span><code>dom</code><span class="md-plain"> 结构,在每次操作在和真实 <span><code>dom</code><span class="md-plain"> 之前,使用实现好的 <span><code>diff</code><span class="md-plain"> 算法,对虚拟 <span><code>dom</code><span class="md-plain"> 进行比较,递归找出有变化的 <span><code>dom</code><span class="md-plain"> 节点,然后对其进行更新操作。为了实现虚拟<span><code>DOM</code><span class="md-plain">,我们需要把每一种节点类型抽象成对象,每一种节点类型有自己的属性,也就是prop,每次进行<span><code>diff</code><span class="md-plain">的时候,<span><code>react</code><span class="md-plain">会先比较该节点类型,假如节点类型不一样,那么<span><code>react</code><span class="md-plain">会直接删除该节点,然后直接创建新的节点插入到其中,假如节点类型一样,那么会比较<span><code>prop</code><span class="md-plain">是否有更新,假如有<span><code>prop</code><span class="md-plain">不一样,那么<span><code>react</code><span class="md-plain">会判定该节点有更新,那么重渲染该节点,然后在对其子节点进行比较,一层一层往下,直到没有子节点</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></p>
</blockquote>
<h2 class="md-end-block md-heading"><span><code>react</code><span class="md-plain"> <span><code>diff</code><span class="md-plain"> 原理</span></span></span></span></h2>
<ul class="ul-list" data-mark="*">
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">把树形结构按照层级分解,只比较同级元素</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">给列表结构的每个单元添加唯一的 key 属性,方便比较</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">React 只会匹配相同 class 的 component(这里面的 class 指的是组件的名字)</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">合并操作,调用 component 的 <span><code>setState</code><span class="md-plain"> 方法的时候, React 将其标记为 dirty.到每一个事件循环结束, React 检查所有标记 dirty 的 component 重新绘制</span></span></span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">选择性子树渲染。开发人员可以重写 <span><code>shouldComponentUpdate</code><span class="md-plain"> 提高 <span><code>diff</code><span class="md-plain"> 的性能</span></span></span></span></span></p>
</li>
</ul>
<h2 class="md-end-block md-heading"><span class="md-plain">react 的渲染过程中,兄弟节点之间是怎么处理的?也就是key值不一样的时候</span></h2>
<blockquote>
<p class="md-end-block md-p"><span class="md-plain">我们必须给每一个元素添加 <span><code>key</code><span class="md-plain"> 属性,大概的作用就是给每一个元素添加一个身份标识,方便react进行识别,在重渲染过程中,如果key一样,若组件属性有所变化,则<span><code>react</code><span class="md-plain">只更新组件对应的属性;没有变化则不更新,如果key不一样,则react先销毁该组件,然后重新创建该组件</span></span></span></span></span></p>
</blockquote>
<h2 class="md-end-block md-heading"><span class="md-plain">react组件之间如何通信?</span></h2>
<blockquote>
<p class="md-end-block md-p"><span class="md-plain">父子:父传子:props; 子传父:子调用父组件中的函数并传参;<span class="md-softbreak"> <span class="md-plain">兄弟:利用 <span><code>redux</code><span class="md-plain"> 实现。<span class="md-softbreak"> <span class="md-plain">所有关系都通用的方法:利用<span><code>PubSub.js</code><span class="md-plain">订阅</span></span></span></span></span></span></span></span></span></p>
</blockquote>
<h2 class="md-end-block md-heading"><span><code>setState</code><span class="md-plain"> 为什么是异步的</span></span></h2>
<ol class="ol-list">
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">保证内部的一致性 (因为props是要等到父组件渲染过后才能拿到,也就是不能同步更新,state出于统一性设成异步更新)</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">性能优化 (举例说你正在一个聊天窗口输入,如果来了一条新消息又要render,那就会阻塞你的当前操作,导致延迟什么的)</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">支持state在幕后渲染(异步可以使state在幕后更新,而不影响你当前旧的页面的交互,提升用户体验)</span></p>
</li>
</ol>
<h2 class="md-end-block md-heading"><span class="md-plain">react的优势以及特点</span></h2>
<ul class="ul-list" data-mark="*">
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">优势</span></p>
<ul class="ul-list" data-mark="*">
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">实现对虚拟DOM的操作,使得它速度快,提高了Web性能</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">组件化,模块化。react里每一个模块都是一个组件,组件化开发,可维护性高</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">单向数据流,比较有序,有便于管理,它随着React视图库的开发而被 <span><code>Facebook</code><span class="md-plain"> 概念化</span></span></span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">跨浏览器兼容:虚拟DOM帮助我们解决了跨浏览器问题,它为我们提供了标准化的 <span><code>API</code><span class="md-plain">,甚至在 <span><code>IE8</code><span class="md-plain"> 中都是没问题的</span></span></span></span></span></p>
</li>
</ul>
</li>
</ul>
<ul class="ul-list" data-mark="*">
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">不足</span></p>
<ul class="ul-list" data-mark="*">
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">react中只是 <span><code>MVC</code><span class="md-plain"> 模式的View部分,要依赖引入很多其他模块开发</span></span></span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">当父组件进行重新渲染操作时,即使子组件的props或state没有做出任何改变,也会同样进行重新渲染</span></p>
</li>
</ul>
</li>
</ul>
<ul class="ul-list" data-mark="*">
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">特点</span></p>
<ul class="ul-list" data-mark="*">
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">声明式设计:React采用声明范式,可以轻松描述应用</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">高效:React通过对DOM的模拟,最大限度地减少与DOM的交互</span></p>
</li>
<li class="md-list-item md-focus-container">
<p class="md-end-block md-p md-focus"><span class="md-plain">灵活:React可以与已知的库或框架很好地配合</span></p>
</li>
</ul>
</li>
</ul>
</div>
<div id="MySignature" role="contentinfo">
一辈子说长不长,说短不短,努力做好两件事:第一件事爱生活,爱身边的人,爱自己;第二件事是好好学习,好好工作,实现自己的人生价值观,而不仅仅是为了赚钱<br><br>
来源:https://www.cnblogs.com/dcyd/p/12989422.html
頁:
[1]