我不明白为什么需要以下 useImperativeHandle
, useLayoutEffect
和 useDebugValue
钩子,你能给出可以使用的例子,而不是文档中的例子请。
原文由 user11749073 发布,翻译遵循 CC BY-SA 4.0 许可协议
我不明白为什么需要以下 useImperativeHandle
, useLayoutEffect
和 useDebugValue
钩子,你能给出可以使用的例子,而不是文档中的例子请。
原文由 user11749073 发布,翻译遵循 CC BY-SA 4.0 许可协议
useImperativeHandle
useImperativeHandle
允许您确定将在 ref 上公开哪些属性。在下面的示例中,我们有一个按钮组件,我们想在该 ref 上公开 someExposedProperty
属性:
[索引.tsx]
import React, { useRef } from "react";
import { render } from "react-dom";
import Button from "./Button";
import "./styles.css";
function App() {
const buttonRef = useRef(null);
const handleClick = () => {
console.log(Object.keys(buttonRef.current)); // ['someExposedProperty']
console.log("click in index.tsx");
buttonRef.current.someExposedProperty();
};
return (
<div>
<Button onClick={handleClick} ref={buttonRef} />
</div>
);
}
const rootElement = document.getElementById("root");
render(<App />, rootElement);
[按钮.tsx]
import React, { useRef, useImperativeHandle, forwardRef } from "react";
function Button(props, ref) {
const buttonRef = useRef();
useImperativeHandle(ref, () => ({
someExposedProperty: () => {
console.log(`we're inside the exposed property function!`);
}
}));
return (
<button ref={buttonRef} {...props}>
Button
</button>
);
}
export default forwardRef(Button);
useLayoutEffect
这与 useEffect
相同,但只有在所有 DOM 变更完成后才会触发。 这篇 来自 Kent C. Dodds 的文章解释了关于这两者的差异以及任何人,他说:
99% 的时间 [
useEffect
] 是你想要使用的。
我还没有看到任何例子可以特别好地说明这一点,而且我也不确定我是否能够创造任何东西。最好的说法是,当 useEffect
出现问题时,您应该只使用 useLayoutEffect
。
useDebugValue
我觉得 文档 做了一个很好的例子来解释这个。如果你有一个自定义钩子,并且你想在 React DevTools 中标记它,那么这就是你使用的。
如果您对此有任何具体问题,那么最好发表评论或提出另一个问题,因为我觉得人们放在这里的任何内容都只是在重申文档,至少在我们遇到更具体的问题之前是这样。
原文由 OliverRadini 发布,翻译遵循 CC BY-SA 4.0 许可协议
3 回答1.9k 阅读✓ 已解决
1 回答1.8k 阅读✓ 已解决
2 回答1.2k 阅读✓ 已解决
1 回答993 阅读✓ 已解决
1 回答792 阅读✓ 已解决
1 回答672 阅读✓ 已解决
1 回答632 阅读✓ 已解决
请允许我通过说明所有这些钩子都很少使用来作为这个答案的序言。 99% 的时间,你不需要这些。它们仅用于涵盖一些罕见的极端情况。
useImperativeHandle
通常,当您使用
useRef
时,您会获得ref
附加到的组件的实例值。这允许您直接与 DOM 元素交互。useImperativeHandle
非常相似,但它可以让你做两件事:blur
、focus
等),从而允许对正常行为或完全不同的行为产生副作用。不过,您可以随意调用该函数。您可能有很多原因可能会执行上述任一操作;您可能不想将本机属性公开给父级,或者您可能想更改本机函数的行为。可能有很多原因。但是,
useImperativeHandle
很少使用。例子
在此示例中,我们将从
ref
获得的值将仅包含我们在blur
useImperativeHandle
。它不会包含任何其他属性( _我正在记录值以证明这一点_)。该函数本身也是“定制的”,其行为与您通常期望的不同。在这里,它设置document.title
并在调用blur
时模糊输入。useLayoutEffect
虽然在某种程度上类似于
useEffect()
,但它的不同之处在于它将在 React 向 DOM 提交更新后运行。当您需要在更新后计算元素之间的距离或进行其他更新后计算/副作用时,在极少数情况下使用。例子
假设您有一个绝对定位的元素,其高度可能会有所不同,并且您想在其下方放置另一个
div
。您可以使用getBoundingCLientRect()
计算父级的高度和顶部属性,然后将它们应用于子级的顶部属性。在这里你会想使用
useLayoutEffect
而不是useEffect
。请参阅以下示例中的原因:使用
useEffect
:(注意跳跃行为)使用
useLayoutEffect
:useDebugValue
有时您可能想要调试某些值或属性,但这样做可能需要昂贵的操作,这可能会影响性能。
useDebugValue
仅在 React DevTools 打开并检查相关钩子时调用,以防止对性能产生任何影响。不过,我个人从未使用过这个钩子。也许评论中的某人可以通过一个很好的例子提供一些见解。