(十三)- 前端-面试-REACT

React相关

1.React 中 keys 的作用是什么?

key 是用来帮助 react 识别哪些内容被更改、添加或者删除。key 需要写在用数组渲染出来的元素内部,并且需要赋予其一个稳定的值。稳定在这里很重要,因为如果 key 值发生了变更,react 则会触发 UI 的重渲染。这是一个非常有用的特性。

key 的唯一性

在相邻的元素间,key 值必须是唯一的,如果出现了相同的 key,同样会抛出一个 Warning,告诉相邻组件间有重复的 key 值。并且只会渲染第一个重复 key 值中的元素,因为 react 会认为后续拥有相同 key 的都是同一个组件。

key 值不可读

虽然我们在组件上定义了 key,但是在其子组件中,我们并没有办法拿到 key 的值,因为 key 仅仅是给 react 内部使用的。如果我们需要使用到 key 值,可以通过其他方式传入,比如将 key 值赋给 id 等。、

2.调用 setState 之后发生了什么?

setState(updater, callback)这个方法是用来告诉react组件数据有更新,有可能需要重新渲染。它是异步的,react通常会集齐一批需要更新的组件,然后一次性更新来保证渲染的性能;

react的生命周期和合成事件中,react仍然处于他的更新机制中,这时更新标识为true。按照上述过程,这时无论调用多少次setState,都会不会执行更新,而是将要更新的state存入_``更新队列中,将要更新的组件存入一个数组中;当上一次更新机制执行完毕后会将更新标识设置为false。这时将一次性执行之前累积的setState。由执行机制看,setState本身并不是异步的,而是如果在调用setState时,如果react正处于更新过程,当前更新会被暂存,等上一次更新执行后在执行,这个过程给人一种异步的假象;可以理解成在生命周期和合成事件中,setState是异步的,但是在原生事件中,setState是同步的;

3:什么是虚拟DOM?

虚拟 DOM (VDOM)****是真实 DOM 在内存中的表示。****UI 的表示形式保存在内存中,并与实际的 DOM 同步。这是一个发生在渲染函数被调用和元素在屏幕上显示之间的步骤,整个过程被称为调和****。

为什么虚拟 dom 会提高性能?

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

具体实现步骤如下:

\1. 用 JavaScript 对象结构表示 DOM 树的结构;然后用这个树构建一个真正的 DOM 树,插到文档当中

\2. 当状态变更的时候,重新构造一棵新的对象树。然后用新的树和旧的树进行比较,记录两棵树差异

3. 把2所记录的差异应用到步骤1所构建的真正的DOM树上,视图就更新了。

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

diff算法

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

l React 只会匹配相同 class 的 component(这里面的class指的是组件的名字)

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

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

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

\1. 类组件可以使用其他特性,如状态 state 和生命周期钩子。

\2. 当组件只是接收 props 渲染到页面时,就是无状态组件,就属于函数组件,也被称为哑组件或展示组件。

函数组件和类组件当然是有区别的,而且函数组件的性能比类组件的性能要高,因为类组件使用的时候要实例化,而函数组件直接执行函数取返回结果即可。为了提高性能,尽量使用函数组件。

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

5:React 中 refs 干嘛用的?

Refs 提供了一种访问在render方法中创建的 DOM 节点或者 React 元素的方法。在典型的数据流中,props 是父子组件交互的唯一方式,想要修改子组件,需要使用新的pros重新渲染它。凡事有例外,某些情况下咱们需要在典型数据流外,强制修改子代,这个时候可以使用 Refs

咱们可以在组件添加一个 ref 属性来使用,该属性的值是一个回调函数,接收作为其第一个参数的底层 DOM 元素或组件的挂载实例。

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属性,它的值是一个函数。该函数接收输入的实际 DOM 元素,然后将其放在实例上,这样就可以在 handleSubmit 函数内部访问它。

经常被误解的只有在类组件中才能使用 refs,但是refs也可以通过利用 JS 中的闭包与函数组件一起使用。

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

6:state 和 props 区别是啥?

