保留对 React 状态变量的“引用”

2024-06-03

据我所知,Javascript 中没有指针。

我有以下问题,但我想知道是否有一个解决方案让我无法解决。解决方案可能是普通的 Javascript,或者像 Context API 这样的 React.js 钩子(useContext),或者更多 Javascript 和 React 的组合,或者解决方案可能是我回到绘图板。

请记住,我将 React.js 引入到在前几年的开发中使用 jQuery 的前端。我的真实情况实际上是一个多表单向导组件,它使用 jQuery 进行下一个/上一个步进和动画。

请不要认为我实际上是在尝试将 jQuery 与 React.js 混合在一起,只是做类似的事情:$('#myBtn').click在 jQuery 中。

我的软件中的实际事件不是“trackMe 更改事件”,因此 useEffect 在这里无济于事。该软件是一个多形式的向导,实际事件是上一个/下一个按钮按下,回调需要知道trackMe的当前值。

这是一个简单的 React 功能组件,演示了我的问题:

import React, { useState } from 'react';
import ReactDOM from 'react-dom';

function App() {
    const [trackMe, setTrackMe] = useState('INIT');

    useEffect(() => {
        console.log('trackMe change', trackMe);
    },[trackMe]);

    const handleOnChange = (e) => {
        setTrackMe(e.target.value);
    };

    const startEvent = () => {
        var trackMeVar = trackMe;
        setTimeout(() => {
            console.log('event complete, callback called');
            console.log('value of trackMe: ', trackMe); //always INIT even though state is changing
            console.log('value of trackMeVar: ', trackMeVar); //always INIT even though state is changing
        }, 1000);
    };

    function init() {
        console.log('init');
        $('#myBtn').click(function (e) {
            e.preventDefault();
            setTimeout(startEvent, 1000);
        });
    }

    window.onload = init;

    return (
        <div>
            <input className="form-control" type="text" name="trackme"
                onChange={e => handleOnChange(e)} value={trackMe} />
            <button type="button" id="myBtn">Start Event</button>
        </div>
    )
}

ReactDOM.render(<App />, document.getElementById('root'))

问题是我的回调startEvent有自己的范围版本trackMe状态变量而不是外部范围最新更新的值,状态更改后,在handleOnChange功能。

要查看实际效果,只需在文本框中输入内容,状态就会发生变化。按“开始活动”按钮即可看到trackMe在事件回调中始终是其初始值“INIT”。

我相信我的问题答案的核心是我是否可以重写我的事件回调函数,以便该函数包含我的状态变量的最新值trackMe.


您可以保留以下值trackMe in a ref https://reactjs.org/docs/hooks-faq.html#is-there-something-like-instance-variables,并从中读取:

function App() {
  const [trackMe, setTrackMe] = useState('INIT');
  const track = useRef('INIT');

  const handleOnChange = (e) => {
      console.log('trackMe before:', trackMe);
      setTrackMe(e.target.value);
      track.current = e.target.value // Sync the state value with the ref's current property
  };

  const startEvent = () => {
      setTimeout(() => {
          console.log('event complete, callback called');
          console.log('value of trackMe: ', track.current); // Read current value in the timeout callback
      }, 1000);
  };

  return (
      <div>
          <input className="form-control" type="text" name="trackme"
              onChange={e => handleOnChange(e)} value={trackMe} />
          <button type="button" onClick={() => setTimeout(startEvent, 1000)} id="myBtn">Start Event</button>
      </div>
  )
}

Demo https://codesandbox.io/s/react-codesandbox-re73w

Source https://reactjs.org/docs/hooks-faq.html#why-am-i-seeing-stale-props-or-state-inside-my-function

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

