# React 基础面试题答案解析

关于答案解析

  • React 相关面试题答案解析过程是根据自身项目实践以及查阅官方文档等最终的得出结论。
  • 仅供学习参考,评论区感谢补充和纠错 !

# 1、React 是什么 ?

答案解析

React 是一个开源的前端 JavaScript 库,用于构建用户界面,尤其适用于单页应用程序。它用于处理 Web 和移动应用程序的视图层

# 2、React 的主要特点是什么 ?

答案解析

  • 考虑到 RealDOM(真实 DOM)操作成本高昂,它使用 VirtualDOM(虚拟 DOM)而不是 RealDOM
  • 支持服务器端渲染
  • 遵循单向数据流或数据绑定
  • 使用可重用/可组合的 UI 组件来开发视图

# 3、使用 React 有什么好处 ?

答案解析


  • 使用虚拟 DOM 提高效率: React 使用虚拟 DOM 来渲染视图。顾名思义,虚拟 DOM 是真实 DOM 的虚拟表示。每次 React 应用程序中的数据发生变化时,都会创建一个新的虚拟 DOM。创建虚拟 DOM 比在浏览器中渲染 UI 快得多。因此,随着虚拟 DOM 的使用,应用程序的效率得到了提高。
  • 温和的学习曲线:与 Angular 等框架相比,React 具有温和的学习曲线。任何对 JavaScript 知之甚少的人都可以开始使用 React 构建 Web 应用程序。
  • SEO 友好: React 允许开发人员开发引人入胜的用户界面,可以在各种搜索引擎中轻松导航。它还允许服务器端渲染,从而提高应用程序的 SEO。
  • 可重用组件: React 使用基于组件的架构来开发应用程序,组件是独立且可重用的代码,这些组件可以在具有类似功能的各种应用程序之间共享,组件的重复使用加快了开发速度。
  • 庞大的库生态系统可供选择:React 让你可以根据自己的需求自由选择工具、库和架构来开发应用程序。

# 4、React 的局限性是什么 ?

答案解析

  • React 不是一个成熟的框架,因为它只是一个库
  • React 的组件众多,需要时间才能完全掌握所有组件的好处
  • 初学者程序员可能很难理解 React
  • 编码可能会变得复杂,因为它将使用内联模板和 JSX

# 5、Real DOM(真实 DOM)和 Virtual DOM(虚拟 DOM)区别 ?

真实的 DOM 虚拟 DOM
更新慢 更新速度更快
可以直接更新 HTML 不能直接更新 HTML
如果元素更新,则创建一个新的 DOM 如果元素更新,则更新 JSX
DOM 操作代价很高 DOM 操作非常简单
内存消耗较多 没有内存消耗

# 6、什么是 JSX ?

答案解析

JSX 是 ECMAScript 的类似 XML 的语法扩展(首字母缩写词代表 JavaScript XML)。

  • 基本上,它只是为React.createElement()函数提供语法糖,为我们提供 JavaScript 的表现力以及类似 HTML 的模板语法。
// 在下面的示例中,<h1>标签内的文本作为 JavaScript 函数返回给渲染函数。
class App extends React.Component {
  render() {
    return (
      <div>
        <h1>{"Welcome to React world!"}</h1>
      </div>
    );
  }
}

# 7、为什么浏览器无法读取 JSX ?

答案解析

  • 浏览器只能处理 JavaScript 对象,而不能读取常规 JavaScript 对象中的 JSX。
  • 所以为了使浏览器能够读取 JSX,首先,需要用像 Babel 这样的 JSX 转换器将 JSX 文件转换为 JavaScript 对象,然后再将其传给浏览器。

# 8、React 中的 useState() 是什么 ?

答案解析

  • useState() 是一个内置的 React Hook,它允许您在功能组件中拥有状态变量。
  • 当 DOM 具有动态操作/控制的东西时,应该使用它。

在下面给出的示例代码中,useState(0) 将返回一个元组,其中 count 是表示计数器当前状态的第一个参数,第二个参数 setCounter 方法将允许我们更新计数器的状态。

...
const [count, setCounter] = useState(0);
const [otherStuffs, setOtherStuffs] = useState(...);
...
const setCount = () => {
   setCounter(count + 1);
   setOtherStuffs(...);
   ...
};

