reactjs - 为什么全局变量在 React 中执行两次
问题描述
我是前端开发和学习 React 的新手。现在我正在尝试构建一个 hello-world 项目。
执行后npx create-react-app myapp
,我得到了一个初始的 React 项目,我只是在文件中编码App.js
。
import React, {useState} from 'react';
var counter = 0;
function App() {
const [counter2, setCount] = useState(0);
const increment = () => {
setCount(counter2 + 1);
};
return(
<div>
<button onClick= {increment}>Increment</button>
<h1>{counter++}</h1> // 1, 3, 5, 7... WHY???
<h1>{counter2}</h1> // 0, 1, 2, 3...
</div>
);
}
export default App;
执行后npm start
,我得到了我的索引页,它包含三个部分:一个按钮和两个数字。
令我惊讶的是,当我单击按钮时,counter2
按预期增加,但counter
增加了两倍。这意味着继续单击该按钮会给我以下结果:
1 0
, 3 1
, 5 2
...
为什么全局变量是counter
二加二,而不是一一增加?
此外,React State 和通用全局变量有什么区别?
解决方案
当您将组件包装在 中时<React.StrictMode>
,它将运行某些函数两次,其中之一是您的功能组件的函数体:
这是通过有意双重调用以下函数来完成的:
... 功能组件体
-反应文档
这仅在开发模式下完成,这样做的目的是帮助您捕捉项目中的副作用。
看起来你的组件似乎只执行一次,因为console.log()
在你的功能组件内部放置一个状态更改只会运行一次。这是因为,从 React 17 开始,他们已经更新了 console.log 方法以不登录您的函数的第二次调用:
从 React 17 开始,React 会自动修改 console.log() 等控制台方法,以在对生命周期函数的第二次调用中静默日志
-反应文档
但是,可以通过保存对该console.log
方法的引用并使用它来执行日志来解决此问题。这样做可以让你看到你的组件被执行了两次:
const log = console.log;
function App() {
const [counter2, setCount] = useState(0);
const increment = () => {
setCount(counter2 + 1);
};
log("Rendering, counter is:", counter);
return(
<div>
<button onClick= {increment}>Increment</button>
<h1>{counter++}</h1>
<h1>{counter2}</h1>
</div>
);
}
上面会在组件挂载时输出如下内容,说明函数体运行了两次:
Rendering, counter is: 0
Rendering, counter is: 1
如果你移除<React.StrictMode>
组件,那么每次渲染计数器都会增加一个,因为 React 将不再重复调用你的函数式组件体,并且你的组件体只会被调用一次:
ReactDOM.render(<App />, document.getElementById('root'));
在全局变量与状态方面,主要区别已在上面的评论中指出。也就是说,当您使用 更新您的状态时setMethodName()
,您将导致您的组件主体重新呈现,当您更新普通变量时不会发生这种情况,因为 React 不会知道对其所做的更改。
推荐阅读
- c# - ASP.NET Core 3.1 + Open ID Connect + AD 不会将 id 令牌持久化到 User.Identity
- python - Pythonpipbuilder:解决依赖关系 - 列表索引超出范围
- ios - 取消隐藏 iPad 上的导航视图
- spring-boot - 六边形架构中的层
- python - Pandas 或 python,遍历数据框中列中的 SQL 查询,将结果附加到数据框中
- amazon-cognito - 是否可以创建一个信任,允许来自 cognito 的联合用户根据自定义属性担任角色?
- flutter - 带有特殊字符 FLUTTER 的 HIVE openBox 问题
- javascript - 输入框的简单赋值返回 NaN
- node.js - 使用 SQL Server 处理多对多对一关系 - 分配数据的配置文件
- youtube - 访问 Youtube URL 时自动暂停