componentWillReceiveProps调用机会

  • 曾经被废除掉
  • 当props扭转的时候才调用,子组件第二次接管到props的时候

在调用setState 之后产生了什么

  • 状态合并,触发和谐:

    setState函数之后,会将传入的参数对象与以后的状态合并,而后登程调用过程

  • 依据新的状态构建虚构dom树

    通过和谐过程,react会高效的依据新的状态构建虚构DOM树,筹备渲染整个UI页面

  • 计算新老树节点差别,最小化渲染

    得倒新的虚构DOM树后,会计算出新老树的节点差别,会依据差别对界面进行最小化渲染

  • 按需更新

    在差别话计算中,react能够绝对精确的晓得哪些地位产生了扭转以及该如何扭转,这保障按需更新,而不是发表从新渲染

概述一下 React中的事件处理逻辑。

为了解决跨浏览器兼容性问题, React会将浏览器原生事件( Browser Native Event)封装为合成事件( Synthetic Event)并传入设置的事件处理程序中。
这里的合成事件提供了与原生事件雷同的接口,不过它们屏蔽了底层浏览器的细节差别,保障了行为的一致性。另外, React并没有间接将事件附着到子元素上,而是以繁多事件监听器的形式将所有的事件发送到顶层进行解决(基于事件委托原理)。
这样 React在更新DOM时就不须要思考如何解决附着在DOM上的事件监听器,最终达到优化性能的目标。

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

简略地说,在 React中元素(虛拟DOM)形容了你在屏幕上看到的DOM元素。
换个说法就是,在 React中元素是页面中DOM元素的对象示意形式。在 React中组件是一个函数或一个类,它能够承受输出并返回一个元素。
留神:工作中,为了进步开发效率,通常应用JSX语法示意 React元素(虚构DOM)。在编译的时候,把它转化成一个 React. createElement调用办法。

参考:前端react面试题具体解答

在 ReactNative中,如何解决 adb devices找不到连贯设施的问题?

在应用 Genymotion时,首先须要在SDK的 platform-tools中退出环境变量,而后在 Genymotion中单击 Setting,抉择ADB选项卡,单击 Use custom Android SDK tools,浏览本地SDK的地位,单击OK按钮就能够了。启动虛拟机后,在cmd中输出 adb devices能够查看设施。

说说 React组件开发中对于作用域的常见问题。

在 EMAScript5语法标准中,对于作用域的常见问题如下。
(1)在map等办法的回调函数中,要绑定作用域this(通过bind办法)。
(2)父组件传递给子组件办法的作用域是父组件实例化对象,无奈扭转。
(3)组件事件回调函数办法的作用域是组件实例化对象(绑定父组件提供的办法就是父组件实例化对象),无奈扭转。
在 EMAScript6语法标准中,对于作用域的常见问题如下。
(1)当应用箭头函数作为map等办法的回调函数时,箭头函数的作用域是以后组件的实例化对象(即箭头函数的作用域是定义时的作用域),毋庸绑定作用域。
(2)事件回调函数要绑定组件作用域。
(3)父组件传递办法要绑定父组件作用域。
总之,在 EMAScript6语法标准中,组件办法的作用域是能够扭转的。

生命周期调用办法的程序是什么?

React生命周期分为三大周期,11个阶段,生命周期办法调用程序别离如下。
(1)在创立期的五大阶段,调用办法的程序如下。

  • getDetaultProps:定义默认属性数据。
  • getInitialState:初始化默认状态数据。
  • component WillMount:组件行将被构建。
  • render:渲染组件。
  • componentDidMount:组件构建实现

(2)在存在期的五大阶段,调用办法的程序如下。

  • componentWillReceiveProps:组件行将接管新的属性数据。
  • shouldComponentUpdate:判断组件是否应该更新。
  • componnent WillUpdate:组件行将更新。
  • render:渲染组件。
  • componentDidUpdate:组件更新实现。

(3)在销毁期的一个阶段,调用办法 componentWillUnmount,示意组件行将被销毀。

React 中 refs 的作用是什么

  • RefsReact 提供给咱们的平安拜访 DOM元素或者某个组件实例的句柄
  • 能够为元素增加ref属性而后在回调函数中承受该元素在 DOM 树中的句柄,该值会作为回调函数的第一个参数返回