可以使用 setCounter() 方法在任何地方更新计数状

  • 在此示例中,我们在 setCount 函数中使用 setCounter(),还可以完成各种其他操作。
  • 使用钩子的想法是,我们将能够使我们的代码更具功能性,并在不需要时避免使用基于类的组件。

# 9、React 中的键是什么 ?

答案解析

key 是使用元素列表时需要包含的特殊字符串属性,其 key 的重要性如下:

  • key 有助于 React 识别添加、更改或删除的元素
  • 应为数组元素提供 key,以便为每个元素提供唯一标识
  • 没有 key,React 无法理解每个元素的顺序或唯一性
  • 通过 key,React 可以知道删除、编辑和添加了哪个特定元素
  • key 通常用于显示来自 API 的数据列表

注意: 数组中使用的 key 在兄弟姐妹中应该是唯一的,它们不必是全球唯一的

image-20220406165211010

// 使用key的事例
const ids = [1, 2, 3, 4, 5];
const listElements = ids.map((id) => {
  return <li key={id.toString()}>{id}</li>;
});

# 10、使用 React Hooks 时必须遵守哪些规则 ?

答案解析

使用 Hooks 编码时必须遵循 2 条规则:

  • React Hooks 只能在顶层调用。不允许在嵌套函数、循环或条件中调用它们。
  • 只允许从 React 函数组件调用 Hook。

# 11、为什么 React Hooks 使用 refs ?

答案解析

以前,refs 仅限于类组件,但现在它也可以通过 React 中的 useRef Hook 在函数组件中访问

主要用于:

  • 管理焦点、媒体播放或文本选择
  • 通过第三方与 DOM 库集成
  • 触发命令式动画

# 12、为什么浏览器无法读取 JSX ?

答案解析

浏览器只能处理 JavaScript 对象,而不能读取常规 JavaScript 对象中的 JSX。

  • 所以为了使浏览器能够读取 JSX,首先,需要用像 Babel 这样的 JSX 转换器将 JSX 文件转换为 JavaScript 对象,然后再将其传给浏览器。

# 13、与 ES5 相比,React 的 ES6 语法有何不同 ?

以下语法是 React 的 ES5 与 ES6 中的区别

  • require 与 import
// ES5
var React = require("react");
// ES6
import React from "react";
  • export 与 exports
// ES5
module.exports = Component;
// ES6
export default Component;
  • component 和 function
// ES5
var MyComponent = React.createClass({
  render: function () {
    return;
    <h3>Hello arry老师</h3>;
  },
});
// ES6
class MyComponent extends React.Component {
  render() {
    return;
    <h3>Hello arry老师</h3>;
  }
}
  • props
// ES5
var App = React.createClass({
  propTypes: { name: React.PropTypes.string },
  render: function () {
    return;
    <h3>Hello, {this.props.name}!</h3>;
  },
});
// ES6
class App extends React.Component {
  render() {
    return;
    <h3>Hello, {this.props.name}!</h3>;
  }
}
  • state
// ES5
var App = React.createClass({
  getInitialState: function () {
    return { name: "world" };
  },
  render: function () {
    return;
    <h3>Hello, {this.state.name}!</h3>;
  },
});
// ES6
class App extends React.Component {
  constructor() {
    super();
    this.state = { name: "world" };
  }
  render() {
    return;
    <h3>Hello, {this.state.name}!</h3>;
  }
}

# 14、你是如何理解在 React 中,“一切都是组件” 这句话 ?

答案解析

  • 组件是 React 应用 UI 的构建块,这些组件将整个 UI 分成小的独立并可重用的部分。
  • 每个组件彼此独立,而不会影响 UI 的其余部分。

# 15、React 中 render() 的作用是什么 ?

答案解析

  • 每个 React 组件都必须强制有一个render() 它返回一个单一的 React 元素,它是原生 DOM 组件的表示。
  • 如果需要渲染多个 HTML 元素,则必须将它们组合在一个封闭标记中,例如<form><group><div>

此函数必须保持纯净,即必须每次调用时都返回相同的结果

# 16、如何将两个或多个组件嵌入到一个组件中 ?

