Javascript 在事件侦听器函数中无法访问React hooks值
我决定使用windom width和resize event listener为我的组件使用React挂钩。问题是我无法访问所需的当前值。我得到添加事件侦听器时设置的嵌套值 将函数传递给值设置函数对我来说不是一个解决方案,因为它会强制渲染并破坏我的其他功能 我附上极简主义的例子来说明核心问题:Javascript 在事件侦听器函数中无法访问React hooks值,javascript,reactjs,addeventlistener,react-hooks,Javascript,Reactjs,Addeventlistener,React Hooks,我决定使用windom width和resize event listener为我的组件使用React挂钩。问题是我无法访问所需的当前值。我得到添加事件侦听器时设置的嵌套值 将函数传递给值设置函数对我来说不是一个解决方案,因为它会强制渲染并破坏我的其他功能 我附上极简主义的例子来说明核心问题: import React, { Component, useState, useEffect } from 'react'; import { render } from 'react-dom'; co
import React, { Component, useState, useEffect } from 'react';
import { render } from 'react-dom';
const App = () => {
const [width, setWidth] = useState(0);
const resize = () => {
console.log("width:", width); // it's always 0 even after many updates
setWidth(window.innerWidth);
};
useEffect(() => {
resize();
window.addEventListener("resize", resize);
return () => window.removeEventListener("resize", resize);
}, []);
return <div>{width}</div>;
}
render(<App />, document.getElementById('root'));
import React,{Component,useState,useffect}来自'React';
从'react dom'导入{render};
常量应用=()=>{
const[width,setWidth]=useState(0);
常量大小=()=>{
console.log(“width:,width);//即使经过多次更新,也始终为0
setWidth(window.innerWidth);
};
useffect(()=>{
调整大小();
addEventListener(“调整大小”,调整大小);
return()=>window.removeEventListener(“resize”,resize);
}, []);
返回{width};
}
渲染(
请寻求帮助。每次渲染时,您都会获得一个新的resize
函数副本。每个副本都捕获宽度的当前值。您的侦听器有一个副本,该副本是在第一次渲染时创建的,其宽度为0
要解决此问题,您有几个选项:
当width
更改时更新侦听器
useEffect(() => {
resize();
window.addEventListener("resize", resize);
return () => window.removeEventListener("resize", resize);
}, [width]);
用于获取侦听器内的当前宽度
const resize = () => {
setWidth(oldWidth => {
console.log("width:", oldWidth);
return window.innerWidth
});
};
将宽度存储在
获取数据的另一种方法是设置组件的变量
import React,{Component,useState,useffect}来自'React';
从'react dom'导入{render};
//*******
常量appData={
宽度:0
}
//*******
常量应用=()=>{
const[width,setWidth]=useState(0);
常量大小=()=>{
//*******获得宽度
console.log('=>',appData.width);
//*******
console.log(“width:,width);//即使经过多次更新,也始终为0
setWidth(window.innerWidth);
//*******更新宽度
appData.width=window.innerWidth;
//*******
};
useffect(()=>{
调整大小();
addEventListener(“调整大小”,调整大小);
return()=>window.removeEventListener(“resize”,resize);
}, []);
返回{width};
}
render(,document.getElementById('root'));
是的。第二个useffect
对这个问题没有帮助。你要么需要在width
更改时删除add listeners,要么用其他方法获取width
的当前值。因此有3种可能的解决方案。第一种是最简单的解决方案。你的代码优化不好,对or没有真正的帮助原始问题。它只是隐藏了问题。第一个useffect
设置一个事件侦听器,将width
重置为初始值。这会触发重新渲染器,第二个useffect
。第二个useffect
将width
设置为正确的值。因此每个调整大小事件都会触发两个重新渲染器,而不是打开e和一个resize
调用使用了错误的值。我喜欢第三种方法。谢谢。
const widthRef = useRef(width);
const resize = () => {
console.log("width:", widthRef.current);
widthRef.current = window.innerWidth;
setWidth(window.innerWidth);
};
import React, { Component, useState, useEffect } from 'react';
import { render } from 'react-dom';
//*******
const appData = {
width:0
}
//*******
const App = () => {
const [width, setWidth] = useState(0);
const resize = () => {
//******* get width
console.log('===>',appData.width);
//*******
console.log("width:", width); // it's always 0 even after many updates
setWidth(window.innerWidth);
//******* update width
appData.width = window.innerWidth;
//*******
};
useEffect(() => {
resize();
window.addEventListener("resize", resize);
return () => window.removeEventListener("resize", resize);
}, []);
return <div>{width}</div>;
}
render(<App />, document.getElementById('root'));