javascript - 将流/类组件重写为自定义钩子
问题描述
我正在尝试在此处重写以下代码,该代码是按流程编写的,以自定义挂钩。我被卡住了,钩子不能正常工作。你看到我犯了什么错误吗?
我得到的错误是TypeError: elementRefs.ref is not a function
我是这样称呼它的:
父.js
import MultiRef from "./MultiRef";
const [elementRefs] = useState(() => new MultiRef());
这是我的版本:
function useMultiRef() {
const map = new Map();
const _refFns = new Map();
const ref = (key) => {
let refFn = _refFns.get(key);
if (!refFn) {
refFn = (value) => {
if (value == null) {
_refFns.delete(key);
map.delete(key);
} else {
map.set(key, value);
}
};
_refFns.set(key, refFn);
}
return refFn;
};
}
export default useMultiRef;
这是原始代码:
/* @flow */
type RefFn<V> = (value: V|null) => mixed;
export default class MultiRef<K,V> {
map: Map<K,V> = new Map();
_refFns: Map<K,RefFn<V>> = new Map();
ref(key: K): RefFn<V> {
let refFn: ?RefFn<V> = this._refFns.get(key);
if (!refFn) {
refFn = value => {
if (value == null) {
this._refFns.delete(key);
this.map.delete(key);
} else {
this.map.set(key, value);
}
};
this._refFns.set(key, refFn);
}
return refFn;
}
}
更新(parent.js):
/**
* Scrolls to element if var goToElement is set
*/
useEffect(() => {
const ref = elementRefs.map.get(goToElement);
// If no ref exists, scroll to top of the floor instead
if (!ref) {
floorRef.current.scrollTop = 0;
return;
}
// Scroll to element: scrollTo(x-coord, y-coord)
floorRef.current.scrollTo(0, ref.offsetTop);
// Wait for a short time to perform scrolling
const timer = setTimeout(() => {
// currentElementRef is needed for highlighting the element
setCurrentElementRef(ref);
}, 500);
return () => clearTimeout(timer);
}, [elementRefs, goToElement]);
解决方案
您需要返回ref
值elementRefs.ref
才能工作,目前,您只需运行一个 void 函数。
此外,这不是您实现简单功能的自定义钩子。
function multiRef() {
//...
const ref = (key) => {...};
return { ref };
}
自定义钩子应该使用 hooks来获得类似于类的属性,它应该看起来像:
function useMultiRef() {
const map = useRef(new Map());
const _refFns = useRef(new Map());
const ref = useCallback((key) => {
let refFn = _refFns.current.get(key);
if (!refFn) {
refFn = (value) => {
if (value == null) {
_refFns.current.delete(key);
map.current.delete(key);
} else {
map.current.set(key, value);
}
};
_refFns.current.set(key, refFn);
}
return refFn.current;
}, []);
return { ref, map };
}
export default useMultiRef;
推荐阅读
- python - 如何通过 XPath 转到下一页?
- python - Music21,窗口分析获取时间?
- wordpress - 我想在移动视图 woocommerce 上有两种产品
- r - R 中 google_analytics_3 中的错误 404。词法错误:json 文本中的字符无效
- jquery - 如何在 Symfony 4 和 Webpack Encore 中使用数据表?
- css - 如何使用 mat-icon 保留默认的 SVG 颜色?
- php - html - Datalist displaying arabic text as squares
- google-cloud-platform - Can't find the option to export billing?
- javascript - How to combine data from two endpoints via observables?
- reactjs - TS2339: Property 'classes' does not exist on type 'PropsWithChildren