// 通过以下方式将组件嵌入其中
class MyComponent extends React.Component {
  render() {
    return (
      <div>
        <h1>Hello</h1>
        <Header />
      </div>
    );
  }
}
class Header extends React.Component {
  render() {
    return;
    <h1>Header Component</h1>;
  }
}
ReactDOM.render(<MyComponent />, document.getElementById("content"));

# 17、React 中的 state(状态)是什么 ?

答案解析

  • 组件的状态(state )是一个对象,它包含一些可能在组件的生命周期内发生变化的信息。
  • 我们应该始终尝试使我们的状态尽可能简单,并尽量减少有状态组件的数量。
// 我们来创建一个带有消息状态的用户组件
class User extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      message: "Welcome to React world ,Hello Arry老师",
    };
  }
  render() {
    return (
      <div>
        <h1>{this.state.message}</h1>
      </div>
    );
  }
}

image-20220405012255560

State 类似于 props,但它是私有的并且完全由组件控制,即在所有者组件决定传递它之前,任何其他组件都无法访问它。

# 18、React 中的 props 是什么 ?

答案解析

props 是组件的输入。它们是单个值或包含一组值的对象,这些值在创建时使用类似于 HTML 标记属性的命名约定传递给组件。它们是从父组件传递到子组件的数据

React 中 props 的主要目的是提供以下组件功能:

  • ① 将自定义数据传递给你的组件
  • ② 触发状态变化
  • ③ 通过this.props.reactProp内部组件的render()方法使用
// 例如,创建一个具有reactProp属性的元素:
<Element reactProp={"1"} />;

// 这个reactProp(或任何你想出来的)名称然后成为附加到 React 的本机 props 对象的属性
// 该对象最初已经存在于使用 React 库创建的所有组件上。
props.reactProp;

# 19、为什么我们不应该直接更新状态 ?

答案解析

如果你尝试直接更新状态,那么它不会重新渲染组件。

// 错误
this.state.message = "Hello world";

// 而是使用setState()方法,它安排对组件状态对象的更新。当状态改变时,组件通过重新渲染来响应
this.setState({ message: "Hello World" }); // 正确做法

注意:你可以在构造函数中或使用最新 JavaScript 的类字段声明语法直接分配给状态对象

# 20、state 状态 和 props 有什么区别 ?

答案解析

propsstate都是纯 JavaScript 对象。

  • 虽然它们都持有影响渲染输出的信息,但它们在组件方面的功能不同。
  • Props 类似于函数参数传递给组件,而 state 在组件内管理,类似于在函数中声明的变量。
条件 State Props
从父组件中接收初始值 Yes Yes
父组件可以改变值 No Yes
在组件中设置默认值 Yes Yes
在组件的内部变化 Yes No
设置子组件的初始值 Yes Yes
在子组件的内部更改 No Yes

# 21、有状态和无状态组件的区别 ?

有状态的组件 无状态组件
在内存中存储有关组件状态变化的信息 计算组件的内部状态
有权改变状态 无权改变状态
包含过去、现在和未来可能的状态变化情况 不包含过去,现在和未来可能发生的状态变化情况
接受无状态组件状态变化要求的通知,然后将 props 发送给他们 从有状态组件接收 props 并将其视为回调函数。

# 22、React 组件生命周期的阶段是什么 ?

答案解析

React 组件的生命周期有三个不同的阶段:

  • 初始渲染阶段:这是组件即将开始其生命之旅并进入 DOM 的阶段。
  • 更新阶段:一旦组件被添加到 DOM,它只有在 prop 或状态发生变化时才可能更新和重新渲染,这些只发生在这个阶段。
  • 卸载阶段:这是组件生命周期的最后阶段,组件被销毁并从 DOM 中删除。

# 23、你对受控组件和非受控组件了解多少 ?

受控组件 非受控组件
没有维持自己的状态 保持着自己的状态
数由父组件控制 数据由 DOM 控制
通过 props 获取当前值,然后通过回调通知更改 Refs 用于获取其当前值

# 24、Element(元素)和 Component(组件)有什么区别 ?

