示例使用typescript编写一个简单的hello
新建一个Hello.tsx组件:
import React, {useState} from 'react'
interface IHelloProps {
message?: string;
}
const Hello: React.FC<IHelloProps> = (props) => {
console.log('hello before render....')
return (
<h2>
{props.message}
</h2>
)
}
export default Hello
Hello.defaultProps = {
message: 'what the fuck'
}
观察控制台输出,会发现,hello before render....只输出一次。
继续往hello组件中添加count状态
import React, {useState} from 'react'
interface IHelloProps {
message?: string;
}
const Hello: React.FC<IHelloProps> = (props) => {
const [count, setCount] = useState(0)
console.log('hello before render....')
return (
<h2>
{props.message}
<div>点击次数{count}</div>
</h2>
)
}
export default Hello
Hello.defaultProps = {
message: 'what the fuck'
}
观察控制台输出,会发现hello before render....输出了两次,
继续往hello添加点击事件:
import React, {useState} from 'react'
interface IHelloProps {
message?: string;
}
const Hello: React.FC<IHelloProps> = (props) => {
const [count, setCount] = useState(0)
console.log('hello before render....')
return (
<h2>
{props.message}
<div
onClick={() => {
setCount(count + 1)
}}
>
点击次数{count}
</div>
</h2>
)
}
export default Hello
Hello.defaultProps = {
message: 'what the fuck'
}
观察控制台输出,会发现初始化的时候,hello before render....执行了两次,每次点击的时候,hello before render....都输出了两次。
这个问题产生的原因是啥,可以从https://reactjs.org/docs/strict-mode.html#detecting-unexpected-side-effects找到答案
原因:
最近的react版本,dev模式下render使用的是strict mode,strict mode的通过两次调用constructor和render函数来更好的检测不符合预期的side effects
文档中有表明
Strict mode can’t automatically detect side effects for you, but it can help you spot them by making them a little more deterministic. This is done by intentionally double-invoking the following functions:
- Class component constructor, render, and shouldComponentUpdate methods
- Class component static getDerivedStateFromProps method
- Function component bodies
- State updater functions (the first argument to setState)
- Functions passed to useState, useMemo, or useReducer
下列函数会执行两次
- 类组件的constructor,render和shouldComponentUpdate方法
- 类组建的静态方法getDerivedStateFromProps
- 函数组件方法体
- 状态更新函数(setState的第一个参数)
- 传入useState,useMemo或useReducer的函数
在production环境下不会这样,所以不用担心