2018年1月,Brian Vaughn 添加了 。下面是今天如何在你的应用程序中开始使用它:
ReactDOM.render(
,
,
document.getElementById('root'),
)
好吧,那么这是做什么的?来吧,在你的应用程序中试一试,看看会发生什么。别担心,我等着...

发生的事情对每个人来说都是不同的,但这里有一个例子,你们中的一些人可能已经看到了。
Warning: A string ref, "myDiv", has been found within a strict mode tree. String refs are a source of potential bugs and should be avoided. We recommend using createRef() instead.
in StringRef (created by App)
in StrictMode (created by App)
in App
Learn more about using refs safely here:
https://fb.me/react-strict-mode-string-ref
Warning: Unsafe lifecycle methods were found within a strict-mode tree:
in StrictMode (created by App)
in App
componentWillMount: Please update the following components to use componentDidMount instead: WillMount
componentWillReceiveProps: Please update the following components to use static getDerivedStateFromProps instead: WillReceiveProps
componentWillUpdate: Please update the following components to use componentDidUpdate instead: WillUpdate
Learn more about this warning here:
https://fb.me/react-strict-mode-warnings
Warning: Legacy context API has been detected within a strict-mode tree:
in StrictMode (created by App)
in App
Please update the following components: MyColorDiv, MyColorProvider
Learn more about this warning here:
https://fb.me/react-strict-mode-warnings
Warning: findDOMNode is deprecated in StrictMode. findDOMNode was passed an instance of FindDOMNode which is inside StrictMode. Instead, add a ref directly to the element you want to reference.
in div (created by FindDOMNode)
in FindDOMNode (created by App)
in StrictMode (created by App)
in App
Learn more about using refs safely here:
https://fb.me/react-strict-mode-find-node
这是我用来生成这些警告的代码:
import * as React from 'react'
import ReactDOM from 'react-dom'
import PropTypes from 'prop-types'
class WillMount extends React.Component {
componentWillMount() {
// Use componentDidMount instead
}
render() {
return null
}
}
class WillReceiveProps extends React.Component {
componentWillReceiveProps() {
// Use static getDerivedStateFromProps
}
render() {
return null
}
}
class WillUpdate extends React.Component {
componentWillUpdate() {
// Use componentDidUpdate instead
}
render() {
return null
}
}
class StringRef extends React.Component {
render() {
// Use React.createRef instead
return
而你可以在这个codeandbox中自己检查一下。
这些警告中的每一个都有一个可靠的解决方法,将使你的代码在不同方面得到改善(其中大多数与并发模式有关,希望今年晚些时候能进入React)。今天处理好这些警告,将使你在升级到并发反应模式时更容易没有错误。
也就是说,如果你的应用程序中有大量的警告,不要惊慌失措。你的代码将在未来继续工作。对于那些生命周期方法,还有一个UNSAFE_ 的前缀,如果你需要,你可以用它来静音警告。React不会在这里把你留在尘埃里。
React严格模式做的另一件事是运行某些回调/方法两次(仅在DEV模式下)。你没看错!以下回调/方法将在严格模式下运行两次(仅在DEV模式下):
- 类组件
constructor方法 render方法(包括函数组件)setState更新器函数(第一个参数)- 静态的
getDerivedStateFromProps生命周期 React.useState状态初始化器回调函数React.useMemo回调函数
看看这个codeandbox,它在钩子回调和类方法中记录到控制台,向你显示某些事情发生了两次。
React这样做是因为它不能可靠地警告你在这些方法中的副作用。但如果这些方法是empotent的,那么多次调用它们应该不会造成任何麻烦。如果它们不是同位素的,那么你应该注意到一些有趣的事情,希望你能注意到并解决这些问题。
请注意,即使在开发模式+严格模式下,useEffect 和useLayoutEffect 回调也不会被调用两次,因为这些回调的全部意义是为了执行副作用。
请注意,我还观察到,你传递给React.useReducer 的reducer 在开发模式下不会被调用两次。我不确定这是为什么,因为我觉得这也可以从这种警告中受益。
你会注意到,如果你下载我的codeandbox项目中的任何一个,并运行build 脚本(启用生产模式),所有的警告都会消失,回调只被调用一次。这是因为这些只是在开发过程中帮助你,在生产中不会影响你。
在React.StrictMode 中渲染你的应用程序,当一个组件使用了次优的方法或API时,会向你发出警告,它可以帮助你抓住那些可能导致难以调试的错误的东西。但有时违反严格模式的代码并不是你自己的代码,而是一个库中的代码。
那么,当你在第三方组件中得到这样的警告时,你该怎么办?我建议看看对该项目开一个PR会有多容易。如果这样做不成功,那么你可以直接 "vendor"(下载并提交)或 "fork "该依赖性,然后继续前进。
记住,无论你是否使用严格模式和修复警告,你的代码都会继续工作。
我认为许多团队正在采用的一种方法(我也推荐)是,首先用 ,而不是用整个应用程序来包装你的部分应用程序:
function App() {
return (
)
}
你可以在你的应用中的任何地方使用 ,在任何深度。这可能是将你的应用程序的某些部分选择为严格模式的好方法,而不会到处都有大量的警告。
我希望这样做能帮助你在你的React代码库中捕捉到bug!
回头见 💯
阅读更多关于React文档中的严格模式的内容