作者:小胡https://github.com/nanhupatar/FEGuide/blob/master/框架/react.md

React 中 keys 的作用是什么?

Keys 是 React 用于追踪哪些列表中元素被修改、被添加或者被移除的辅助标识。

render () {return (<ul>{this.state.todoItems.map(({item, key}) => {return <li key={key}>{item}</li>})}</ul>)
}

在开发过程中,我们需要保证某个元素的 key 在其同级元素中具有唯一性。在 React Diff 算法中 React 会借助元素的 Key 值来判断该元素是新近创建的还是被移动而来的元素,从而减少不必要的元素重渲染。此外,React 还需要借助 Key 值来判断元素与本地状态的关联关系,因此我们绝不可忽视转换函数中 Key 的重要性。

调用 setState 之后发生了什么?

在代码中调用 setState 函数之后,React 会将传入的参数对象与组件当前的状态合并,然后触发所谓的调和过程(Reconciliation)。经过调和过程,React 会以相对高效的方式根据新的状态构建 React 元素树并且着手重新渲染整个 UI 界面。在 React 得到元素树之后,React 会自动计算出新的树与老树的节点差异,然后根据差异对界面进行最小化重渲染。在差异计算算法中,React 能够相对精确地知道哪些位置发生了改变以及应该如何改变,这就保证了按需更新,而不是全部重新渲染。

react 生命周期函数

  • 初始化阶段:
  • getDefaultProps:获取实例的默认属性
  • getInitialState:获取每个实例的初始化状态
  • componentWillMount:组件即将被装载、渲染到页面上
  • render:组件在这里生成虚拟的 DOM 节点
  • componentDidMount:组件真正在被装载之后
  • 运行中状态:
  • componentWillReceiveProps:组件将要接收到属性的时候调用
  • shouldComponentUpdate:组件接受到新属性或者新状态的时候(可以返回 false,接收数据后不更新,阻止 render 调用,后面的函数不会被继续执行了)
  • componentWillUpdate:组件即将更新不能修改属性和状态
  • render:组件重新描绘
  • componentDidUpdate:组件已经更新
  • 销毁阶段:
  • componentWillUnmount:组件即将销毁

shouldComponentUpdate 是做什么的,(react 性能优化是哪个周期函数?)

shouldComponentUpdate 这个方法用来判断是否需要调用 render 方法重新描绘 dom。因为 dom 的描绘非常消耗性能,如果我们能在 shouldComponentUpdate 方法中能够写出更优化的 dom diff 算法,可以极大的提高性能。

参考react 性能优化-sf

为什么虚拟 dom 会提高性能?(必考)

虚拟 dom 相当于在 js 和真实 dom 中间加了一个缓存,利用 dom diff 算法避免了没有必要的 dom 操作,从而提高性能。

用 JavaScript 对象结构表示 DOM 树的结构;然后用这个树构建一个真正的 DOM 树,插到文档当中当状态变更的时候,重新构造一棵新的对象树。然后用新的树和旧的树进行比较,记录两棵树差异把 2 所记录的差异应用到步骤 1 所构建的真正的 DOM 树上,视图就更新了。

参考 如何理解虚拟 DOM?-zhihu

react diff 原理(常考,大厂必考)

  • 把树形结构按照层级分解,只比较同级元素。
  • 给列表结构的每个单元添加唯一的 key 属性,方便比较。
  • React 只会匹配相同 class 的 component(这里面的 class 指的是组件的名字)
  • 合并操作,调用 component 的 setState 方法的时候, React 将其标记为 dirty.到每一个事件循环结束, React 检查所有标记 dirty 的 component 重新绘制.
  • 选择性子树渲染。开发人员可以重写 shouldComponentUpdate 提高 diff 的性能。

参考:React 的 diff 算法

React 中 refs 的作用是什么?

Refs 是 React 提供给我们的安全访问 DOM 元素或者某个组件实例的句柄。我们可以为元素添加 ref 属性然后在回调函数中接受该元素在 DOM 树中的句柄,该值会作为回调函数的第一个参数返回:

class CustomForm extends Component {handleSubmit = () => {console.log("Input Value: ", this.input.value)}render () {return (<form onSubmit={this.handleSubmit}><inputtype='text'ref={(input) => this.input = input} /><button type='submit'>Submit</button></form>)}
}

上述代码中的 input 域包含了一个 ref 属性,该属性声明的回调函数会接收 input 对应的 DOM 元素,我们将其绑定到 this 指针以便在其他的类函数中使用。另外值得一提的是,refs 并不是类组件的专属,函数式组件同样能够利用闭包暂存其值:

