2022 必备 react 面试题 附答案
React 视频解说 点击学习
1. React 的严格模式如何应用,有什么用途?
StrictMode
是一个用来突出显示应用程序中潜在问题的工具。与 Fragment
一样,StrictMode
不会渲染任何可见的 UI。它为其后辈元素触发额定的检查和正告。能够为应用程序的任何局部启用严格模式。例如:
import React from 'react';
function ExampleApplication() {
return (
<div>
<Header />
<React.StrictMode>
<div>
<ComponentOne />
<ComponentTwo />
</div>
</React.StrictMode>
<Footer />
</div>
);
}
复制代码
在上述的示例中,不会对 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 (
<ul>
{arr.map((item, index) => {return <li key={index}>{item}</li>
})
}
</ul>
)
}
}
class App extends React.Component {render() {let arr = ['a', 'b', 'c', 'd'];
return (
<ul>
{arr.forEach((item, index) => {return <li key={index}>{item}</li>
})
}
</ul>
)
}
}
复制代码
(2)遍历对象:map && for in
class App extends React.Component {render() {
let obj = {
a: 1,
b: 2,
c: 3
}
return (
<ul>
{(() => {let domArr = [];
for(const key in obj) {if(obj.hasOwnProperty(key)) {const value = obj[key]
domArr.push(<li key={key}>{value}</li>)
}
}
return domArr;
})()}
</ul>
)
}
}
// Object.entries() 把对象转换成数组
class App extends React.Component {render() {
let obj = {
a: 1,
b: 2,
c: 3
}
return (
<ul>
{Object.entries(obj).map(([key, value], index) => {// item 是一个数组,把 item 解构,写法是[key, value]
return <li key={key}>{value}</li>
})
}
</ul>
)
}
}
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 <div>Hello {this.props.toWhat}</div>;
}
}
ReactDOM.render(
<Hello toWhat="World" />,
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 <BaseComponent {...this.props} {...this.state}/>
}
}
return DerivedClass;
}
const MyComponent = (props) => {return <div>Window width is: {props.windowWidth}</div>
};
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 <h1>Hello, {this.props.name}</h1>;
}
}
复制代码
函数组件是无状态的(同样,小于 React 16.8 版本),并返回要出现的输入。它们渲染 UI 的首选只依赖于属性,因为它们比基于类的组件更简略、更具性能。
函数组件:
function Welcome(props) {return <h1>Hello, {props.name}</h1>;
}
复制代码
留神:在 React 16.8 版本中引入钩子意味着这些区别不再实用(请参阅 14 和 15 题)。
进一步浏览
- React 中比照函数式组件和类组件
- React 中函数与类组件比对
9. React 中 keys 的作用是什么?
Keys 是 React 用于追踪哪些列表中元素被批改、被增加或者被移除的辅助标识。
在 React 中渲染汇合时,向每个反复的元素增加关键字对于帮忙 React 跟踪元素与数据之间的关联十分重要。key 应该是惟一 ID,最好是 UUID 或收集项中的其余惟一字符串:
<ul>
{todos.map((todo) =>
<li key={todo.id}>
{todo.text}
</li>
)};
</ul>
复制代码
在汇合中增加和删除我的项目时,不应用键或将索引用作键会导致奇怪的行为。
进一步浏览
- 列表 & key
- React 中 key 属性
10. 为什么调用 setState 而不是间接扭转 state?
解答
如果您尝试间接扭转组件的状态,React 将无奈得悉它须要从新渲染组件。通过应用 setState()
办法,React 能够更新组件的 UI。
另外,您还能够谈谈如何不保障状态更新是同步的。如果须要基于另一个状态(或属性)更新组件的状态,请向 setState()
传递一个函数,该函数将 state 和 props 作为其两个参数:
this.setState((state, props) => ({counter: state.counter + props.increment}));
复制代码
进一步浏览
- 正确地应用 State