React Hook State not matching



我创建了一个监控滚动行为的自定义挂钩。但是,当我更改使用钩子的组件的状态时,我确实会从控制台日志中看到状态的更改,但一旦我开始滚动,状态的原始值为true。更奇怪的是,react dev工具与控制台日志输出不匹配。

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开发工具控制台日志

更新如果我把它改成这个,我相信这个问题与事件侦听器的状态范围有关。它需要删除并更新为正确的状态。

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;

您没有在示例中正确导出函数,但您在父组件上导入了它们,在子组件上使用了useState,如果您想将函数分离为子组件,则状态应在父组件中,并在状态最初设置为true的子组件中导入,则useExample将始终返回true。

export const useExample = (status) => {
console.log(`useExample status: ${status}`);
function handleScroll() {
console.log(`handle scroll, status: ${status}`);
}
useEffect(() => {
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll);
}, []);
};

在父级中应该是

import {useExample} from './useExample';
useExample(status);

但由于函数内部是useEffect,因此您可以在父组件中这样编写它。这样做会更容易。

import React, { useState, useEffect } from 'react';
function Example() {
const [status, setStatus] = useState(true);

function handleScroll() {
console.log(`handle scroll, status: ${status}`);
}
useEffect(() => {
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll);
}, []);

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;

相关内容

最新更新