2022必备react面试题 附答案
React视频讲解 点击学习
1. React的严格模式如何使用,有什么用处?
StrictMode
是一个用来突出显示应用程序中潜在问题的工具。与 Fragment
一样,StrictMode
不会渲染任何可见的 UI。它为其后代元素触发额外的检查和警告。 可以为应用程序的任何部分启用严格模式。例如:
import React from 'react';
function ExampleApplication() {
return (
);
}
复制代码
在上述的示例中,不会对 Header
和 Footer
组件运行严格模式检查。但是,ComponentOne
和 ComponentTwo
以及它们的所有后代元素都将进行检查。
StrictMode
目前有助于:
- 识别不安全的生命周期
- 关于使用过时字符串 ref API 的警告
- 关于使用废弃的 findDOMNode 方法的警告
- 检测意外的副作用
- 检测过时的 context API
2. 在React中遍历的方法有哪些?
(1)遍历数组:map && forEach
import React from 'react';
class App extends React.Component {
render() {
let arr = ['a', 'b', 'c', 'd'];
return (
{
arr.map((item, index) => {
return - {item}
})
}
)
}
}
class App extends React.Component {
render() {
let arr = ['a', 'b', 'c', 'd'];
return (
{
arr.forEach((item, index) => {
return - {item}
})
}
)
}
}
复制代码
(2)遍历对象:map && for in
class App extends React.Component {
render() {
let obj = {
a: 1,
b: 2,
c: 3
}
return (
{
(() => {
let domArr = [];
for(const key in obj) {
if(obj.hasOwnProperty(key)) {
const value = obj[key]
domArr.push(- {value}
)
}
}
return domArr;
})()
}
)
}
}
// Object.entries() 把对象转换成数组
class App extends React.Component {
render() {
let obj = {
a: 1,
b: 2,
c: 3
}
return (
{
Object.entries(obj).map(([key, value], index) => { // item是一个数组,把item解构,写法是[key, value]
return - {value}
})
}
)
}
}
3. 在React中页面重新加载时怎样保留数据?
这个问题就设计到了数据持久化, 主要的实现方式有以下几种:
- Redux: 将页面的数据存储在redux中,在重新加载页面时,获取Redux中的数据;
- data.js: 使用webpack构建的项目,可以建一个文件,data.js,将数据保存data.js中,跳转页面后获取;
- sessionStorge: 在进入选择地址页面之前,componentWillUnMount的时候,将数据存储到sessionStorage中,每次进入页面判断sessionStorage中有没有存储的那个值,有,则读取渲染数据;没有,则说明数据是初始化的状态。返回或进入除了选择地址以外的页面,清掉存储的sessionStorage,保证下次进入是初始化的数据
- history API: History API 的
pushState
函数可以给历史记录关联一个任意的可序列化state
,所以可以在路由push
的时候将当前页面的一些信息存到state
中,下次返回到这个页面的时候就能从state
里面取出离开前的数据重新渲染。react-router 直接可以支持。这个方法适合一些需要临时存储的场景。
4. React必须使用JSX吗?
React 并不强制要求使用 JSX。当不想在构建环境中配置有关 JSX 编译时,不在 React 中使用 JSX 会更加方便。
每个 JSX 元素只是调用 React.createElement(component, props, ...children)
的语法糖。因此,使用 JSX 可以完成的任何事情都可以通过纯 JavaScript 完成。
例如,用 JSX 编写的代码:
class Hello extends React.Component {
render() {
return Hello {this.props.toWhat};
}
}
ReactDOM.render(
,
document.getElementById('root')
);
复制代码
可以编写为不使用 JSX 的代码:
class Hello extends React.Component {
render() {
return React.createElement('div', null, `Hello ${this.props.toWhat}`);
}
}
ReactDOM.render(
React.createElement(Hello, {toWhat: 'World'}, null),
document.getElementById('root')
);
5.为什么使用jsx的组件中没有看到使用react却需要引入react?
本质上来说JSX是React.createElement(component, props, ...children)
方法的语法糖。在React 17之前,如果使用了JSX,其实就是在使用React, babel
会把组件转换为 CreateElement
形式。在React 17之后,就不再需要引入,因为 babel
已经可以帮我们自动引入react。
5. 在React中怎么使用async/await?
async/await是ES7标准中的新特性。如果是使用React官方的脚手架创建的项目,就可以直接使用。如果是在自己搭建的webpack配置的项目中使用,可能会遇到 regeneratorRuntime is not defined 的异常错误。那么我们就需要引入babel,并在babel中配置使用async/await。可以利用babel的 transform-async-to-module-method 插件来转换其成为浏览器支持的语法,虽然没有性能的提升,但对于代码编写体验要更好。
6. React.Children.map和js的map有什么区别?
JavaScript中的map不会对为null或者undefined的数据进行处理,而React.Children.map中的map可以处理React.Children为null或者undefined的情况。
7. React 中的高阶组件运用了什么设计模式?
使用了装饰模式,高阶组件的运用:
function withWindowWidth(BaseComponent) {
class DerivedClass extends React.Component {
state = {
windowWidth: window.innerWidth,
}
onResize = () => {
this.setState({
windowWidth: window.innerWidth,
})
}
componentDidMount() {
window.addEventListener('resize', this.onResize)
}
componentWillUnmount() {
window.removeEventListener('resize', this.onResize);
}
render() {
return
}
}
return DerivedClass;
}
const MyComponent = (props) => {
return Window width is: {props.windowWidth}
};
export default withWindowWidth(MyComponent);
复制代码
装饰模式的特点是不需要改变 被装饰对象 本身,而只是在外面套一个外壳接口。JavaScript 目前已经有了原生装饰器的提案,其用法如下:
@testable
class MyTestableClass {
}
8. 类组件和函数组件有何不同?
解答
在 React 16.8版本(引入钩子)之前,使用基于类的组件来创建需要维护内部状态或利用生命周期方法的组件(即componentDidMount
和shouldComponentUpdate
)。基于类的组件是 ES6 类,它扩展了 React 的 Component 类,并且至少实现了render()
方法。
类组件:
class Welcome extends React.Component {
render() {
return Hello, {this.props.name}
;
}
}
复制代码
函数组件是无状态的(同样,小于 React 16.8版本),并返回要呈现的输出。它们渲染 UI 的首选只依赖于属性,因为它们比基于类的组件更简单、更具性能。
函数组件:
function Welcome(props) {
return Hello, {props.name}
;
}
复制代码
注意:在 React 16.8版本中引入钩子意味着这些区别不再适用(请参阅14和15题)。
进一步阅读
9. React 中 keys 的作用是什么?
Keys 是 React 用于追踪哪些列表中元素被修改、被添加或者被移除的辅助标识。
在 React 中渲染集合时,向每个重复的元素添加关键字对于帮助React跟踪元素与数据之间的关联非常重要。key 应该是唯一ID,最好是 UUID 或收集项中的其他唯一字符串:
{todos.map((todo) =>
-
{todo.text}
)};
复制代码
在集合中添加和删除项目时,不使用键或将索引用作键会导致奇怪的行为。
进一步阅读
10. 为什么调用 setState 而不是直接改变 state?
解答
如果您尝试直接改变组件的状态,React 将无法得知它需要重新渲染组件。通过使用setState()
方法,React 可以更新组件的UI。
另外,您还可以谈谈如何不保证状态更新是同步的。如果需要基于另一个状态(或属性)更新组件的状态,请向setState()
传递一个函数,该函数将 state 和 props 作为其两个参数:
this.setState((state, props) => ({
counter: state.counter + props.increment
}));
复制代码
进一步阅读