React- Router有几种模式?

有以下几种模式。
HashRouter,通过散列实现,路由要带#。
BrowerRouter,利用HTML5中 history API实现,须要服务器端反对,兼容性不是很好。

在 React 中如何处理事件

为了解决跨浏览器的兼容性问题,SyntheticEvent 实例将被传递给你的事件处理函数,SyntheticEvent是 React 跨浏览器的浏览器原生事件包装器,它还领有和浏览器原生事件雷同的接口,包含 stopPropagation()preventDefault()
比拟乏味的是,React 实际上并不将事件附加到子节点自身。React 应用单个事件侦听器侦听顶层的所有事件。这对性能有益处,也意味着 React 在更新 DOM 时不须要跟踪事件监听器。

受控组件和非受控组件区别是啥?

  • 受控组件是 React 管制中的组件,并且是表单数据实在的惟一起源。
  • 非受控组件是由 DOM 解决表单数据的中央,而不是在 React 组件中。
    只管非受控组件通常更易于实现,因为只需应用refs即可从 DOM 中获取值,但通常倡议优先选择受管制的组件,而不是非受管制的组件。
    这样做的次要起因是受控组件反对即时字段验证,容许有条件地禁用/启用按钮,强制输出格局。

redux有什么毛病

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

在应用 React Router时,如何获取以后页面的路由或浏览器中地址栏中的地址?

在以后组件的 props中,蕴含 location属性对象,蕴含以后页面路由地址信息,在 match中存储以后路由的参数等数据信息。能够间接通过 this .props应用它们。

在结构函数调用 super 并将 props 作为参数传入的作用是啥?

在调用 super() 办法之前,子类构造函数无奈应用this援用,ES6 子类也是如此。将 props 参数传递给 super() 调用的次要起因是在子构造函数中可能通过this.props来获取传入的 props
传递 props

class MyComponent extends React.Component {  constructor(props) {    super(props);    console.log(this.props); // { name: 'sudheer',age: 30 }  }}

没传递 props

class MyComponent extends React.Component {  constructor(props) {    super();    console.log(this.props); // undefined    // 然而 Props 参数依然可用    console.log(props); // Prints { name: 'sudheer',age: 30 }  }  render() {    // 构造函数内部不受影响    console.log(this.props); // { name: 'sudheer',age: 30 }  }}

下面示例揭示了一点。props 的行为只有在构造函数中是不同的,在构造函数之外也是一样的。

useEffect(fn, []) 和 componentDidMount 有什么差别

useEffect 会捕捉 props 和 state。所以即使在回调函数里,你拿到的还是初始的 props 和 state。如果想得到“最新”的值,能够应用 ref。

React有哪些优化性能的伎俩

类组件中的优化伎俩

  • 应用纯组件 PureComponent 作为基类。
  • 应用 React.memo 高阶函数包装组件。
  • 应用 shouldComponentUpdate 生命周期函数来自定义渲染逻辑。

办法组件中的优化伎俩

  • 应用 useMemo
  • 应用 useCallBack

其余形式

  • 在列表须要频繁变动时,应用惟一 id 作为 key,而不是数组下标。
  • 必要时通过扭转 CSS 款式暗藏显示组件,而不是通过条件判断显示暗藏组件。
  • 应用 Suspense 和 lazy 进行懒加载,例如:
import React, { lazy, Suspense } from "react";export default class CallingLazyComponents extends React.Component {  render() {    var ComponentToLazyLoad = null;    if (this.props.name == "Mayank") {      ComponentToLazyLoad = lazy(() => import("./mayankComponent"));    } else if (this.props.name == "Anshul") {      ComponentToLazyLoad = lazy(() => import("./anshulComponent"));    }    return (      <div>        <h1>This is the Base User: {this.state.name}</h1>        <Suspense fallback={<div>Loading...</div>}>          <ComponentToLazyLoad />        </Suspense>      </div>    )  }}

新版生命周期

在新版本中,React 官网对生命周期有了新的 变动倡议:
  • 应用getDerivedStateFromProps替换componentWillMount;
  • 应用getSnapshotBeforeUpdate替换componentWillUpdate;
  • 防止应用componentWillReceiveProps
其实该变动的起因,正是因为上述提到的 Fiber。首先,从下面咱们晓得 React 能够分成 reconciliationcommit两个阶段,对应的生命周期如下:

reconciliation