function CustomForm ({handleSubmit}) {let inputElementreturn (<form onSubmit={() => handleSubmit(inputElement.value)}><inputtype='text'ref={(input) => inputElement = input} /><button type='submit'>Submit</button></form>)
}

如果你创建了类似于下面的 Twitter 元素,那么它相关的类定义是啥样子的?

<Twitter username='tylermcginnis33'>{(user) => user === null? <Loading />: <Badge info={user} />}
</Twitter>import React, { Component, PropTypes } from 'react'
import fetchUser from 'twitter'
// fetchUser take in a username returns a promise
// which will resolve with that username's data.
class Twitter extends Component {// finish this
}

如果你还不熟悉回调渲染模式(Render Callback Pattern),这个代码可能看起来有点怪。这种模式中,组件会接收某个函数作为其子组件,然后在渲染函数中以 props.children 进行调用:

import React, { Component, PropTypes } from 'react'
import fetchUser from 'twitter'
class Twitter extends Component {state = {user: null,}static propTypes = {username: PropTypes.string.isRequired,}componentDidMount () {fetchUser(this.props.username).then((user) => this.setState({user}))}render () {return this.props.children(this.state.user)}
}

这种模式的优势在于将父组件与子组件解耦和,父组件可以直接访问子组件的内部状态而不需要再通过 Props 传递,这样父组件能够更为方便地控制子组件展示的 UI 界面。譬如产品经理让我们将原本展示的 Badge 替换为 Profile,我们可以轻易地修改下回调函数即可:

<Twitter username='tylermcginnis33'>{(user) => user === null? <Loading />: <Profile info={user} />}
</Twitter>

展示组件(Presentational component)和容器组件(Container component)之间有何不同

  • 展示组件关心组件看起来是什么。展示专门通过 props 接受数据和回调,并且几乎不会有自身的状态,但当展示组件拥有自身的状态时,通常也只关心 UI 状态而不是数据的状态。
  • 容器组件则更关心组件是如何运作的。容器组件会为展示组件或者其它容器组件提供数据和行为(behavior),它们会调用 Flux actions,并将其作为回调提供给展示组件。容器组件经常是有状态的,因为它们是(其它组件的)数据源。

类组件(Class component)和函数式组件(Functional component)之间有何不同

  • 类组件不仅允许你使用更多额外的功能,如组件自身的状态和生命周期钩子,也能使组件直接访问 store 并维持状态
  • 当组件仅是接收 props,并将组件自身渲染到页面时,该组件就是一个 '无状态组件(stateless component)',可以使用一个纯函数来创建这样的组件。这种组件也被称为哑组件(dumb components)或展示组件

(组件的)状态(state)和属性(props)之间有何不同

  • State 是一种数据结构,用于组件挂载时所需数据的默认值。State 可能会随着时间的推移而发生突变,但多数时候是作为用户事件行为的结果。
  • Props(properties 的简写)则是组件的配置。props 由父组件传递给子组件,并且就子组件而言,props 是不可变的(immutable)。组件不能改变自身的 props,但是可以把其子组件的 props 放在一起(统一管理)。Props 也不仅仅是数据--回调函数也可以通过 props 传递。

何为受控组件(controlled component)

在 HTML 中,类似 <input>, <textarea><select> 这样的表单元素会维护自身的状态,并基于用户的输入来更新。当用户提交表单时,前面提到的元素的值将随表单一起被发送。但在 React 中会有些不同,包含表单元素的组件将会在 state 中追踪输入的值,并且每次调用回调函数时,如 onChange 会更新 state,重新渲染组件。一个输入表单元素,它的值通过 React 的这种方式来控制,这样的元素就被称为"受控元素"。

何为高阶组件(higher order component)

高阶组件是一个以组件为参数并返回一个新组件的函数。HOC 运行你重用代码、逻辑和引导抽象。最常见的可能是 Redux 的 connect 函数。除了简单分享工具库和简单的组合,HOC 最好的方式是共享 React 组件之间的行为。如果你发现你在不同的地方写了大量代码来做同一件事时,就应该考虑将代码重构为可重用的 HOC。

为什么建议传递给 setState 的参数是一个 callback 而不是一个对象

因为 this.props 和 this.state 的更新可能是异步的,不能依赖它们的值去计算下一个 state。

除了在构造函数中绑定 this,还有其它方式吗

你可以使用属性初始值设定项(property initializers)来正确绑定回调,create-react-app 也是默认支持的。在回调中你可以使用箭头函数,但问题是每次组件渲染时都会创建一个新的回调。

(在构造函数中)调用 super(props) 的目的是什么

