Nic*_*Diz 9 javascript events reactjs react-hooks
我有一个handleScroll在滚动事件上监听的函数。此函数必须更新isFetching(以false开头,并且必须更改布尔值)。
如图所示,该函数handleScroll已正确收听console.log。但是,isFetching总是错误的。似乎setIsFetching从未读过。我认为,另一个选择就像eventListener冻结了handleScroll函数的第一个版本。
我该怎么做才能更新该函数中的钩子? 这是代码和codesandbox的简化版本:
/* <div id='root'></div> */
import React, { useState, useEffect } from "react";
import ReactDOM from "react-dom";
const debounce = (func, wait, immediate) => {
let timeout;
return function() {
const context = this;
const args = arguments;
clearTimeout(timeout);
timeout = setTimeout(() => {
timeout = null;
if (!immediate) func.apply(context, args);
}, wait);
if (immediate && !timeout) func.apply(context, args);
};
};
const App = () => {
const [isFetching, setIsFetching] = useState(false);
const handleScroll = debounce(() => {
setIsFetching(!isFetching);
console.log({ isFetching });
}, 300);
useEffect(() => {
window.addEventListener("scroll", handleScroll);
return () => window.removeEventListener("scroll", handleScroll);
}, []);
return <div style={{ height: "1280px" }}>Hello world</div>;
};
const root = document.getElementById("root");
if (root) ReactDOM.render(<App />, root);
Run Code Online (Sandbox Code Playgroud)
更新
我将一个空数组作为第二个参数,useEffect因为我希望第一个参数函数仅在componentDidMount()上触发一次
添加isFetching为依赖项useEffect
虽然我无法提供深入的解释,但我可以说,当您useEffect说效果不依赖于任何东西时,您基本上对 React 撒了谎,通过提供一个空的依赖项数组,传递包含在您的代码中的所有变量总是好的。影响。
此外,您每次创建组件时都会创建一个新函数re-render,以避免这种情况,将函数移动到内部useEffect或将其包装在内部useCallback,除非依赖项数组中的某些内容发生更改,否则不会重新创建该函数
useEffect(
() => {
const handleScroll = debounce(() => {
setIsFetching(prevState => !prevState);
console.log({ isFetching });
}, 300);
window.addEventListener("scroll", handleScroll);
return () => window.removeEventListener("scroll", handleScroll);
},
[isFetching]
);
Run Code Online (Sandbox Code Playgroud)
或者与useCallback
const handleScroll = useCallback(
debounce(() => {
setIsFetching(prevState => !prevState);
console.log({ isFetching });
}, 300),
[isFetching]
);
useEffect(
() => {
window.addEventListener("scroll", handleScroll);
return () => window.removeEventListener("scroll", handleScroll);
},
[isFetching]
);
Run Code Online (Sandbox Code Playgroud)
小智 2
为了从回调内部监听状态的变化useEffect(当您不跟踪任何 props 更新时),您可以将状态保存在组件范围之外的变量中,并直接使用它而不是状态。
这里有代码:
import React, { useState, useEffect } from "react";
import ReactDOM from "react-dom";
const debounce = (func, wait, immediate) => {
let timeout;
return function() {
const context = this;
const args = arguments;
clearTimeout(timeout);
timeout = setTimeout(() => {
timeout = null;
if (!immediate) func.apply(context, args);
}, wait);
if (immediate && !timeout) func.apply(context, args);
};
};
let isFetchingState;
const App = () => {
const [isFetching, setIsFetching] = useState(false);
isFetchingState = isFetching;
const handleScroll = debounce(() => {
setIsFetching(!isFetchingState);
console.log({ isFetchingState });
}, 300);
useEffect(() => {
window.addEventListener("scroll", handleScroll);
return () => window.removeEventListener("scroll", handleScroll);
}, []);
return <div style={{ height: "1280px" }}>Hello world</div>;
};
const root = document.getElementById("root");
if (root) ReactDOM.render(<App />, root);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
246 次 |
| 最近记录: |