gpt4 book ai didi

javascript - 将 ref 传递给 HTML 元素到自定义钩子(Hook)

转载 作者:行者123 更新时间:2023-12-01 15:37:24 25 4
gpt4 key购买 nike

想象一下,我有一个自定义钩子(Hook),我将使用它将单击事件监听器添加到 HTML 元素中。

我使用 const buttonRef = useRef(null); 创建引用,所以第一次渲染的值为空。 ref 值仅在渲染方法的最后分配,在我的自定义钩子(Hook)已经被调用的地方。

因此,在第一次渲染时,我的自定义钩子(Hook)没有任何东西可以添加事件监听器。

我最终不得不在我的自定义钩子(Hook)第二次运行之前更新组件,最后将事件监听器添加到元素。我得到以下行为:

enter image description here

Sandbox with example

问题:

如何解决这个问题?我真的需要强制更新我的组件才能将 ref 发送到自定义钩子(Hook)吗?由于我只能在顶层调用钩子(Hook)和自定义钩子(Hook)(钩子(Hook)规则),因此不允许使用如下内容。

useEffect(() => {
useMyHook();
});

应用.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(自定义 Hook )
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;

最佳答案

解决方案非常简单,您只需将 ref 传递给自定义钩子(Hook)而不是 ref.current因为,当将 ref 分配给 DOM 并且在第一次渲染后触发自定义 Hook 中的 useEffect 时,ref.current 会在其原始引用处发生突变,所以 buttonRef.current将引用 DOM 节点

使用MyHook.js

import { useEffect, useState } from "react";

function useMyHook(refEl) {
const [myHookState, setMyHookState] = useState(0);

console.log("Inside useMyhook...");
console.log("This is the element received: ", refEl);

useEffect(() => {
const element = refEl.current;
console.log("Inside useMyhook useEffect...");

function onClick() {
console.log("click");
setMyHookState(prevState => prevState + 1);
}
console.log(element);
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;

index.js
function App() {
const buttonRef = useRef(null);
const hookValue = useMyHook(buttonRef);
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>
);
}

Working demo

关于javascript - 将 ref 传递给 HTML 元素到自定义钩子(Hook),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56136601/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com