在 super() 被调用之前,子类是不能使用 this 的,在 ES2015 中,子类必须在 constructor 中调用 super()。传递 props 给 super() 的原因则是便于(在子类中)能在 constructor 访问 this.props。

应该在 React 组件的何处发起 Ajax 请求

在 React 组件中,应该在 componentDidMount 中发起网络请求。这个方法会在组件第一次“挂载”(被添加到 DOM)时执行,在组件的生命周期中仅会执行一次。更重要的是,你不能保证在组件挂载之前 Ajax 请求已经完成,如果是这样,也就意味着你将尝试在一个未挂载的组件上调用 setState,这将不起作用。在 componentDidMount 中发起网络请求将保证这有一个组件可以更新了。

描述事件在 React 中的处理方式。

为了解决跨浏览器兼容性问题,您的 React 中的事件处理程序将传递 SyntheticEvent 的实例,它是 React 的浏览器本机事件的跨浏览器包装器。

这些 SyntheticEvent 与您习惯的原生事件具有相同的接口,除了它们在所有浏览器中都兼容。有趣的是,React 实际上并没有将事件附加到子节点本身。React 将使用单个事件监听器监听顶层的所有事件。这对于性能是有好处的,这也意味着在更新 DOM 时,React 不需要担心跟踪事件监听器。

createElement 和 cloneElement 有什么区别?

React.createElement():JSX 语法就是用 React.createElement()来构建 React 元素的。它接受三个参数,第一个参数可以是一个标签名。如 div、span,或者 React 组件。第二个参数为传入的属性。第三个以及之后的参数,皆作为组件的子组件。

React.createElement(type,[props],[...children]
)

React.cloneElement()与 React.createElement()相似,不同的是它传入的第一个参数是一个 React 元素,而不是标签名或组件。新添加的属性会并入原有的属性,传入到返回的新元素中,而就的子元素奖杯替换。

React.cloneElement(element,[props],[...children]
)

React 中有三种构建组件的方式

React.createClass()、ES6 class 和无状态函数。

react 组件的划分业务组件技术组件?

  • 根据组件的职责通常把组件分为 UI 组件和容器组件。
  • UI 组件负责 UI 的呈现,容器组件负责管理数据和逻辑。
  • 两者通过 React-Redux 提供 connect 方法联系起来。

简述 flux 思想

Flux 的最大特点,就是数据的"单向流动"。

  1. 用户访问 View
  2. View 发出用户的 Action
  3. Dispatcher 收到 Action,要求 Store 进行相应的更新
  4. Store 更新后,发出一个"change"事件
  5. View 收到"change"事件后,更新页面

React 项目用过什么脚手架(本题是开放性题目)

creat-react-app Yeoman 等

了解 redux 么,说一下 redux 把

  • redux 是一个应用数据流框架,主要是解决了组件间状态共享的问题,原理是集中式管理,主要有三个核心方法,action,store,reducer,工作流程是 view 调用 store 的 dispatch 接收 action 传入 store,reducer 进行 state 操作,view 通过 store 提供的 getState 获取最新的数据,flux 也是用来进行数据操作的,有四个组成部分 action,dispatch,view,store,工作流程是 view 发出一个 action,派发器接收 action,让 store 进行数据更新,更新完成以后 store 发出 change,view 接受 change 更新视图。Redux 和 Flux 很像。主要区别在于 Flux 有多个可以改变应用状态的 store,在 Flux 中 dispatcher 被用来传递数据到注册的回调事件,但是在 redux 中只能定义一个可更新状态的 store,redux 把 store 和 Dispatcher 合并,结构更加简单清晰
  • 新增 state,对状态的管理更加明确,通过 redux,流程更加规范了,减少手动编码量,提高了编码效率,同时缺点时当数据更新时有时候组件不需要,但是也要重新绘制,有些影响效率。一般情况下,我们在构建多交互,多数据流的复杂项目应用时才会使用它们

redux 有什么缺点

  • 一个组件所需要的数据,必须由父组件传过来,而不能像 flux 中直接从 store 取。
  • 当一个组件相关数据更新时,即使父组件不需要用到这个组件,父组件还是会重新 render,可能会有效率影响,或者需要写复杂的 shouldComponentUpdate 进行判断。

觉得本文对你有帮助?请分享给更多人

关注「前端树」加星标,提升前端技能

