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
目前有助于:
未来的 React 版本将添加更多额外功能。
识别不安全的生命周期
当启用严格模式时,React 会列出使用了不安全生命周期方法的所有 class 组件,并打印一条包含这些组件信息的警告消息,如下所示:
此时解决项目中严格模式所识别出来的问题,会使得在未来的 React 版本中使用异步渲染变得更容易。
关于使用过时字符串 ref API 的警告
React 16.3 新增了第三种选择,它提供了使用字符串 ref 的便利性,并且不存在任何缺点:
class MyComponent extends {
constructor(props) {
super(props);
this.inputRef = React.createRef();
}
render() {
return <input type="text" ref={this.inputRef} />;
}
componentDidMount() {
this.inputRef.current.focus();
}
}
由于对象 ref 主要是为了替换字符串 ref 而添加的,因此严格模式现在会警告使用字符串 ref。
注意:
除了新增加的
createRef
API,回调 ref 依旧适用。你无需替换组件中的回调 ref。它们更灵活,因此仍将作为高级功能保留。
关于使用废弃的 findDOMNode 方法的警告
findDOMNode
也可用于 class 组件,但它违反了抽象原则,它使得父组件需要单独渲染子组件。它会产生重构危险,你不能更改组件的实现细节,因为父组件可能正在访问它的 DOM 节点。findDOMNode
只返回第一个子节点,但是使用 Fragments,组件可以渲染多个 DOM 节点。findDOMNode
是一个只读一次的 API。调用该方法只会返回第一次查询的结果。如果子组件渲染了不同的节点,则无法跟踪此更改。因此,findDOMNode
仅在组件返回单个且不可变的 DOM 节点时才有效。
你也可以在组件中创建一个 DOM 节点的 wrapper,并将 ref 直接绑定到它。
class MyComponent extends {
constructor(props) {
super(props);
this.wrapper = React.createRef();
}
render() {
return <div ref={this.wrapper}>{this.props.children}</div>;
}
}
注意:
检测意外的副作用
从概念上讲,React 分两个阶段工作:
-
渲染 阶段会确定需要进行哪些更改,比如 DOM。在此阶段,React 调用
render
,然后将结果与上次渲染的结果进行比较。 -
提交 阶段发生在当 React 应用变化时。(对于 React DOM 来说,会发生在 React 插入,更新及删除 DOM 节点的时候。)在此阶段,React 还会调用
componentDidMount
和componentDidUpdate
之类的生命周期方法。
提交阶段通常会很快,但渲染过程可能很慢。因此,即将推出的异步模式 (默认情况下未启用) 将渲染工作分解为多个部分,对任务进行暂停和恢复操作以避免阻塞浏览器。这意味着 React 可以在提交之前多次调用渲染阶段生命周期的方法,或者在不提交的情况下调用它们(由于出现错误或更高优先级的任务使其中断)。
渲染阶段的生命周期包括以下 class 组件方法:
constructor
componentWillMount
componentWillReceiveProps
componentWillUpdate
getDerivedStateFromProps
shouldComponentUpdate
render
-
setState
更新函数(第一个参数)
严格模式不能自动检测到你的副作用,但它可以帮助你发现它们,使它们更具确定性。通过故意重复调用以下方法来实现的该操作:
- class 组件的
constructor
方法 -
render
方法 -
setState
更新函数 (第一个参数) - 静态的
getDerivedStateFromProps
生命周期方法
注意:
这仅适用于开发模式。生产模式下生命周期不会被调用两次。
例如,请考虑以下代码:
class TopLevelRoute extends {
constructor(props) {
super(props);
SharedApplicationState.recordEvent('ExampleComponent');
}
}
严格模式采用故意重复调用方法(如组件的构造函数)的方式,使得这种 bug 更容易被发现。
检测过时的 context API
过时的 context API 容易出错,将在未来的主要版本中删除。在所有 16.x 版本中它仍然有效,但在严格模式下,将显示以下警告:
更多angular1/2/4/5、ionic1/2/3、react、vue、微信小程序、nodejs等技术文章、视频教程和开源项目,请关注微信公众号——全栈弄潮儿。
微信公众号