当应用程序运行在开发模式时,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,
};
以下是 React的 主要优势。
除了优点之外,React 也有一些限制。
错误边界是指在其子组件树的任何地方捕获 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>
React v15 使用 unstable_handleError
方法为错误边界提供了非常基本的支持。在 React v16 中,它已经被重新命名为 componentDidCatch
。
通常我们使用 PropTypes 库(React.PropTypes
从 React v15.5 开始转移到 prop-types
包)来进行 React 应用中的类型检查。对于大型代码库,建议使用静态类型检查器,如 Flow 或 TypeScript,在编译时进行类型检查并提供自动补全功能。
react-dom
包有什么用?react-dom
包提供了 DOM 特定的方法,可以在你的应用程序的顶层使用。大多数组件不需要使用此模块。这个包的一些方法是:
render()
hydrate()
unmountComponentAtNode()
findDOMNode()
createPortal()
react-dom
的 render 方法的目的是什么?此方法用于将 React 元素渲染到提供的容器中的 DOM 中,并返回对组件的引用。如果 React 元素之前已渲染到容器中,它将对其执行更新,并且仅在必要时更改 DOM 以反映最新更改。
ReactDOM.render(element, container[, callback])
如果提供了可选的回调,它将在组件渲染或更新后执行。
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();
});
dangerouslySetInnerHTML
属性是 React 在浏览器 DOM 中使用 innerHTML
的替代品。就像 innerHTML
一样,考虑到跨站点脚本 (XSS) 攻击,使用此属性是有风险的。你只需要传递一个 __html
对象作为键和 HTML 文本作为值。
在这个例子中,MyComponent 使用 dangerouslySetInnerHTML
属性来设置 HTML 标记:
function createMarkup() {
return { __html: 'First · Second' };
}
function MyComponent() {
return <div dangerouslySetInnerHTML={createMarkup()} />;
}