严格模式(Reatc.StrictMode)
StrictMode是一个用以标记出应用中潜在问题的工具。就是Fragment,StrictMode不会渲染任何真是的UI。它为其后代元素触发额外的检查的警告
注:严格模式检查只在开发模式下运行,不会与生产模式冲突
可以在代码的任何地方启用严格模式。例如:
// 入口文件
React.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById(“root")
)
// 单个组件中
import React from “react”;
function Home(){
return (
<div className=“home”>
<React.StrictMode>
<ComponentTable />
<ComponentDialog />
</React.StrictMode>
<CommonInfo />
</div>
)
}
上述案例中,在入口文件中使用,会对他的所有后代元素都进行检查;在单个组件中使用,会对CommpoentTable和CommonentDialog以及他们的所有后代元素进行检查,不会对CommonInfo组件运行严格模式
使用StrictMode的优点:
- 识别不安全的声明周期组件
- 有关旧式字符串ref用法的警告
- 关于使用废弃的findDOMMode方法的警告
- 检测意外的副作用
- 检测过时的context API
生命周期警告
过时的组件生命周期往往会带来不安全的编码实践,具体函数如下:
- componentWillMount
- componentWillReceiveProps
- componentWillUpdate
16.3:为不安全的生命周期引入别名
- UNSAFE_componentWillMount
- UNSAFE_componentWillReceiveProps
- UNSAFE_componentWillUpdate
1、componentWillMount (旧的名称正常使用)
2、componentWillReceiveProps(旧的名称正常使用)
3、componentWillUpdate(旧的名称正常使用)
16.3<16.x<17.0
- UNSAFE_componentWillMount
- UNSAFE_componentWillReceiveProps
- UNSAFE_componentWillUpdate
1、componentWillMount (旧的名称在开发模式下会产生一个警告)
2、componentWillReceiveProps(旧的名称在开发模式下会产生一个警告)
3、componentWillUpdate(旧的名称在开发模式下会产生一个警告)
17.0 只有新的 “UNSAFE_” 生命周期名称可以使用
- UNSAFE_componentWillMount
- UNSAFE_componentWillReceiveProps
- UNSAFE_componentWillUpdate
1、componentWillMount (已经删除不能使用)
2、componentWillReceiveProps (已经删除不能使用)
3、componentWillUpdate (已经删除不能使用)
当启用严格模式时,React 会列出使用了不安全生命周期方法的所有 class 组件,并打印一条包含这些组件信息的警告消息,如下所示:
ref API 的警告
React 提供了两种方法管理 refs 的方式:已过时的字符串 ref API 的形式及回调函数 API 的形式。尽管字符串 ref API 在两者中使用更方便,但是它有一些缺点,因此官方推荐采用回调的方式。
你可能了解过之前的 API 中的 string 类型的 ref 属性,例如 “textInput”。你可以通过 this.refs.textInput 来访问 DOM 节点。
class MyComponent extends React.Component {
render() {
return <input type="text" ref="textInput" />;
}
componentDidMount() {
this.refs.textInput.focus();
}
}
React 16.3 新增了第三种选择,它提供了使用字符串 ref 的便利性,并且不存在任何缺点。
检测副作用
渲染阶段的生命周期包括以下 class 组件方法:
- constructor
- componentWillMount (or UNSAFE_componentWillMount)
- componentWillReceiveProps (or UNSAFE_componentWillReceiveProps)
- componentWillUpdate (or UNSAFE_componentWillUpdate)
- getDerivedStateFromProps shouldComponentUpdate render setState
更新函数(第一个参数)
因为上述方法可能会被多次调用,所以不要在它们内部编写副作用相关的代码,这点非常重要。忽略此规则可能会导致各种问题的产生,包括内存泄漏和或出现无效的应用程序状态。不幸的是,这些问题很难被发现,因为它们通常具有非确定性。
严格模式不能自动检测到你的副作用,但它可以帮助你发现它们,使它们更具确定性。通过故意重复调用以下函数来实现的该操作:
- class 组件的 constructor,render 以及 shouldComponentUpdate 方法
- class组件的生命周期方法 getDerivedStateFromProps
- 函数组件体
- 状态更新函数 (即 setState 的第一个参数)
- 函数组件通过使用 useState,useMemo 或者 useReducer
context API 警告
过时的 context API 容易出错,将在未来的主要版本中删除。在所有 16.x 版本中它仍然有效,但在严格模式下,将显示以下警告:
旧版本的使用
import React, { Component } from 'react';
import PropTypes from 'prop-types';
class App extends Component {
static childContextTypes = {
theme: PropTypes.string
}
getChildContext () {
return {
theme: 'dark'
}
}
render() {
return (
<Toolbar />
);
}
}
function Toolbar (props) {
return (
<div>
<ThemedButton />
</div>
)
}
class ThemedButton extends Component {
static contextTypes = {
theme: PropTypes.string
}
render() {
return (
<button>{this.context.theme}</button>
);
}
}
export default App;
新版本的使用
import React, { Component } from 'react';
const ThemeContext = React.createContext('light');
class App extends Component {
render() {
return (
<ThemeContext.Provider value="dark">
<Toolbar />
</ThemeContext.Provider>
);
}
}
function Toolbar (props) {
return (
<div>
<ThemedButton />
</div>
)
}
class ThemedButton extends Component {
static contextType = ThemeContext
render() {
return (
<button>{this.context}</button>
);
}
}
export default App;