为啥我的反应组件在初始加载时渲染两次?

Posted

技术标签:

【中文标题】为啥我的反应组件在初始加载时渲染两次?【英文标题】:Why is my react component rendering twice on initial load? [duplicate]为什么我的反应组件在初始加载时渲染两次? 【发布时间】:2020-10-01 01:58:37 【问题描述】:

我有一个名为 (First) 的功能组件

function First() 
    const [count,setCount]=useState(0)

    console.log("component first rendering") // this logging is happening twice


    return (
        <div>
            first component
        </div>
    )

当我最初运行应用程序时,console 语句记录了两次,这是为什么,它应该只记录一次,因为我没有明确更新状态。

【问题讨论】:

你能在你使用这个组件的地方显示你的父组件代码吗? 它在我的主要应用程序组件中 也许 React.StrictMode 在某处被使用了。 它是什么,你能解释一下,如果我删除 useState 它只呈现一次,它是 useState 吗。 【参考方案1】:

我已经在代码沙箱here 中尝试过了,果然,它确实渲染了两次。这是因为,在index.js 文件中,它使用了React.StrictMode

据此documentation:

严格模式无法自动为您检测副作用,但可以通过使它们更具确定性来帮助您发现它们。这是通过有意双重调用以下函数来完成的:

类组件构造函数、渲染和 shouldComponentUpdate 方法

传递给 useState、useMemo 或 useReducer 的函数

这通常仅用于帮助发现开发环境中的副作用。它不适用于生产环境。

所以如果你不想让它渲染两次,只需删除index.js文件中的&lt;React.StrictMode&gt; &lt;/ React.StrictMode&gt;就可以正常工作了。

希望对你有帮助:)

【讨论】:

如果我删除它只呈现一次的useState,是否有useState钩子 不,useState() 没有任何问题。只是在开发环境中,当你使用React.StrictMode时,总是会调用两次useState。我已经展示了沙箱中的代码示例。只需在 index.js 文件中删除React.StrictMode,它只会被调用一次。 你是说在React.StrictMode中调用useState两次,但是两次调用useState与再次渲染组件有什么关系 它不仅会调用useState,还会将整个组件渲染两次。 严格模式无法自动为您检测副作用,但可以通过使它们更具确定性来帮助您发现它们。这是通过故意双重调用以下函数来完成的:我不明白这一行的含义是什么副作用,请您解释一下,【参考方案2】:

发生这种情况是因为您的应用被包裹在 React.StrictMode 下。

<React.StrictMode>
<First />
</React.StrictMode>

在 React 16.* 中为功能组件引入了严格模式。我们将组件包装在React.StrictMode 下,以识别应用程序中的潜在错误。

StrictMode 有助于维持大型代码库的稳定性,并有助于升级到更新版本的 React。 StrictMode 在控制台中记录我们的应用程序可能遇到的问题:

React.StrictMode 需要触发一些方法和生命周期钩子两次来解决这些问题:

    这些方法可能会被多次调用并且可能会产生副作用,因此 React.StrictMode 会触发这些方法两次以检查任何副作用。如果有任何副作用,将记录错误。 (副作用:在方法/组件之外更新的东西)

    构造函数 componentWillMount(或 UNSAFE_componentWillMount) componentWillReceiveProps(或 UNSAFE_componentWillReceiveProps) componentWillUpdate(或 UNSAFE_componentWillUpdate) getDerivedStateFromProps 应该组件更新 渲染 setState 更新函数(第一个参数)

    我们可能正在使用一些旧的 React 方法和 API,因此 React.StrictMode 会识别出这一点并将错误记录到控制台中,并指出该方法已过时。

    React.StrictMode 仅适用于开发模式,因此无需担心生产。

结论: React.StrictMode 由 React 社区提供,以帮助我们的应用程序跟踪更改,我们可以轻松地将应用程序升级到新版本。

【讨论】:

我无法理解这一行(副作用:在方法/组件之外更新的内容)。可以举个例子吗 您可以将副作用视为任何修改函数之外的内容的东西。简单的例子是,假设一个函数更新了一个全局变量,或者更新了缓存,这些都是副作用。在存在副作用的情况下,组件的行为取决于执行历史。所以,总是更喜欢 react 中的纯函数(假设输入产生相同的输出)。

以上是关于为啥我的反应组件在初始加载时渲染两次?的主要内容,如果未能解决你的问题,请参考以下文章

为啥反应上下文提供程序组件呈现两次[重复]

为啥渲染方法在类组件中运行两次而没有包含任何状态?

为啥我的组件在使用 React 的 Context API 和 useEffect 挂钩时会渲染两次?

导航到该组件后反应功能组件渲染两次,但是在尝试刷新时,仅渲染一次

构造函数和渲染方法在反应组件中运行两次

为啥 useState 会导致组件在每次更新时渲染两次?