【发布时间】:2020-10-22 16:40:16
【问题描述】:
我创建了一个自定义挂钩来监控滚动行为。但是当我从使用钩子的组件中更改状态时,我确实从控制台日志中看到了状态更改,但是一旦我开始滚动,状态的原始值为 true。更奇怪的是react dev工具和console log输出的内容不匹配。
import React, { useEffect } from 'react';
import useExample from './useExample';
function Example() {
const [status, setStatus] = useExample();
console.log(`example, status: ${status}`);
useEffect(() => {
setStatus(false);
},[]);
useEffect(() => {
setInterval(() => console.log(status), 2000);
}, [])
return (<div>
Something scrollable
ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
</div>);
}
export default Example;
import React, { useState, useEffect } from 'react';
const useExample = () => {
const [status, setStatus] = useState(true);
console.log(`useExample status: ${status}`);
useEffect(() => {
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll);
}, []);
function handleScroll() {
console.log(`handle scroll, status: ${status}`);
}
return [status, setStatus];
};
export default useExample;
我更新了功能。 setInterval 函数始终返回 true,即使在 Example.js 中的第一个 useEffect 中更改了状态。 React dev tools console log
更新 如果我将其更改为此它会起作用,我相信问题与事件侦听器的状态范围有关。它需要被移除并更新为正确的状态。
import React, { useState, useEffect, useCa } from 'react';
const useExample = () => {
const [status, setStatus] = useState(true);
console.log(`useExample status: ${status}`);
useEffect(() => {
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll);
}, [status]);
useEffect(() => {
console.log(`${status} useffect`);
}, [status]);
function handleScroll() {
console.log(`handle scroll, status: ${status}`);
}
return [status, setStatus];
};
export default useExample;
【问题讨论】:
-
为什么要把事件监听器写在另一个组件中,而不是在同一个组件中。
-
需要复用组件
标签: reactjs react-hooks use-state