保留对 React 状态变量的“引用” 的相关文章

  • Google Closure 和生成的 getter/setter

    我正在尝试让 KineticJS 与 Google Closure Compiler 一起使用 然而 KineticJS 根据变量的名称生成它的 getter 和 setter 像这样的事情 add getter and setter me
  • HTML5 Canvas - 在画布上绘图、保存上下文并稍后恢复

    要求 现在 在画布上绘制 然后点击 保存 存储画布状态 离线绘制 但不作为图像 稍后 打开画布并显示之前保存的绘图 然后继续再次绘制 对于绘图 我们通常使用如下代码 canvas document getElementById can ct
  • 范围滑块 javascript 以小时和分钟为单位

    我试图分别以小时和分钟为单位显示滑块的值 我对 JS 还很陌生 并且仍在尝试了解它是如何工作的 到目前为止 我所拥有的是一个工作滑块 其最大值为 1440 24 小时内的分钟 在 JS 中 我尝试将其划分为小时和分钟 并使用 innerHt
  • 如果用户禁用了 javascript,如何回退到完全不同的索引页面?

    我有一个大型 动态生成的单页网站 该网站严重依赖 javascript 我想为没有 javascript 的人提供后备 每个版本必须有不同的 php 代码 所以基本上我需要一个完全不同的索引页面 我不想将所有内容都包装在 javascrip
  • 如何使用 JavaScript 获取光标下的单词?

    如果我有 p some long text p 在我的 HTML 页面上 我如何知道鼠标光标位于 文本 一词上方 我的另一个答案仅适用于 Firefox 这个答案适用于 Chrome 也许在 Firefox 中也能工作 我不知道 funct
  • 系统js语法错误,IE11

    我有一个 Angular 2 应用程序可以在 Firefox 和 Chrome 中工作 但在 IE 中却没有那么多工作 根据我的堆栈跟踪 我的 System js 设置似乎存在问题 这是我在网络控制台中看到的错误描述 Error Syste
  • 错误:捆绑失败:TypeError:无法读取未定义的属性“transformFile”,React Native

    每当我运行react native start时 我都会收到此错误 但是最近在我在节点模块中安装了firebase tools和stripe之后 这种情况开始发生 但在此之前它会运行得很好 这也是错误的堆栈跟踪 ffff 127 0 0 1
  • Karma Webpack - 错误:找不到模块“./test/utilities.js”

    我正在使用 Karma Webpack 进行项目的单元测试 当我跑步时karma start 我有这个错误 Error Cannot find module test utilities js at myproject test campa
  • 将 Babel 与单个输出文件和 ES6 模块一起使用

    这是我的 gulp 任务 将 ES6 代码编译成单个 ES5 文件 我使用类和模块 import export 在 ES6 中 gulp src paths scripts pipe sourcemaps init pipe babel p
  • JSON 解析错误 - JSON 中位置 1 处出现意外标记 o

    我需要获取一个 JSON 对象并记录标题控制台以实现自动完成功能 我的 json 的示例如下 title Example 1 url http www example1 com title Example 2 url http www ex
  • 闭包和异步 Node.js 函数

    All 尝试了解 Node js 上下文中的闭包 异步调用 我有以下代码 timer setInterval pollOID 1000 function pollOID for channel in channels session get
  • 如何在反应路由器的登录页面中隐藏导航栏

    我想隐藏登录页面中的导航栏 我确实做到了 但我在其他页面上看不到导航栏 此代码是 My App jsx 文件的一部分 我在 App 的状态中创造了历史 当路径名是 或 login 时 我会隐藏导航栏 有用 但随后我输入了 ID 和密码 然后
  • Django 管理中的自定义依赖下拉菜单

    我有一个按阶段模型的项目外键 我很难在 Django 管理页面中创建依赖的下拉列表 我想当用户从该项目的 项目下拉 阶段选择一个项目时 在第二个下拉菜单中显示 实现这一目标的最佳方法是什么 如果下拉列表根据其父级的值来过滤项目 那就太好了
  • Redux 形式:REGISTER_FIELD / UNREGISTER_FIELD 在更改或焦点事件后被调用

    我正在使用 Redux Form 在 React 应用程序中渲染和处理表单事件 使用以下东西 初始值 场数组 不可变 js 材质用户界面 此外 字段数组是使用初始值构建的 export default connect state gt re
  • Firebase 停止监听 onAuthStateChanged

    从版本 3 0 0 开始 我很难删除身份验证状态更改侦听器 要根据文档启动侦听器 firebase auth onAuthStateChanged function user handle it 但是 我在文档中找不到任何涉及删除身份验证状
  • 我怎么知道我的组件用在哪里?

    我目前正在开发一个相当大的react js 系统 项目 其中有很多重用的组件 并且没有任何单元测试或文档 当我针对一个特定用例更改 修复 其中一个组件以及在组件发生故障时我不知道的其他 3 个位置时 我的担忧就开始了 如果有一些工具告诉我
  • 带搜索框的 D3 图表

    我在 D3 中创建了一个图表 其中节点显示特定个人创建文档的时间 该图表还显示了一个搜索框 该搜索框根据搜索框输入是否与与该文档关联的单词匹配而将节点变成红色 这些单词列在数据集的第 5 列中 请参阅下面的数据集 我的问题 一旦将搜索输入到
  • jQuery 分钟和秒倒计时器

    我想创建一个 jquery 倒计时器 我尝试了以下代码 但它不起作用 我该怎么办 DEMO https jsfiddle net tbosn210 https jsfiddle net tbosn210 var interval setIn
  • 将 html

    我有一些服务器端代码当前支持 http 字节范围请求 没有任何问题 但是 我希望能够在将转码后的块发送到客户端之前使用 ffmpeg 即时转码视频文件 位于磁盘上 但 ffmpeg 要求我在获取字节时给它一个寻道时间范围来自客户 给定客户端
  • 什么是标志变量?

    最近我遇到了标志变量 但我不知道它们的作用 我不太确定何时使用标志变量以及如何使用它 我用 Google 搜索了它 但没有任何与我的上下文 JavaScript 相关的具体示例 标记变量的定义和使用 http www javascriptk

