React 16.13.1使用useState时会执行两次render的问题

lizuncong (lizuncong) · GitHubI am a strong believer in reverse engineering. lizuncong has 43 repositories available. Follow their code on GitHub.https://github.com/lizuncong

示例使用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....都输出了两次。

这个问题产生的原因是啥,可以从Strict Mode – React找到答案

原因:

最近的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环境下不会这样,所以不用担心

  • 8
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值