假设我有一个自定义挂钩,我将使用它来将单击事件侦听器添加到 HTML 元素中。
我创建参考const buttonRef = useRef(null);
,因此第一次渲染时的值为 null。 ref 值仅在渲染方法的final 中分配,此时我的自定义钩子已被调用。
因此,在第一次渲染时,我的自定义挂钩没有任何可添加事件侦听器的内容。
我最终必须更新组件,然后我的自定义挂钩才能第二次运行,并最终将事件侦听器添加到元素。我得到以下行为:
沙盒示例 https://codesandbox.io/s/9l5lxo3ryy
问题:
如何解决这个问题?我真的需要强制更新我的组件才能将引用发送到自定义挂钩吗?由于我只能在顶层调用钩子和自定义钩子(钩子规则),所以不允许像下面这样的东西。
useEffect(() => {
useMyHook();
});
App.js
function App() {
const buttonRef = useRef(null);
const hookValue = useMyHook(buttonRef.current);
const [forceUpdate, setForceUpdate] = useState(false);
return (
<div>
<button onClick={() => setForceUpdate(prevState => !prevState)}>
Update Component
</button>
<button ref={buttonRef}>Update Hook</button>
{"This is hook returned value: " + hookValue}
</div>
);
}
useMyHook.js(自定义挂钩)
import { useEffect, useState } from "react";
function useMyHook(element) {
const [myHookState, setMyHookState] = useState(0);
console.log("Inside useMyhook...");
console.log("This is the element received: " + element);
useEffect(() => {
console.log("Inside useMyhook useEffect...");
function onClick() {
setMyHookState(prevState => prevState + 1);
}
if (element !== null) {
element.addEventListener("click", onClick);
}
return () => {
console.log("Inside useMyhook useEffect return...");
if (element !== null) {
element.removeEventListener("click", onClick);
}
};
});
return myHookState;
}
export default useMyHook;