react map循环生成的button_常见 React 面试题相关推荐

  1. react map循环生成的button_关于Vue和React的一些对比及个人思考(中)

    vue和React都是目前最流行.生态最好的前端框架之一.框架本身没有优劣之分,只有适用之别,选择符合自身业务场景.团队基础的技术才是我们最主要的目的. 博主1年前用的是Vue框架,近半年转技术栈到R ...

  2. react map循环生成的button_【第1945期】彻底搞懂React源码调度原理(Concurrent模式)...

    前言 估计会懵逼.今日早读文章由成都@苏溪云投稿分享. 正文从这开始~~ 最早之前,React还没有用fiber重写,那个时候对React调度模块就有好奇.而现在的调度模块对于之前没研究过它的我来说更 ...

  3. React map循环

    map循环的使用: 我本来使用的是通过for循环去将数组下的各个值以及个别值下面的值都取出来作为一个数组使用: const result = providers.map((provider) => ...

  4. react map 循环 带条件输出

    在平时开发中经常会使用map 来遍历后台的数据,有时需要判断一些参数 <ul className="box-clounm">{warningData.poepleDat ...

  5. React学习:事件绑定、组件定义、for、map循环-学习笔记

    文章目录 React学习:事件绑定.组件定义.for.map循环-学习笔记 事件绑定 组件定义 (参数传递) for.map循环 React学习:事件绑定.组件定义.for.map循环-学习笔记 事件 ...

  6. react 面试题 高级_常见 React 面试题

    (给前端大全加星标,提升前端技能) 作者:小胡 https://github.com/nanhupatar/FEGuide/blob/master/框架/react.md React 中 keys 的 ...

  7. react 面试题 高级_常见react面试题汇总(适合中级前端)

    转载自<原文> React 中 keys 的作用是什么? Keys 是 React 用于追踪哪些列表中元素被修改.被添加或者被移除的辅助标识. render () {return( {th ...

  8. web前端教程分享:常见 React 面试题

    React 中 keys 的作用是什么? Keys 是 React 用于追踪哪些列表中元素被修改.被添加或者被移除的辅助标识. render () {   return (     <ul> ...

  9. react以及常见前端面试题(看这一篇就够了)持续更新中...

    目录 1.说说对React的理解?有哪些特性? 2.说说Real diff算法是怎么运作的? 3. 说说React生命周期有哪些不同的阶段?每个阶段对应的方法是? 4.说说你对React中虚拟dom的 ...

最新文章

  1. 基于Servlet+JDBC+Bootstrap+MySQL+AJAX权限管理系统项目实战教程
  2. python正则匹配_Python正则表达式初识(五)
  3. 过三关 Java冒泡排序选择排序插入排序小练习
  4. linux 下如何升级CMAKE?(安装指定版本cmake)(高版本cmake)(不删除之前的,可以用软连接)
  5. linux查找替换grep以及正则表达式
  6. android代码画出波浪球,Android绘制波浪曲线,效果很赞的。
  7. 你可能不需要 jQuery!使用原生 JavaScript 进行开发
  8. 二进制数据结构:JavaScript中的树和堆简介
  9. script标签中defer和async的区别
  10. 【卡塔兰数】LeetCode 96. Unique Binary Search Trees
  11. 专业模拟飞行11 linux,飞行模拟器 FlightGear 2019.1,Ubuntu PPA安装
  12. linux ping监控脚本,Shell长ping脚本监控网络状态
  13. 非因解读|Digital Spatial Profiler 新一代高维度空间组学技术
  14. 升腾 linux管理密码,升腾Linux终端使用指南
  15. kernel 选项详解(stlinux2.3)
  16. 【网站搭建】vps购买、域名注册、ngnix安装一条龙搭建静态网站
  17. javascript里将函数名字符串转为函数并执行
  18. 计算机启动u盘启动不了怎么办,电脑没有U盘启动项怎么办?主板不支持U盘启动怎么办?...
  19. 图dl:4受限玻尔兹曼机
  20. php setcookie 参数1,使用setcookie函数一步搞定设置和删除cookie

热门文章

  1. 大火C4D元素,电商大促海报背景BANNER素材
  2. 【设计素材】表格数据形平面海报素材
  3. 流程图和布局套件模板
  4. programfilesx86可以移动吗_配置全套的移动洗砂机多少钱?时产200吨可以处理吗?...
  5. Linux内存管理:MMU那些事儿
  6. Linux虚拟文件系统VFS的相关数据结构和操作
  7. 大工13秋 c/c++语言程序设计 在线作业3,大工19秋《JavaScript基础教程与应用》在线作业3【满分答案】...
  8. python开启新代码块_20课零基础快速学python完成简单邮件完整邮件代码块
  9. spss方差分析_交叉设计及SPSS多因素方差分析
  10. Django视图层:视图函数、视图类