关于React的几个简单问题

1.什么是虚拟DOM

虚拟DOM(VDOM)是真实DOM的内存表示。将整个UI结构保持在内存中并和真正的DOM结构保持同步。在调用渲染函数和元素展示在屏幕上之间有一个处理过程,这个过程叫作reconciliationjavascript

2.虚拟DOM是如何工做的

虚拟DOM的工做过程分为三个阶段:
1)每当任意一个底层数据发生更改时,整个UI都将在虚拟DOM表示中从新渲染
2)对比固然的虚拟DOM和上一份虚拟DOM的不一样之处
3)对比结束以后,真是DOM就会根据对比结果从新渲染变化的DOM节点java

3.影子(Shadow)DOM和虚拟DOM有什么区别

Shadow DOM 在网络平台中引入做用域样式。 无需工具或命名约定,您便可使用原生 JavaScript 捆绑 CSS 和标记、隐藏实现详情以及编写独立的组件。
Shadow DOM 与普通 DOM 相同,但有两点区别:1) 建立/使用的方式;2) 与页面其余部分有关的行为方式。 一般,您建立 DOM 节点并将其附加至其余元素做为子项。 借助于 shadow DOM,您能够建立做用域 DOM 树,该 DOM 树附加至该元素上,但与其自身真正的子项分离开来。这一做用域子树称为影子树。被附着的元素称为影子宿主。 您在影子中添加的任何项均将成为宿主元素的本地项,包括 <style>。 这就是 shadow DOM 实现 CSS 样式做用域的方式。
因此,Shadow DOM是一种浏览器技术,主要用于在web组件中肯定变量和CSS的范围。虚拟DOM是一个由JavaScript中的库在浏览器api之上实现的概念。react

4.类组件和方法组件的区别

  • 类组件:它容许您使用其余特性,如本地状态和生命周期钩子。此外,还可使组件直接访问store,从而保持状态。
  • 若是你的组件只接收props属性并将它处理以后渲染在页面上,那么这就是个无状态组件,可使用纯函数来实现。

5.refs在React中用于什么

你可使用refs直接访问一个元素节点或者组件实例。要使用这个属性,您须要向组件添加一个ref属性,该属性的值是一个回调函数,它将接收底层DOM元素或组件实例做为其第一个参数。webpack

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

能够看到,在input标签上有一个ref属性,给它赋值了一个函数方法。这个方法接收了input的真实DOM元素,接着咱们将在handleSubmit方法里面访问它。
一般认为只能在类组件中使用refs,但你也但是利用闭包在方法组件中使用。web