  • componentWillMount
  • componentWillReceiveProps
  • shouldComponentUpdate
  • componentWillUpdate

commit

  • componentDidMount
  • componentDidUpdate
  • componentWillUnmount
Fiber 中,reconciliation 阶段进行了工作宰割,波及到 暂停 和 重启,因而可能会导致 reconciliation 中的生命周期函数在一次更新渲染循环中被 屡次调用 的状况,产生一些意外谬误

新版的倡议生命周期如下:

class Component extends React.Component {  // 替换 `componentWillReceiveProps` ,  // 初始化和 update 时被调用  // 动态函数,无奈应用 this  static getDerivedStateFromProps(nextProps, prevState) {}  // 判断是否须要更新组件  // 能够用于组件性能优化  shouldComponentUpdate(nextProps, nextState) {}  // 组件被挂载后触发  componentDidMount() {}  // 替换 componentWillUpdate  // 能够在更新之前获取最新 dom 数据  getSnapshotBeforeUpdate() {}  // 组件更新后调用  componentDidUpdate() {}  // 组件行将销毁  componentWillUnmount() {}  // 组件已销毁  componentDidUnMount() {}}

应用倡议:

  • constructor初始化 state
  • componentDidMount中进行事件监听,并在componentWillUnmount中解绑事件;
  • componentDidMount中进行数据的申请,而不是在componentWillMount
  • 须要依据 props 更新 state 时,应用getDerivedStateFromProps(nextProps, prevState)

    • 旧 props 须要本人存储,以便比拟;
public static getDerivedStateFromProps(nextProps, prevState) {    // 当新 props 中的 data 发生变化时,同步更新到 state 上    if (nextProps.data !== prevState.data) {        return {            data: nextProps.data        }    } else {        return null1    }}
能够在componentDidUpdate监听 props 或者 state 的变动,例如:
componentDidUpdate(prevProps) {    // 当 id 发生变化时,从新获取数据    if (this.props.id !== prevProps.id) {        this.fetchData(this.props.id);    }}
  • 在componentDidUpdate应用setState时,必须加条件,否则将进入死循环;
  • getSnapshotBeforeUpdate(prevProps, prevState)能够在更新之前获取最新的渲染数据,它的调用是在 render 之后, update 之前;
  • shouldComponentUpdate: 默认每次调用setState,肯定会最终走到 diff 阶段,但能够通过shouldComponentUpdate的生命钩子返回false来间接阻止前面的逻辑执行,通常是用于做条件渲染,优化渲染的性能。

类组件和函数组件之间的区别是啥?

  • 类组件能够应用其余个性,如状态 state 和生命周期钩子。
  • 当组件只是接管 props 渲染到页面时,就是无状态组件,就属于函数组件,也被称为哑组件或展现组件。
    函数组件和类组件当然是有区别的,而且函数组件的性能比类组件的性能要高,因为类组件应用的时候要实例化,而函数组件间接执行函数取返回后果即可。为了进步性能,尽量应用函数组件。

    区别函数组件类组件
    是否有 this没有
    是否有生命周期没有
    是否有状态 state没有

依据上面定义的代码,能够找出存在的两个问题吗 ?

请看上面的代码:

答案:
1.在构造函数没有将 props 传递给 super,它应该包含以下行

constructor(props) {super(props);// ...}

2.事件监听器(通过addEventListener()调配时)的作用域不正确,因为 ES6 不提供主动绑定。因而,开发人员能够在构造函数中重新分配clickHandler来蕴含正确的绑定:

constructor(props) {super(props);this.clickHandler = this.clickHandler.bind(this);// ...}

redux中间件

中间件提供第三方插件的模式,自定义拦挡 action -> reducer 的过程。变为 action -> middlewares -> reducer。这种机制能够让咱们扭转数据流,实现如异步actionaction 过滤,日志输入,异样报告等性能
  • redux-logger:提供日志输入
  • redux-thunk:解决异步操作
  • redux-promise:解决异步操作,actionCreator的返回值是promise