1. 如何在 React 中对 props 进行验证?
当应用程序运行在开发模式时,React 会自动检查我们在组件上设置的所有 props,以确保它们具有正确的类型。如果类型不正确,React 会在控制台生成警告信息。由于对性能的影响,它在生产模式中被禁用。必需 props 是用 isRequired 定义的。
预定义的 props 类型集合。
- PropTypes.number
- PropTypes.string
- PropTypes.array
- PropTypes.object
- PropTypes.func
- PropTypes.node
- PropTypes.element
- PropTypes.bool
- PropTypes.symbol
- PropTypes.any
我们可以为 User 组件定义 propTypes,如下所示。
import React from 'react';
import PropTypes from 'prop-types';
class User extends React.Component {
static propTypes = {
name: PropTypes.string.isRequired,
age: PropTypes.number.isRequired,
};
render() {
return (
<>
<h1>{`Welcome, ${this.props.name}`}</h1>
<h2>{`Age, ${this.props.age}`}</h2>
</>
);
}
}
注意:在 React v15.5 中,PropTypes 被从 React.PropTypes 移到 prop-types库中。
等效的函数式组件:
import React from 'react';
import PropTypes from 'prop-types';
function User() {
return (
<>
<h1>{`Welcome, ${this.props.name}`}</h1>
<h2>{`Age, ${this.props.age}`}</h2>
</>
);
}
User.propTypes = {
name: PropTypes.string.isRequired,
age: PropTypes.number.isRequired,
};
2. React 的优势是什么?
以下是 React的 主要优势。
- 通过虚拟 DOM 提高应用程序的性能。
- JSX 使代码易于阅读和编写。
- 它在客户端和服务器端都能进行渲染(SSR)。
- 易于与框架(Angular, Backbone)集成,因为它只是一个视图库。
- 使用 Jest 等工具容易编写单元和集成测试。
3. React 的局限性是什么?
除了优点之外,React 也有一些限制。
- React 只是一个视图库,不是一个完整的框架。
- 对于刚接触网络开发的初学者来说,有一个学习曲线。
- 将 React 整合到传统的 MVC 框架中需要一些额外的配置。
- 代码的复杂性随着内联模板和 JSX 的增加而增加。
- 太多的小组件导致了过度工程化或模板化。
4. 什么是 React v16 中的错误边界(Error Boundary)?
错误边界是指在其子组件树的任何地方捕获 JavaScript 错误的组件,记录这些错误,并显示一个后备 UI ,而不是崩溃的组件树。
如果一个类组件定义了一个新的生命周期方法 componentDidCatch(error, info) 或 static getDerivedStateFromError() ,它就成为一个错误边界。
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
componentDidCatch(error, info) {
// 你也可以把错误记录到一个错误报告服务中去
logErrorToMyService(error, info)。
}
static getDerivedStateFromError(error) {
// 更新状态,以便下次渲染时显示回退的用户界面。
return { hasError: true };
}
render() {
if (this.state.hasError) {
// 你可以渲染任何自定义的回退用户界面
return <h1>{'Something went wrong.'}</h1>;
}
return this.props.children。
}
}
之后把它作为一个普通的组件使用。
<ErrorBoundary>
<MyWidget />
</ErrorBoundary>
5. React v15 中是如何处理错误边界的?
React v15 使用 unstable_handleError 方法为错误边界提供了非常基本的支持。在 React v16 中,它已经被重新命名为 componentDidCatch。
6. 静态类型检查的推荐方式是什么?
通常我们使用 PropTypes 库(React.PropTypes 从 React v15.5 开始转移到 prop-types 包)来进行 React 应用中的类型检查。对于大型代码库,建议使用静态类型检查器,如 Flow 或 TypeScript,在编译时进行类型检查并提供自动补全功能。
7. react-dom 包有什么用?
react-dom 包提供了 DOM 特定的方法,可以在你的应用程序的顶层使用。大多数组件不需要使用此模块。这个包的一些方法是:
- render()
- hydrate()
- unmountComponentAtNode()
- findDOMNode()
- createPortal()
8. react-dom 的 render 方法的目的是什么?
此方法用于将 React 元素渲染到提供的容器中的 DOM 中,并返回对组件的引用。如果 React 元素之前已渲染到容器中,它将对其执行更新,并且仅在必要时更改 DOM 以反映最新更改。
ReactDOM.render(element, container[, callback])
如果提供了可选的回调,它将在组件渲染或更新后执行。
9. 什么是 ReactDOMServer?
ReactDOMServer 对象使你能够将组件呈现为静态标记(通常用于节点服务器)。该对象主要用于服务器端渲染(SSR)。以下方法可用于服务器和浏览器环境:
- renderToString()
- renderToStaticMarkup()
例如,你通常运行基于 Node 的 Web 服务器(如 Express、Hapi 或 Koa),然后调用 renderToString 将根组件渲染为字符串,然后将其作为响应发送。
// 使用 Express
import { renderToString } from 'react-dom/server';
import MyPage from './MyPage';
app.get('/', (req, res) => {
res.write('<!DOCTYPE html><html><head><title>My Page</title></head><body>');
res.write('<div id="content">');
res.write(renderToString(<MyPage />));
res.write('</div></body></html>');
res.end();
});
10. 如何在 React 中使用 innerHTML?
dangerouslySetInnerHTML 属性是 React 在浏览器 DOM 中使用 innerHTML 的替代品。就像 innerHTML 一样,考虑到跨站点脚本 (XSS) 攻击,使用此属性是有风险的。你只需要传递一个 __html 对象作为键和 HTML 文本作为值。
在这个例子中,MyComponent 使用 dangerouslySetInnerHTML 属性来设置 HTML 标记:
function createMarkup() {
return { __html: 'First · Second' };
}
function MyComponent() {
return <div dangerouslySetInnerHTML={createMarkup()} />;
}