在事件侦听器函数中无法访问 React hooks 值
React hooks value is not accessible in event listener function
我决定使用 windom 宽度和调整大小事件侦听器为我的组件使用 React 挂钩。问题是我无法访问我需要的当前值。我得到了在添加事件侦听器时设置的嵌套值。
将函数传递给值 setter 函数对我来说不是解决方案,因为它会强制渲染并破坏我的其他功能。
我附上一个简单的例子来说明核心问题:
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'));
求助。
每次渲染你都会得到一个新的 resize
函数副本。每个副本捕获 width
的当前值。您的听众有一个副本,它是在第一次渲染时使用 width = 0
.
创建的
要解决此问题,您有多种选择:
width
更改时更新侦听器
useEffect(() => {
resize();
window.addEventListener("resize", resize);
return () => window.removeEventListener("resize", resize);
}, [width]);
使用functional updates获取listener中的当前宽度
const resize = () => {
setWidth(oldWidth => {
console.log("width:", oldWidth);
return window.innerWidth
});
};
将宽度存储在mutable reference
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'));
我决定使用 windom 宽度和调整大小事件侦听器为我的组件使用 React 挂钩。问题是我无法访问我需要的当前值。我得到了在添加事件侦听器时设置的嵌套值。
将函数传递给值 setter 函数对我来说不是解决方案,因为它会强制渲染并破坏我的其他功能。
我附上一个简单的例子来说明核心问题:
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'));
求助。
每次渲染你都会得到一个新的 resize
函数副本。每个副本捕获 width
的当前值。您的听众有一个副本,它是在第一次渲染时使用 width = 0
.
要解决此问题,您有多种选择:
width
更改时更新侦听器useEffect(() => { resize(); window.addEventListener("resize", resize); return () => window.removeEventListener("resize", resize); }, [width]);
使用functional updates获取listener中的当前宽度
const resize = () => { setWidth(oldWidth => { console.log("width:", oldWidth); return window.innerWidth }); };
将宽度存储在mutable reference
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'));