React 是当前广泛应用的 JavaScript 库,用于构建高效的用户界面。根据 2021 年的开发者调查,React 成为最受欢迎的前端框架之一,占据了约 40.14% 的市场份额,并拥有超过 70,000 个 GitHub Star。这意味着掌握 React 的关键概念和常见面试问题是确保求职成功的第一步。
在本文中,我们将系统性地讲解一些 React 基础知识,然后深入探讨面试中常见的问题及其答案,帮助你提升 React 面试表现。
React 是什么?
React 是一个用于创建用户界面的开源前端 JavaScript 库。它是声明式的、高效的、灵活的,并且它遵循基于组件的方法,这使我们能够创建可重用的 UI 组件。
开发人员主要使用 React 来创建单页应用程序,该库仅需专注于 MVC 的视图层。并且它非常快。
React 的特点
React 有许多与众不同的特性,这里有一些亮点:
- React 使用虚拟 DOM 而不是真实浏览器 DOM。
- React 使用单向数据绑定。
- 它用于开发 Web 应用程序以及使用 React Native 的移动应用程序,这使我们能够构建跨平台应用程序。
如何开始一个 React 新项目
我们可以通过初始化项目并安装所有依赖项来从头开始创建 React 应用程序。但最简单的方法是使用 create-react-app
通过以下命令:
npx create-react-app my-app
注意:my-app
是我们正在创建的应用程序的名称,但您可以将其更改为您选择的任何名称。
DOM 代表什么?
术语“DOM”代表文档对象模型,指的是将 Web 应用程序的整个用户界面表示为树状数据结构。
DOM 的类型
我们有两种类型的 DOM,即虚拟 DOM 和真实 DOM。
React 的优点和缺点
以下是 React 的一些优点和缺点:
React 的优点
- 对于 JavaScript 开发人员来说,它的学习曲线更短,并且由于其活跃的社区,可以获得大量的手册、教程和培训材料。
- React 对搜索引擎友好。
- 它使创建丰富的 UI 和自定义组件变得更加容易。
- React 具有极快渲染速度。
- JSX 的使用使我们能够编写更简单、更吸引人且更易于理解的代码。
React 的缺点
- 因为 React 是一个前端库,所以需要其他语言和库来构建一个完整的应用程序。
- 没有经验的程序员可能很难理解,因为它使用了 JSX。
- 由于开发周期短,现有文档很快就会过时。
什么是 JSX?
JavaScript XML 缩写为 JSX。 JSX 支持并简化了 React 中 HTML 的创建,从而产生更具可读性和可理解性的标记。
例如:
const App = () => {
return (
<div>
<h1>Hello World</h1>
</div>
);
};
为什么浏览器不能读取 JSX?
JSX 不是有效的 JavaScript 代码,并且没有允许浏览器读取和理解它的内置实现。我们需要将代码从 JSX 转换为浏览器可以理解的有效 JavaScript 代码,我们使用 Babel,一种 JavaScript 编译器/转译器来完成此任务。
注意:create-react-app
在内部使用 Babel 进行 JSX 到 JavaScript 的转换,但您也可以使用 Webpack 设置自己的 babel 配置。
什么是组件?
组件是一个独立的、可重用的代码块,它将用户界面分成更小的部分,而不是在单个文件中构建整个 UI。
React 中有两种组件:函数组件和类组件(Class 组件)。
什么是类组件?
类组件是返回 JSX 的 ES6 类,必须从 React 继承。由于在早期版本的 React (16.8) 中无法在函数组件内部使用状态,因此函数组件仅用于渲染 UI。
例子:
import React, { Component } from "react";
export default class App extends Component {
render() {
return (
<div>
<h1>Hello World</h1>
</div>
);
}
}
什么是函数组件?
返回 React 元素的 JavaScript/ES6 函数称为函数组件 (JSX)。
自从引入 React Hooks 以来,我们已经能够在函数组件中使用状态,这让许多人采用它们,因为它们的语法更清晰。
例子:
import React from "react";
const App = () => {
return (
<div>
<h1>Hello World</h1>
</div>
);
};
export default App;
函数组件和类组件之间的区别
函数组件 | 类组件 |
---|---|
函数式组件是一个 JavaScript/ES6 函数,它接受一个参数、props 并返回 JSX。 | 要创建一个一个 class 组件,必须从 React 中继承。创建一个组件和一个返回 React 元素的渲染函数。 |
函数组件中没有渲染方法 | 必须使用 render()方法返回 JSX |
函数组件从上至下运行,一旦返回就无法保持活动状态。 | class 组件被实例化,各种生命周期方法根据类组件的阶段保持活跃运行并且被调用。 |
它们也被称为无状态组件,因为它们只接受数据并以某种形式显示,它们主要负责 UI 渲染。 | 它们也被称为有状态组件,因为它们实现了逻辑和状态。 |
不能在函数组件中使用 React 生命周期方法。 | 可以在 class 组件中使用 React 生命周期方法。 |
Hooks 如 useState()被采用以使得函数组件有状态。 | 在 class 组件中要使用另外的语法来实现 hook。 |
不使用构造函数(constructor)。 | 用构造函数(constructor)来存储状态 |
如何在 React 中使用 CSS
有 3 种方法可以使用 CSS 设置 React 应用程序的样式:
- 行内样式
- 外部样式
- JS 中的 CSS
React 中 render() 的用途是什么?
类组件中使用 Render() 返回将在组件中显示的 HTML。它用于读取 props 和 state 并将我们的 JSX 代码返回到我们应用程序的根组件。
什么是 props?
props 也称为属性。它们用于将数据从一个组件传输到下一个组件(父组件到子组件)。它们通常用于呈现动态生成的数据。
注意:子组件永远不能将 props 发送到父组件,因为此流是单向的(父到子)。
例子:
function App({ name, hobby }) {
return (
<div>
<h1>My name is {name}.</h1>
<p>My hobby is {hobby}.</p>
</div>
);
}
export default App;
React 中的 state 是什么?
state 是一个内置的 React 对象,用于在我们的组件中创建和管理数据。它与 props 的不同之处在于它用于存储数据而不是传递数据。
state 是可变的(数据可以改变)并且可以通过 this.state() 访问。
例子:
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
name: "John Doe",
};
}
render() {
return (
<div>
<h1>My name is {this.state.name}</h1>
</div>
);
}
}
如何在 React 中更新组件的状态
重要的是要知道,当我们直接更新状态时,它不会重新渲染组件——这意味着我们看不到更新。
如果我们想让它重新渲染,那么我们必须使用 setState()
方法来更新组件的 state 对象并重新渲染组件。
例子:
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
name: "John Doe",
};
}
changeName = () => {
this.setState({ name: "Jane Doe" });
};
render() {
return (
<div>
<h1>My {this.state.name}</h1>
<button type="button" onClick={this.changeName}>
Change Name
</button>
</div>
);
}
}
如何区分 state 和 props
state 和 props 是具有不同功能的 JavaScript 对象。
props 用于将数据从父组件传输到子组件,而 state 是本地数据存储,仅供组件使用,不能与其他组件共享。
React 中的事件是什么?
在 React 中,事件是可以由用户操作或系统生成的事件触发的操作。鼠标点击、网页加载、按键、窗口大小调整、滚动和其他交互都是事件的示例。
例子:
// For class component
<button type="button" onClick={this.changeName} >Change Name</button>
// For function component
<button type="button" onClick={changeName} >Change Name</button>
如何在 React 中处理事件
React 中的事件处理方式与 DOM 元素类似。我们必须考虑的一个区别是我们事件的命名,它们以驼峰命名而不是小写命名。
例子:
类组件(Class Component)
class App extends Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
console.log("This button was Clicked");
}
render() {
return (
<div>
<button onClick={this.handleClick}>Click Me</button>
</div>
);
}
}
函数组件(Function Component)
const App = () => {
const handleClick = () => {
console.log("Click happened");
};
return (
<div>
<button onClick={handleClick}>Click Me</button>
</div>
);
};
export default App;
如何将参数传递给事件处理程序(Event Handler)
在函数组件中,我们可以这样做:
const App = () => {
const handleClick = (name) => {
console.log(`My name is ${name}`);
};
return (
<div>
<button onClick={() => handleClick("John Doe")}>Click Me</button>
</div>
);
};
export default App;
在类组件中,我们可以这样做:
class App extends React.Component {
call(name) {
console.log(`My name is ${name}`);
}
render() {
return (
<button onClick={this.call.bind(this, "John Doe")}>
Click the button!
</button>
);
}
}
export default App;
什么是 Redux?
Redux 是一个流行的开源 JavaScript 库,用于管理和集中应用程序状态。它通常与 React 或任何其他视图库一起使用。
什么是 React Hooks?
在 v16.8 中添加了 React hooks,使我们无需编写类即可使用 state 和其他 React 功能。
它们不在类组件中运行,而是帮助我们从函数组件挂钩到 React 状态和生命周期特性。
我们什么时候开始在 React 中使用 Hooks 的?
React 团队在 2018 年 10 月下旬的 React Conf(React 年度大会)期间首次向全世界介绍了 React Hooks,然后在 2019 年 2 月上旬 React v16.8.0 中开始使用 hooks。
解释一下 useState Hook
useState Hook 是一个可以在功能组件中使用状态变量的存储。您可以将初始状态传递给此函数,它将返回一个包含当前状态值(不一定是初始状态)的变量和另一个更新此值的函数。
例子:
import React, { useState } from "react";
const App = () => {
const [count, setCount] = useState(0);
return <div>// ...</div>;
};
解释 useEffect Hook
useEffect Hook 允许您在组件中执行副作用,例如数据获取、直接 DOM 更新、计时器(如 setTimeout()
)等等。
此 Hook 接受两个参数:回调和依赖项,它们允许您控制何时执行副作用。
注意:第二个参数是可选的。
例子:
import React, { useState, useEffect } from "react";
const App = () => {
const [loading, setLoading] = useState(false);
useEffect(() => {
setLoading(true);
setTimeout(() => {
setLoading(false);
}, 2000);
}, []);
return <div>// ...</div>;
};
export default App;
useMemo Hook 的用途是什么?
useMemo Hook 在函数组件中用于记忆耗资源的函数,以便它们仅在设定的输入更改时调用,而不是每次渲染都调用。
例子:
const result = useMemo(() => expensivesunction(input), [input]);
这类似于 useCallback hook,用于优化你的 React 函数组件的渲染行为。 useMemo 用于记忆耗资源的函数,这样就不必在每次渲染时都调用它们。
什么是 useRefs Hook?
useRefs hook,也称为 References 挂钩,用于存储更新时不需要重新渲染的可变值。它还用于存储对特定 React 元素或组件的引用,这在我们需要 DOM 测量或直接向组件添加方法时很有用。
当我们需要进行以下操作时,我们使用 useRefs:
- 调整焦点,并在文本和媒体播放之间进行选择。
- 使用第三方 DOM 库。
- 启动命令式动画
例子:
import React, { useEffect, useRef } from "react";
const App = () => {
const inputRef = useRef(null);
useEffect(() => {
inputElRef.current.focus();
}, []);
return (
<div>
<input type="text" ref={inputRef} />
</div>
);
};
export default App;
什么是自定义 Hook?
自定义 hook 是您编写的 JavaScript 函数,允许您在多个组件之间共享逻辑,以前的 React 组件并不支持这个功能。
React 中的上下文(Context)是什么?
上下文的目的是为 React 组件树共享“全局”数据,允许数据向下传递,并在不使用 props 的情况下,让 React 应用中任何需要该数据的组件中使用(消费)。它使得组件之间分享数据(状态)更容易。
什么是 React 路由器(Router)?
React router 是 React 应用程序中用于处理路由并允许在各种组件的视图之间导航的标准库。
将这个库安装到你的 React 项目中就像在你的终端中输入以下命令一样简单:
npm install – -save react-router-dom
总结
在本文中,我们回顾了一些 React 面试问题,以帮助您准备面试。 希望您在面试中获得好运和成功。