示例使用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環境下不會這樣,所以不用擔心