我正在尝试将事件发射器与React
useEffect
和一起使用useState
,但是它始终获取初始状态而不是更新状态。如果我直接调用事件处理程序(即使使用),也可以使用setTimeout
。
如果我将值传递给useEffect()
第二个参数,它将使其起作用,但是,每当值更改时(这是击键触发的),这都会导致事件发射器重新订阅。
我究竟做错了什么?我试过useState
,useRef
,useReducer
,和useCallback
,并不能得到任何工作。
这是复制品:
import React, { useState, useEffect } from "react";
import { Controlled as CodeMirror } from "react-codemirror2";
import "codemirror/lib/codemirror.css";
import EventEmitter from "events";
let ee = new EventEmitter();
const initialValue = "initial value";
function App(props) {
const [value, setValue] = useState(initialValue);
// Should get the latest value, both after the initial server load, and whenever the Codemirror input changes.
const handleEvent = (msg, data) => {
console.info("Value in event handler: ", value);
// This line is only for demoing the problem. If we wanted to modify the DOM in this event, we would instead call some setState function and rerender in a React-friendly fashion.
document.getElementById("result").innerHTML = value;
};
// Get value from server on component creation (mocked)
useEffect(() => {
setTimeout(() => {
setValue("value from server");
}, 1000);
}, []);
// Subscribe to events on component creation
useEffect(() => {
ee.on("some_event", handleEvent);
return () => {
ee.off(handleEvent);
};
}, []);
return (
<React.Fragment>
<CodeMirror
value={value}
options={{ lineNumbers: true }}
onBeforeChange={(editor, data, newValue) => {
setValue(newValue);
}}
/>
{/* Everything below is only for demoing the problem. In reality the event would come from some other source external to this component. */}
<button
onClick={() => {
ee.emit("some_event");
}}
>
EventEmitter (doesnt work)
</button>
<div id="result" />
</React.Fragment>
);
}
export default App;
这是具有相同代码的代码沙箱App2
:
https://codesandbox.io/s/ww2v80ww4l
App
组件具有3种不同的实现-EventEmitter,pubsub-js和setTimeout。仅setTimeout有效。
为了阐明我的目标,我只是希望其中handleEvent
的值在所有情况下都与Codemirror值匹配。单击任何按钮时,应显示当前的代码镜像值。而是显示初始值。
value
在事件处理程序中是过时的,因为它从定义它的闭包中获取其值。除非每次value
更改都重新订阅新的事件处理程序,否则它将不会获得新值。
解决方案1:对发布效果进行第二个论证[value]
。这使事件处理程序获得正确的值,但也使效果在每次击键时再次运行。
解决方案2:使用ref
将最新的存储value
在组件实例变量中。然后,产生一个效果,每当value
状态更改时,该效果仅更新此变量。在事件处理程序中,请使用ref
,而不是value
。
const [value, setValue] = useState(initialValue);
const refValue = useRef(value);
useEffect(() => {
refValue.current = value;
});
const handleEvent = (msg, data) => {
console.info("Value in event handler: ", refValue.current);
};
https://reactjs.org/docs/hooks-faq.html#what-can-i-do-if-my-effect-
dependencies-change-too-oftenten
该页面上似乎还有其他一些解决方案也可能起作用。非常感谢@Dinesh的帮助。
在Autoconf的第2版,大部分宏被重新命名以使用更加统一和具有描述性的命名方案。下面是被重新命名了的宏的原来名字, 随后给出了这些宏现在的名字。虽然为了保持向后兼容,旧名字仍然能够被autoconf程序所接受,旧名字都 被看作过时的。关于新的命名方案,参见 宏名 。AC—ALLOCAAC—FUNC—ALLOCA AC—ARG—ARRAY 因为用途有限而被删除了。AC—CHAR—UNSIGNED
下面的示例是一个计时器组件,它有一个按钮(用于启动计时器)和两个标记,显示经过的秒数和经过的秒数乘以2。 但是,它不工作(CodeSandbox演示) 守则 问题 在使用效果调用中,秒值将始终等于上次呈现使用效果块时(当isActive上次更改时)的值。这将导致setDouble秒(秒*2)语句失败。React Hooks ESLint插件给我一个关于这个问题的警告: React Hook use
我正在写一个小的抓取程序,它导航到一个包含链接列表的页面, 它单击第一个链接,打开一个新页面,获取一些详细信息,然后导航回包含链接列表的页面,然后尝试查找下一个链接,但我得到: 组织。openqa。硒。StaleElementReferenceException:stale元素引用:元素未附加到页面文档 你知道我该怎么避免吗?
问题内容: 环境 hibernate4.2 ojdbc6-Oracle 11.2.0.3.0 JDBC 4.0 Oracle数据库11g 问题 我们遵循了许多建议,以如下方式配置Hibernate批处理: 我们检查了日志,发现生成的SQL语句已批处理。但是,如果两个事务同时修改相同版本的实体行,则Hibernate将成功提交它们,导致最后提交的事务中的冲突更新丢失(两个事务中都保存了无冲突的数据,
我有以下Useffect钩子: 然而,我得到以下警告: React Hook useEffect缺少依赖项:“image.height”、“image.img”、“image.width”、“scaleProperties.scaleInstance”和“scaleProperties.scaleValueMm”。请包含它们或删除依赖项数组 Image和scaleProperties也是组件的状态
我不熟悉React钩子和React 16.13.1。 我将实现能够处理登录的Auth组件。 但是它似乎没有正确更新状态,即使使用响应对象调用。 这个代码有什么问题?