答案解析

  • Element 是一个简单的对象,它根据 DOM 节点或其他组件描述你希望在屏幕上显示的内容,元素可以在其 props 中包含其他元素。
  • 创建一个 React 元素很容易,一旦创建了一个元素,它就永远不会发生变异。
// React Element 的对象表示如下
const element = React.createElement(
  'div',
  {id: 'login-btn'},
  'Login'
)
// 上面的React.createElement()函数返回一个对象:
{
  type: 'div',
  props: {
    children: 'Login',
    id: 'login-btn'
  }
}
// 最后它使用以下方式渲染到DOM,ReactDOM.render();
<div id='login-btn'>Login</div>
  • 而一个组件可以用几种不同的方式声明。它可以是具有render()方法的类,也可以定义为函数。
  • 无论哪种情况,它都将 props 作为输入,并返回一个 JSX 树作为输出:
const Button = ({ onLogin }) => (
  <div id={"login-btn"} onClick={onLogin}>
    Login
  </div>
);

然后 JSX 被转译成React.createElement()函数树:

const Button = ({ onLogin }) =>
  React.createElement("div", { id: "login-btn", onClick: onLogin }, "Login");

# 25、如何在 React 中创建组件 ?

有两种方法来创建组件

  • Function Components:这是创建组件的最简单方法,这些是纯 JavaScript 函数,它们接受 props 对象作为第一个参数并返回 React 元素:
function Greeting({ message }) {
  return <h1>{`Hello, ${message}`}</h1>;
}
  • Class Components:你也可以使用 ES6 类来定义一个组件,上面的函数组件可以写成:
class Greeting extends React.Component {
  render() {
    return <h1>{`Hello, ${this.props.message}`}</h1>;
  }
}

# 26、何时在函数组件上使用类组件 ?

答案解析

如果组件需要状态或生命周期方法,则使用类组件,否则使用函数组件

  • 然而,在 React 16.8 中,通过添加 Hooks,您可以使用状态、生命周期方法和其他功能,这些功能仅在功能组件的类组件中可用
  • 因此,除非您需要一个函数组件等效物尚未出现的 React 功能,如错误边界,否则始终建议使用函数组件

# 27、你能用 HOC 做什么 ?

答案解析

HOC 可用于许多任务,例如:

  • 代码重用,逻辑和引导抽象
  • 渲染劫持
  • 状态抽象和控制
  • Props 控制

# 28、解释一下 Flux ?

答案解析

Flux 是一种强制单向数据流的架构模式。

  • 它控制派生数据,并使用具有所有数据权限的中心 store 实现多个组件之间的通信。
  • 整个应用中的数据更新必须只能在此处进行,Flux 为应用提供稳定性并减少运行时的错误。

flux-547x180

# 29、Redux 遵循的三个原则是什么 ?

答案解析

  • 单一事实来源:整个应用的状态存储在单个 store 中的对象/状态树里,单一状态树可以更容易地跟踪随时间的变化,并调试或检查应用程序
  • 状态是只读的:改变状态的唯一方法是去触发一个动作,动作是描述变化的普通 JS 对象,就像 state 是数据的最小表示一样,该操作是对数据更改的最小表示
  • 使用纯函数进行更改:为了指定状态树如何通过操作进行转换,你需要纯函数。
  • 纯函数是那些返回值仅取决于其参数值的函数

1111111-16529643137339

# 30、数据是如何通过 Redux 流动的 ?

答案解析

Redux 由以下组件组成:

  • Action:这是一个用来描述发生了什么事情的对象
  • Reducer: 这是一个确定状态将如何变化的地方
  • Store: 整个程序的状态/对象树保存在 Store 中
  • View:只显示 Store 提供的数据

flowda-768x333-165296433670711

# 31、Redux 与 Flux 有何不同 ?

Flux Redux
Store 包含状态和更改逻辑 Store 和更改逻辑是分开的
有多个 Store 只有一个 Store
所有 Store 都互不影响且是平级的 带有分层 reducer 的单一 Store
有单一调度器 没有调度器的概念
React 组件订阅 store 容器组件是有联系的
状态是可变的 状态是不可改变的

# 32、Redux 有哪些优点 ?