propsstate是普通的 JS 对象。虽然它们都包含影响渲染输出的信息,但是它们在组件方面的功能是不同的。即

\1. state 是组件自己管理数据,控制自己的状态,可变;

\2. props 是外部传入的数据参数,不可变;

\3. 没有state的叫做无状态组件,有state的叫做有状态组件;

\4. 多用 props,少用 state,也就是多写无状态组件。

7.react性能优化是哪个周期函数?

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

8:什么是高阶组件?

高阶组件(HOC)是接受一个组件并返回一个新组件的函数。基本上,这是一个模式,是从 React 的组合特性中衍生出来的,称其为纯组件,因为它们可以接受任何动态提供的子组件,但不会修改或复制输入组件中的任何行为。

const EnhancedComponent = higherOrderComponent(WrappedComponent);

HOC 可以用于以下许多用例

\1. 代码重用、逻辑和引导抽象

\2. 渲染劫持

\3. state 抽象和操作

\4. props 处理

8:在构造函数调用 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 的行为只有在构造函数中是不同的,在构造函数之外也是一样的。

9:什么是受控组件?

在 HTML 中,表单元素如 <input><textarea><select>通常维护自己的状态,并根据用户输入进行更新。当用户提交表单时,来自上述元素的值将随表单一起发送。

而 React 的工作方式则不同。包含表单的组件将跟踪其状态中的输入值,并在每次回调函数(例如onChange)触发时重新渲染组件,因为状态被更新。以这种方式由 React 控制其值的输入表单元素称为受控组件

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

\1. 受控组件是 React 控制中的组件,并且是表单数据真实的唯一来源。

\2. 非受控组件是由 DOM 处理表单数据的地方,而不是在 React 组件中。

尽管非受控组件通常更易于实现,因为只需使用refs即可从 DOM 中获取值,但通常建议优先选择受控制的组件,而不是非受控制的组件。

这样做的主要原因是受控组件支持即时字段验证,允许有条件地禁用/启用按钮,强制输入格式。

10:如何 实现React.createElement ?

