我有一个特定组件的很多实例,我们称之为<Item>
。将鼠标悬停在任何<Item>
上时,(非常复杂和动态)工具提示应出现在项目的位置。
当我使用语义UI反应时,我选择的工具是使用Popup
显示工具提示。使用弹出窗口的一种方法是为它们提供一个触发器组件(这将是我的<Item>
)和一个内容组件,并且它将自动在触发器组件周围的某个位置显示。但是然后我为每个项目都有一个Popup
实例,这大大增加了我的应用程序的响应时间,因为所有Popup
都必须创建,即使我当前不需要它们也是如此。
使用Popup
的另一种方法是通过其context
属性为其提供引用,它将在该DOM节点处打开。因此,我想使用这种机制只有一个Popup
,只要将鼠标悬停在context
上,它就会对其<Item>
属性进行动态更新。
但是,要执行此操作,我需要将当前的<Item>
引用传递给弹出窗口。由于我有一个深度嵌套的应用程序,因此我选择使用https://github.com/diegohaz/constate来全局共享状态。
不幸的是,共享引用似乎无效。每当我尝试从共享上下文中读取它时,它都是null。
请在这里看一个简单的例子: https://codesandbox.io/s/pplw689627
尽管我可以在调试器中看到tooltipTarget
中写入了onMouseEnter
,但是在<Tooltip>
组件中读取它时,它始终为空。
有什么想法我在做什么错吗?
我愿意接受不同的建议,但我希望尽可能使用Semantic的Popup来保持一致的视觉风格。
更新:
汤姆·芬尼(Tom Finneys)的答案在上面的沙箱中有效,很不幸,我在实际环境中使用Typescript,但现在无法正常工作。我在此沙箱中得到了一个可行的解决方案: https://codesandbox.io/s/7143r32klj
主要问题是current
的{{1}}属性是只读的。这样可以防止您编写这样的上下文:
RefObject<T>
export function useTooltip() {
const [tooltipRecipe, setTooltipRecipe] = React.useState<string | undefined>(
undefined
);
let tooltipTarget = React.useRef<HTMLElement>(null);
const setTooltipTarget = (target: HTMLElement | null) => {
dummy.current = target;
};
return { tooltipRecipe, tooltipTarget, setTooltipRecipe, setTooltipTarget };
}
无法编译。
我现在可以使之起作用的唯一方法是将setTooltipTarget
转换为RefObject<T>
不是只读的本地类型。这是一个相当不错的技巧,但确实可行。在沙箱中查看解决方案。
实际上,有关此的讨论正在进行中: https://github.com/DefinitelyTyped/DefinitelyTyped/issues/31065
答案 0 :(得分:0)
您的问题源于试图对组件主体内部的tooltipTarget
ref进行突变。您应该在上下文中声明另一个setter函数,您可以调用该函数来更改ref的当前值。