答案解析


  • 结果的可预测性:由于总是存在一个真实来源,即 store ,因此不存在如何将当前状态与动作和应用的其他部分同步的问题
  • 可维护性:代码变得更容易维护,具有可预测的结果和严格的结构。
  • 服务器端渲染:你只需将服务器上创建的 store 传到客户端即可。这对初始渲染非常有用,并且可以优化应用性能,从而提供更好的用户体验
  • 开发人员工具:从操作到状态更改,开发人员可以实时跟踪应用中发生的所有事情
  • 社区和生态系统:Redux 背后有一个巨大的社区,这使得它更加迷人。一个由才华横溢的人组成的大型社区为库的改进做出了贡献,并开发了各种应用。
  • 易于测试:Redux 的代码主要是小巧、纯粹和独立的功能。这使代码可测试且独立。
  • 组织:Redux 准确地说明了代码的组织方式,这使得代码在团队使用时更加一致和简单

# 33、React Router 与常规路由有何不同 ?

主题 常规路由 React 路由
参与的页面 每个视图对应一个新文件 只涉及单个 HTML 页面
URL 更改 HTTP 请求被发送到服务器并且接收相应的 HTML 页面 仅更改历史记录属性
体验 用户实际在每个视图的不同页面切换 用户认为自己正在不同的页面间切换

# 34、HTML 和 React 事件处理有什么区别 ?

以下是 HTML 和 React 事件处理之间的一些主要区别有 3 点

(1)在 HTML 中,事件名称通常以小写形式表示:

<button onclick="activateLasers()"></button>

而在 React 中,它遵循 camelCase 约定:

<button onClick="{activateLasers}"></button>

(2)在 HTML 中,你可以返回false以防止默认行为:

<a href="#" onclick='console.log("链接被点击了。"); return false;' />

而在 React 中你必须preventDefault()显式调用:

function handleClick(event) {
  event.preventDefault();
  console.log("链接被点击了。");
}

(3)在 HTML 中,需要通过追加()来调用函数,而在 react 中,不应该用函数名追加()

# 35、如何将参数传递给事件处理程序或回调 ?

// (1)你可以使用箭头函数环绕事件处理程序并传递参数
<button onClick={() => this.handleClick(id)} />
// 这相当于调用.bind
<button onClick={this.handleClick.bind(this, id)} />

// (2)除了这两种方法之外,你还可以将参数传递给定义为箭头函数的函数
<button onClick={this.handleClick(id)} />
handleClick = (id) => () => {
    console.log(id);
};

# 36、什么是内联条件表达式 ?

答案解析

  • 你可以使用 JS 提供的 if 语句 或 三元表达式来有条件地呈现表达式。
  • 除了这些方法之外,还可以将任何表达式嵌入 JSX 中,方法是将它们用花括号括起来,然后后跟 JS 逻辑运算符&&
<h1>Hello!</h1>;
{
  messages.length > 0 && !isLogin ? (
    <h2>You have {messages.length} unread messages.</h2>
  ) : (
    <h2>You don't have unread messages.</h2>
  );
}

# 37、React 中虚拟 DOM 是如何工作的 ?

答案解析

Virtual DOM 虚拟 DOM(VDOM) 是 Real DOM(真实 DOM)的内存表示

  • UI 表示保存在内存中并与“真实”DOM 同步,这是在调用渲染函数和在屏幕上显示元素之间发生的一个步骤。
  • 这整个过程称为 reconciliation

Virtual DOM 通过以下三个简单的步骤工作:

① 每当任何底层数据发生更改时,整个 UI 都会在虚拟 DOM 表示中重新呈现

vdom1

② 然后计算之前的 DOM 表示和新的 DOM 表示之间的差异

vdom2

③ 一旦计算完成,真正的 DOM 将只使用实际更改的内容进行更新

vdom3

# 38、Shadow DOM 和 Virtual DOM 有什么区别 ?

答案解析

  • Shadow DOM: 是一种浏览器技术,主要设计用于在 web 组件中定义变量和 CSS
  • Virtual(虚拟)DOM: 是一个由 JavaScript 库在浏览器 API 之上实现的概念
上次更新时间: 6/8/2023, 9:23:17 PM

大厂最新技术学习分享群

大厂最新技术学习分享群

微信扫一扫进群,获取资料

X