本文介绍了如何使用钩子消除功能组件中的回调的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
如何在 React 功能组件去抖动回调中获得实际的 prop 值,它在 React 类组件中工作,但我不知道如何使用钩子在功能组件中实现这种行为.
从react"导入React;从react-dom"导入 ReactDOM;从lodash.debounce"导入去抖动;const TestFunc = ({ count, onClick }) =>{const handleClick = debounce(() => {点击();控制台日志(计数);}, 500);返回 (<div><button type="button" onClick={handleClick}>函数:{count}按钮>
);};class TestClass 扩展了 React.Component {handleClick = debounce(() => {this.props.onClick();console.log(this.props.count);}, 500);使成为() {返回 (<div><button type="button" onClick={this.handleClick}>课程:{this.props.count}按钮>
);}}const App = () =>{const [countClass, setCountClass] = React.useState(0);const [countFunc, setCountFunc] = React.useState(0);返回 (<div><TestFunc count={countFunc} onClick={() =>setCountFunc(countFunc + 1)}/><测试类计数={countClass}onClick={() =>setCountClass(countClass + 1)}/>
);};ReactDOM.render(, document.getElementById("root"));
当你点击功能组件按钮时,它会将之前的 count
属性值记录到控制台,但它已经通过调用 onClick
处理程序改变了,同时类组件按钮将在 onClick
处理程序增加后记录实际的 count
属性值.那么,如何在功能组件中获取实际的 prop 值?
解决方案
这是一个简单的 debounce hook(用 TypeScript 编写)
import { useEffect, useRef } from "react";导出函数 useDebouncedCallback(回调: (...args: A) =>空白,等待:数量){//跟踪参数 &调用之间的超时句柄const argsRef = useRef();const timeout = useRef>();功能清理(){如果(超时.当前){clearTimeout(timeout.current);}}//确保我们的超时被清除,如果//我们的消费组件被卸载useEffect(() => 清理,[]);返回函数 debouncedCallback(...参数:A){//捕获最新的参数argsRef.current = args;//清除去抖动定时器清理();//再次开始等待timeout.current = setTimeout(() => {如果(argsRef.current){回调(...argsRef.current);}}, 等待);};}
您的用例示例:
const handleClick = useDebouncedCallback(() => {点击();控制台日志(计数);}, 500);...<button type="button" onClick={handleClick}>函数:{count}按钮>
也适用于传递参数的情况:
const handleChange = useDebouncedCallback((event) => {console.log(event.currentTarget.value);}, 500);<input onChange={handleChange}/>
How can I get actual prop values in React Functional Component debounced callbacks, It worked in React Class Component, but I have no idea how to reach this behavior in functional component using hooks.
import React from "react";
import ReactDOM from "react-dom";
import debounce from "lodash.debounce";
const TestFunc = ({ count, onClick }) => {
const handleClick = debounce(() => {
onClick();
console.log(count);
}, 500);
return (
<div>
<button type="button" onClick={handleClick}>
Func: {count}
</button>
</div>
);
};
class TestClass extends React.Component {
handleClick = debounce(() => {
this.props.onClick();
console.log(this.props.count);
}, 500);
render() {
return (
<div>
<button type="button" onClick={this.handleClick}>
Class: {this.props.count}
</button>
</div>
);
}
}
const App = () => {
const [countClass, setCountClass] = React.useState(0);
const [countFunc, setCountFunc] = React.useState(0);
return (
<div>
<TestFunc count={countFunc} onClick={() => setCountFunc(countFunc + 1)} />
<TestClass
count={countClass}
onClick={() => setCountClass(countClass + 1)}
/>
</div>
);
};
ReactDOM.render(<App />, document.getElementById("root"));
When you click on functional component button, it logs the previous count
prop value to console, but it's already changed by calling onClick
handler, in the same time the class component button would log the actual count
prop value after it was incremented by onClick
handler. So, how can I get actual prop values in functional component?
解决方案
Here's a simple debounce hook (written in TypeScript)
import { useEffect, useRef } from "react";
export function useDebouncedCallback<A extends any[]>(
callback: (...args: A) => void,
wait: number
) {
// track args & timeout handle between calls
const argsRef = useRef<A>();
const timeout = useRef<ReturnType<typeof setTimeout>>();
function cleanup() {
if(timeout.current) {
clearTimeout(timeout.current);
}
}
// make sure our timeout gets cleared if
// our consuming component gets unmounted
useEffect(() => cleanup, []);
return function debouncedCallback(
...args: A
) {
// capture latest args
argsRef.current = args;
// clear debounce timer
cleanup();
// start waiting again
timeout.current = setTimeout(() => {
if(argsRef.current) {
callback(...argsRef.current);
}
}, wait);
};
}
Example for your use case:
const handleClick = useDebouncedCallback(() => {
onClick();
console.log(count);
}, 500);
...
<button type="button" onClick={handleClick}>
Func: {count}
</button>
Also works for cases that pass arguments:
const handleChange = useDebouncedCallback((event) => {
console.log(event.currentTarget.value);
}, 500);
<input onChange={handleChange}/>
这篇关于如何使用钩子消除功能组件中的回调的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!