function CustomForm ({handleSubmit}{
  let inputElement
  return (
    <form onSubmit={() => handleSubmit(inputElement.value)}>
      <input
        type='text'
        ref={(input) =>
 inputElement = input} />
      <button type='submit'>Submit</button>
    </form>
  )
}
复制代码

还有另一种使用refs的方法。你能够用React.createRef()方法建立refs并经过ref属性绑定到元素上。为了在整个组件中使用ref,只需将ref分配给构造函数中的实例属性。编程

class MyComponent extends React.Component {
  constructor(props) {
    super(props)
    this.myRef = React.createRef()
  }
  render() {
    return <div ref={this.myRef} />
  }
}
复制代码

6.什么是forward refs

Ref forwarding 是一个性质,它容许组件接收一个ref属性,并将这个属性传递给子组件。api

const ButtonElement = React.forwardRef((props, ref) => (
  <button ref={ref} className="CustomButton">
    {props.children}
  </button>

));

// Create ref to the DOM button:
const ref = React.createRef();
<ButtonElement ref={ref}>{'Forward Ref'}</ButtonElement>
复制代码

7.描述一下React中事件是怎么处理的

为了解决跨浏览器兼容性问题,React中的事件处理中将传递SyntheticEvent的实例,SyntheticEvent是React中包装了各类浏览器原生属性的跨浏览器包装器。它暴露出统一的事件接口,保证在不一样浏览器上都可以正常运行。
稍微有趣的是,React实际上并无将事件附加到子节点自己。而是使用事件代理的方式,React使用一个事件侦听器在顶层侦听全部事件。这有助于提升性能,也意味着React在更新DOM时没必要担忧跟踪事件侦听器被移除。数组

8.state和props之间有什么不一样

props和state都是纯JavaScript对象。虽然它们都包含影响渲染输出的信息,但它们在组件方面的功能不一样。好比:浏览器

  • props将数据传递给组件,功能相似于函数中的参数
  • state则维护在组件内部,相似于函数中定义的变量

9.什么是高阶组件

高阶组件(HOC)就是一个方法,它接收一个组件并返回一个新的组件。这是一种由React的组成性质衍生出来的模式。
也能够成为“纯组件”,由于它们能够接受任何动态提供的子组件,但不会修改或复制其输入组件中的任何行为。
HOC 能够用在不少状况下,好比:网络

  • 代码重用、逻辑和引导抽象
  • 状态抽象与操做
  • Props操做

10.使用带有props参数的超级构造函数的目的是什么

一个子类的构造器在调用sper方法以前是不能使用this引用的。就行ES6中的sub-classes。将props参数传递给super()调用的主要缘由是访问子构造函数中的this.props。

  • 传递props
class MyComponent extends React.Component {
    constructor(props) {
        super(props);
        console.log(this.props);  // Prints { name: 'sudheer',age: 30 }
    }
}
复制代码
  • 不传递props
class MyComponent extends React.Component {
    constructor(props) {
        super();
        console.log(this.props); // Prints undefined
        // But Props parameter is still available
        console.log(props); // Prints { name: 'sudheer',age: 30 }
    }

    render() {
        // No difference outside constructor
        console.log(this.props) // Prints { name: 'sudheer',age: 30 }
    }
}
复制代码

上面的代码片断能够看出,this.props行为仅在构造函数中不一样,构造函数以外的表现都是同样的。

11.什么是受控组件

在HTML中,表单元素<input><select>以及<textarea>等,都维护本身的状态并根据用户输入进行更新。当用户提交表单时,上述元素的值将随表单一块儿发送。但在React中,并非这样的,包含表单的组件将跟踪处于其状态中的<input>的值,并在每次启动回调函数(例如onChange)时,由于状态将被更新而从新渲染该组件。
一个输入表单元素,其值以这种方式由React控制,称为受控组件。

12.下面的表达式使用React.createElement的等价写法

const element = (
  <h1 className="greeting">
    Hello, world!
  </h1>

);
复制代码

Answer:

const element = React.createElement(
  'h1',
  {className: 'greeting'},
  'Hello, world!'
);
复制代码

13.怎么理解JSX

当facebook第一次向人们介绍react时,也介绍了一种新的JavaScript写法,也就是 JSX,它将HTML模版写在javascrit代码中。JSX自己是没法被浏览器识别的,它必须借助bable或者webpack编译成传统的javascrit。尽管解一开始许多开发人员下意识的反对这种写法,但JSX(与ES2015一块儿)已经成为定义React组件的肯定方法。

class MyComponent extends React.Component {
  render() {
    let props = this.props;  
    return (
      <div className="my-component">
      <a href={props.url}>{props.name}</a>
      </div>

    );
  }
}
复制代码
14.给定一段代码,找出其中的两处问题?

代码以下:

class MyComponent extends React.Component {
  constructor(props) {
    // set the default internal state
    this.state = {
      clicks: 0
    };
  }

  componentDidMount() {
    this.refs.myComponentDiv.addEventListener('click'this.clickHandler);
  }

  componentWillUnmount() {
    this.refs.myComponentDiv.removeEventListener('click'this.clickHandler);
  }

  clickHandler() {
    this.setState({
      clicks: this.clicks + 1
    });
  }

  render() {
    let children = this.props.children;

    return (
      <div className="my-component" ref="myComponentDiv">
      <h2>My Component ({this.state.clicks} clicks})</h2>
      <h3>{this.props.headerText}</h3>
    {children}
    </div>
    );
  }
}
复制代码

Answer:

  • 构造器中没有将props传给supr()
constructor(props) {
  super(props);
  // ...
}

复制代码
  • 事件侦听器(经过addEventListener()分配时)的做用域不正确。所以,开发人员须要在构造函数中从新分配clickHandler,以包含对此的正确绑定:
constructor(props) {
  super(props);
  this.clickHandler = this.clickHandler.bind(this);
  // ...
}

复制代码

15.介绍下React组件生命周期的不一样阶段