随机推荐

  • 使用 MVC5、Ajax、C# 和 MSSQL Server 级联 DropdownList

    我对来自 Windows 窗体和三层架构的 MVC 非常陌生 我试图找出使用从数据库填充的级联下拉列表 DDL 我使用 MS SQL Server 2012 VS 2013 目前我正在研究用户调查问卷 用户可以从 DDL 的多个答案中进行选
  • 实现 PHP 单例:静态类属性还是静态方法变量?

    所以 我总是像这样实现一个单例 class Singleton private static instance null public static function getInstance if self instance null se
  • 如何使用批处理文件将多个命令插入到批处理文件中

    我正在制作一个批处理文件 我们称之为 Create bat 它将创建一个批处理文件 我们称之为 Created bat 该文件将在其中插入多个命令 其中一条命令如下 FOR F x IN tasklist NH FI IMAGENAME e
  • Windows 2k8 上的 Coldfusion 10 - .com/ 加载正常,但 .com/index.cfm 给出 404

    我正在按照 Pete Freitag 的新 CF10 锁定指南设置一台新服务器 CF10 W2K8 我安装了一个测试站点 如果我打开 www mydomain com 它会加载默认文档 index cfm 但是 如果我尝试 www mydo
  • Angular 2 在没有 @Input 或 @Output 的情况下监视组件属性的更改

    在 Angular 1 x 中 我可以使用 watch 来观看我想要的任何内容 但是在 Angular 2 中 我们有 ngOnChanges 它非常酷且高性能 但只能监视输入和输出装饰器 然而 有时我确实需要观察本地属性 以便在它们发生变
  • Powershell - 从图像网址下载图像

    对 powershell 的了解有限 我尝试从图像网址下载图像 例如这样 http hdwallpaperia com wp content uploads 2014 01 Mc Laren P1 Wallpaper Image Pictu
  • char[length]初始化并处理

    我定义了一个字符数组 char d 6 如果我在以下方面有误 请纠正我 此时没有为变量分配内存d 现在我要初始化它 d aaaaa 这种初始化之后 就不需要释放内存了 它将自动完成 我怎么知道是否char 被初始化了吗 我正在寻找类似的模式
  • “显式”关键字对返回值优化 (RVO) 有何影响?

    以下代码工作得很好 显示 RVO struct A A int cout lt lt A A n constructor A const A cout lt lt A A const A n copy constructor A foo r
  • 在 python 中使用递归替代 len()

    作为 CS1301 问题的一部分 我正在尝试使用递归编写一个函数 该函数将执行与 len 完全相同的操作 但是 我有两个问题 我正在使用全局变量 但我在课程中还没有学到这一点 cs1301 自动评分器告诉我 我的函数返回 26 而不是 13
  • 隔离必需的字段验证器?

    我在页面上有两个搜索按钮 一个链接到下拉列表 另一个链接到带有文本框的下拉列表以获取更多搜索条件 我在所有上述控件上都需要现场验证器 当我从第一个下拉列表中选择某些内容并单击相应的搜索按钮时 文本框的字段验证器会触发 从而禁用第一个搜索按钮
  • 如何强制 Perl 按需重新编译使用“/o”编译的正则表达式?

    技术问题 给定一个正则表达式 my regEx qr whatever myVar oxi Notice o for compile once 强制重新编译的最有效方法是什么一经请求 例如 当我从程序逻辑中知道 myVar值改变 而不下降
  • UITableView 干扰状态栏

    我正在开发一个具有 UITableViewController 的应用程序 该应用程序显示值列表 如下所示 如何将表格向下移动 使其不会与状态栏冲突 看来我无法对这个场景施加任何限制 所以我不知所措 使用以下 3 个属性UIViewCont
  • Node.js 找不到模块“mongodb”

    我正在经历我的第一个 Node js 项目 我已经安装了 mongodb 有一个 server js 文件 当我尝试运行它时 出现此错误 module js 340 throw err Error Cannot find module mo
  • Bootstrap - 为反向行模式创建移动自适应

    我想用 Bootstrap 创建一个反向效果 第一行 左边是文字 右边是图像 第二行 左边是图片 右边是文字 第三行 左边是文字 右边是图片 第四行 左边是图片 右边是文字 而且这种情况一直持续下去 它在大型设备上看起来非常漂亮 但当它在设
  • 替换全局热键

    我有一个位于托盘中的应用程序 我想定义多个热键来触发我的程序中的事件 我从 AaronLS 在这个问题中的出色回答中找到了灵感 使用C 设置全局热键 https stackoverflow com a 27309185 3064934 如果
  • Get-AzureDomain、GetAzureADUser 等返回 Authentication_Unauthorized、未找到用户

    我能够使用 PowerShell 对我创建的 我是全局管理员的 Azure AD 资源进行身份验证 我执行此命令以通过 AD 进行身份验证 AzureADCred Get Credential Message Cred to connect
  • 在 Map() 的条目上使用 Promise.all

    我正在使用 Map 来表示一些键 值对 let myMap new Map myMap set foo bar myMap set foo2 bar42 对于每个 Map 条目 我执行一个返回 Promise 的函数 所有这些 Promis
  • 确保对象实现 Comparable

    我有一个小问题 想知道如何解决它 我有一个通用类Tuple
  • gatsbyjs、reactjs - 为什么组件渲染两次而图像没有出现?

    我是新来的gatsbyjs并使用 v2 我有 3 个组件 加载器 标题和布局 layout js import React from react import Helmet from react helmet import StaticQu
  • 保留对 React 状态变量的“引用”

    据我所知 Javascript 中没有指针 我有以下问题 但我想知道是否有一个解决方案让我无法解决 解决方案可能是普通的 Javascript 或者像 Context API 这样的 React js 钩子 useContext 或者更多