reactjs - React Hooks + window.addEventListener in useEffect
问题描述
我正在尝试console.log
用户正在输入的 html 元素。
为此,我实现了以下钩子:
export const useGetActiveElement = () => {
const [activeElement, setActiveElement] = useState()
useEffect(() => {
if (window){
window.addEventListener('keyup', setCorrectElement);
}
return () => {
window.removeEventListener('keyup', setCorrectElement);
}
}, [])
const setCorrectElement = (element) => {
if(element.target.tagName === 'INPUT' || element.target.tagName === 'TEXTAREA') {
setActiveElement(element.target)
}
}
return activeElement}
export default () => {
const activeElement = useGetActiveElement()
console.log(activeElement) <==== Here! Only prints the value 2 or 3 times...
return <AnotherComponent />
}
出于某种我不明白的原因,该值在控制台中打印了几次,但在某些时候,它就不再打印了。
我不确定这是否是参考问题......但找不到合理的解释。
想法?
谢谢
解决方案
在您的初始渲染中,您的钩子的内部状态初始化为undefined
.
当您按下一个键时,您输入您的回调并尝试将状态设置为 HTML 元素。React 做了几次优化尝试,并将旧状态与新状态进行比较。如果值不同,它将安排重新渲染使用此钩子的任何组件。由于undefined
和 HTML 元素不同,React 将导致您的组件重新渲染,并且您的 console.log 消息将显示当前元素。
当您第二次按下某个键时,您将尝试再次将状态设置为 HTML 元素。然而这一次,这个值作为之前的状态,这意味着之前使用这个状态的组件不需要重新渲染。
然而,React 的并发有一个已知的怪癖,React 实际上会再渲染一次以确定当前提交的版本。
https://github.com/facebook/react/issues/17474#issuecomment-560942800
我们不知道当前提交了两个版本中的哪一个。当这种歧义发生时,我们必须过度渲染一次,然后我们知道两个版本是相同的并且没关系。
因此,您的组件将一次又一次地呈现第二次,您的 console.log 消息将显示当前元素。
然而,当你第三次按下某个键时,React 会再次注意到它是同一个引用,但这次不会重新渲染你的组件。
因此,您的组件不会第三次重新渲染,并且您的控制台日志也不会显示。
推荐阅读
- python - 如何使用子进程 python 恢复终端
- python - 如何通过在任意一对连续数字之间切割整数 N 将其拆分为两个非空部分。这样就创建了一对整数 A, B
- javascript - 如何将 google sheet API v3 迁移到 google sheet Api v4
- google-cloud-platform - 格式化 gcloud 计算实例列表以获取单个元数据值
- python - Django 存储实际可用性并查询新预订的可用时间表
- python - 使用 pandas 的 groupby 和 agg 合并包含 dicts 的列
- java - 我必须使用两个edittext获得两个用户输入,并在单击按钮时在textview中随机显示任何人
- npm - npm install 遇到问题
- go - Bazel没有将BUILD文件添加到外部依赖项
- java - 泛型:为枚举创建接口