React组件的生命周期有四个不一样的阶段:

  1. 初始化(Initialization):在此阶段,react组件准备设置初始状态和默认props。
  2. mounting这个阶段包括componentWillMountcomponentDidMount**两个生命周期方法。
  3. 更新(updating):在这个阶段,组件经过两种方法获取更新:传入新的props以及更新state。包括shouldComponentUpdate, componentWillUpdate 以及 componentDidUpdate三个生命周期方法。
  4. Unmounting: 最后一个阶段,组件再也不被须要,就会从DOM节点上移除。包括componentWillUnmount方法。

16.React中的生命周期方法

  1. componentWillMount:在渲染以前触发,能够用来在根组件里作APP级别的配置。
  2. componentDidMount:在渲染以后触发,在这个阶段AJAX请求、DOM和状态更新以及事件监听均可以触发了。
  3. componentWillReceiveProps:在特定的prop更新引发state变化时触发。
  4. shouldComponentUpdate:用来决定组件是否应该被更新。一般默认返回true。若是你确认组件在state或者prop变化以后不须要更新,那么你能够返回false。由于你能够在组件接收到一个新的prop的时候阻止组件的从新渲染,这对于提升组件性能是一种很好的方式。
  5. componentWillUpdate:props或者state发生变化以及shouldComponentUpdate返回为true,那么在组件从新渲染以前就会触发此方法。
  6. componentDidUpdate:它主要用于更新DOM以响应prop或state的更改。
  7. componentWillUnmount:这个方法主要用于取消任何已发出的网络请求,或删除与组件关联的全部事件侦听器。

17.什么是React Hooks

React Hooks时在React 16.8新增的性质。它的的意思是,组件尽可能写成纯函数,若是须要外部功能和反作用,就用钩子把外部代码"钩"进来。
它容许你不须要写一个类,就可使用react的状态和其它性质。经过Hooks,您能够从组件中提取有状态逻辑,这样就能够独立测试并重用它。Hooks容许您重用有状态逻辑,而无需更改组件层次结构。这使得在许多组件之间钩子变得很容易。

18.使用React Hooks有什么优点

在Hooks出现以前,咱们写一个简单的组件都要建立一个类,在大型复杂的项目中每每很复杂。最终致使:

  • 大型组件很难拆分和重构,也很难测试。
  • 业务逻辑分散在组件的各个方法之中,致使重复逻辑或关联逻辑。
  • 组件类引入了复杂的编程模式,好比 render props 和高阶组件。

React Hooks 的设计目的,就是增强版函数组件,彻底不使用"类",就能写出一个全功能的组件。
一般, hooks可以提取和重用状态逻辑,这种逻辑在多个组件之间是通用的,而不须要高阶组件或渲染props来实现。hooks可以轻松地操做功能组件的状态,而无需将它们转换为类组件。
Hooks在类组件里面不起做用。经过使用它,咱们能够避免使用componentDidMount, componentDidUpdate, componentWillUnmount这些生命周期方法。但须要使用例如useffect这样的内置钩子。

19.React中useState()是什么

...
const [count, setCounter] = useState(0);
const [moreStuff, setMoreStuff] = useState(...);
...

const setCount = () => {
    setCounter(count + 1);
    setMoreStuff(...);
    ...
};
复制代码

useState是react hooks的一个内置方法。useState(0)返回一个元组,其中第一个参数count是计数器的当前状态,setCounter是容许咱们更新计数器状态的方法。
咱们可使用setCounter方法在任何地方更新count的状态。这里,咱们在setCount函数中使用它,在这里咱们能够作更多的事情;hooks的思想是,咱们可使代码更具功能性,并在非必要的状况下避免基于类的组件。

20.描述一下Flux vs MVC

传统的MVC框架很好的将数据 (Model), UI (View) 以及 逻辑 (Controller) 分离开,但它仍然面临两个问题:

  • 数据流的弱定义:在视图之间发生的层叠更新经常致使难以调试的复琐事件网络。
  • 缺乏数据的总体管理:模型数据能够从任何地方变异,从而在整个UI中产生不可预测的结果。

Flux模式使得复杂组件不须要再经过级联更新的方式渲染组件。每一个组件均可以经过store提供的数据维护本身的状态。Flux模式还经过限制对共享数据的直接访问来加强数据的统一管理。

相关文章
相关标签/搜索