![img](file:///C:/Users/admin/AppData/Local/Temp/msohtmlclip1/01/clip_image030.jpg)

11:讲讲什么是 JSX ?

Facebook 第一次发布 React 时,他们还引入了一种新的 JS 方言 JSX,将原始 HTML 模板嵌入到 JS 代码中。JSX 代码本身不能被浏览器读取,必须使用Babelwebpack等工具将其转换为传统的JS。很多开发人员就能无意识使用 JSX,因为它已经与 React 结合在一直了。

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

12:React 的生命周期方法有哪些?

\1. componentWillMount:在渲染之前执行,用于根组件中的 App 级配置。

\2. componentDidMount:在第一次渲染之后执行,可以在这里做AJAX请求,DOM 的操作或状态更新以及设置事件监听器。

\3. componentWillReceiveProps:在初始化render的时候不会执行,它会在组件接受到新的状态(Props)时被触发,一般用于父组件状态更新时子组件的重新渲染

\4. shouldComponentUpdate:确定是否更新组件。默认情况下,它返回true。如果确定在 stateprops 更新后组件不需要在重新渲染,则可以返回false,这是一个提高性能的方法。

\5. componentWillUpdate:在shouldComponentUpdate返回 true 确定要更新组件之前件之前执行。

\6. componentDidUpdate:它主要用于更新DOM以响应propsstate更改。

\7. componentWillUnmount:它用于取消任何的网络请求,或删除与组件关联的所有事件监听器

13:这三个点(...)在 React 干嘛用的?

... 在React(使用JSX)代码中做什么?它叫什么?

<Modal {...this.props} title='Modal heading'  animation={false}/>

这个叫扩展操作符号或者展开操作符,例如,如果this.props包含a``:``1b``:``2,则

<Modal {...this.props} title='Modal heading' animation={false}>

等价于下面内容:

<Modal a={this.props.a} b={this.props.b} title='Modal heading' animation={false}>

扩展符号不仅适用于该用例,而且对于创建具有现有对象的大多数(或全部)属性的新对象非常方便,在更新state 咱们就经常这么做:

this.setState(prevState => {
    return {foo: {...prevState.foo, a: "updated"}};
});

14:使用 React Hooks 好处是啥?

首先,Hooks 通常支持提取和重用跨多个组件通用的有状态逻辑,而无需承担高阶组件或渲染 props 的负担。Hooks 可以轻松地操作函数组件的状态,而不需要将它们转换为类组件。

Hooks 在类中不起作用,通过使用它们,咱们可以完全避免使用生命周期方法,例如 componentDidMountcomponentDidUpdatecomponentWillUnmount。相反,使用像useEffect这样的内置钩子。

15:什么是 React Hooks?

Hooks是 React 16.8 中的新添加内容。它们允许在不编写类的情况下使用state和其他 React 特性。使用 Hooks,可以从组件中提取有状态逻辑,这样就可以独立地测试和重用它。Hooks 允许咱们在不改变组件层次结构的情况下重用有状态逻辑,这样在许多组件之间或与社区共享 Hooks 变得很容易。

16:React 中的 useState() 是什么?

下面说明useState(0)的用途:


useState 是一个内置的 React Hook。useState(0) 返回一个元组,其中第一个参数count是计数器的当前状态,setCounter 提供更新计数器状态的方法。

咱们可以在任何地方使用setCounter方法更新计数状态-在这种情况下,咱们在setCount函数内部使用它可以做更多的事情,使用 Hooks,能够使咱们的代码保持更多功能,还可以避免过多使用基于类的组件。

17:描述 Flux 与 MVC?

传统的 MVC 模式在分离数据(Model)、UI(View和逻辑(Controller)方面工作得很好,但是 MVC 架构经常遇到两个主要问题:

数据流不够清晰:跨视图发生的级联更新常常会导致混乱的事件网络,难于调试。

缺乏数据完整性:模型数据可以在任何地方发生突变,从而在整个UI中产生不可预测的结果。

使用 Flux 模式的复杂用户界面不再遭受级联更新,任何给定的React 组件都能够根据 store 提供的数据重建其状态。Flux 模式还通过限制对共享数据的直接访问来加强数据完整性。

18:如何避免在React重新绑定实例?

有几种常用方法可以避免在 React 中绑定方法:

1.将事件处理程序定义为内联箭头函数

class SubmitButton extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      isFormSubmitted: false
    };
  }
  render() {
    return (
      <button onClick={() => {
        this.setState({ isFormSubmitted: true });
      }}>Submit</button>
    )
  }
}

2.使用箭头函数来定义方法:

class SubmitButton extends React.Component {
  state = {
    isFormSubmitted: false
  }
  handleSubmit = () => {
    this.setState({
      isFormSubmitted: true
    });
  }
  render() {
    return (
      <button onClick={this.handleSubmit}>Submit</button>
    )
  }
}

3.使用带有 Hooks 的函数组件

const SubmitButton = () => {
  const [isFormSubmitted, setIsFormSubmitted] = useState(false);
  return (
    <button onClick={() => {
        setIsFormSubmitted(true);
    }}>Submit</button>
  )
};

19.了解 redux 么,说一下 redux 的作用和运用流程,redux 有什么缺点

Redux 是一个 数据管理中心,可以把它理解为一个全局的 data store 实例。它通过一定的使用规则和限制,保证着数据的健壮性、可追溯和可预测性。它与 React 无关,可以独立运行于任何 JavaScript 环境中,从而也为同构应用提供了更好的数据同步通道。

· 核心理念:

o 单一数据源: 整个应用只有唯一的状态树,也就是所有 state 最终维护在一个根级 Store 中;

o 状态只读: 为了保证状态的可控性,最好的方式就是监控状态的变化。那这里就两个必要条件:

§ Redux Store 中的数据无法被直接修改;

§ 严格控制修改的执行;

o 纯函数: 规定只能通过一个纯函数 (Reducer) 来描述修改;

posted @ 2020-12-23 14:47  HelloBytes  阅读(165)  评论(0编辑  收藏  举报