如何在 Solid.js 中使用 Ref?

Shu*_*ang 4 solid-js

所以我正在学习并开始使用Solid.js,我想知道我们如何处理solid.js中的ref,就像react中的useRef一样。

我检查文档我尝试这样的事情:

      let navigationOuterRef: HTMLDivElement
      let navigationRef: HTMLUListElement
    
     const MenuNavbar = (props: {layoutDatas: LayoutNavigation[]}) => {
        
       const [priorityItems, setPriorityItems] = createSignal<LayoutNavigation[]>(props.layoutDatas);
      
      //....
    
      return (
        <div ref={navigationOuterRef} class="....">
          <ul ref={navigationRef} class="...">
            <For each={priorityItems()}>
              {(labelName) => (
                <li class="flex items-center cursor-pointer">
                  {labelName.label}
                </li>
              )}
            </For>
          </ul>
        //...
Run Code Online (Sandbox Code Playgroud)

它有效...但我收到了警告消息,例如

createRoot在or之外创建的计算render永远不会被处理

所以我认为问题是我在组件外部创建了引用,因此如果没有适当的上下文,如果卸载它就无法处理它,但是如果我在组件中移动了引用声明,我在 TS 中会出现此错误

变量“navigationOuterRef”在分配之前使用。

那么我做错了什么以及正确的方法是什么?

snn*_*snn 7

是的,组件要求您在适当的所有者下运行它们,即render函数或通过createRoot函数或另一个组件创建的根。这是构建所有权图所必需的,该图显示谁拥有谁,以便在处置组件时,其资源将被清理。因此,警告消息与 refs 无关,而是与在响应式上下文之外创建的组件有关。

除此之外,refs 是底层 DOM 节点的句柄。它们有两种形式:变量和函数。

变量形式要求你使用onMount钩子,因为当组件加载时, ref 将是未定义的,只有在渲染阶段完成后它们才指向实际的 DOM 元素。

let ref;

console.log(ref); // undefined

onMount(() => console.log(ref)); // div

<div ref={ref} />
Run Code Online (Sandbox Code Playgroud)

为什么它们不能立即可用是因为 Solid 在构建 DOM 树时运行赋值操作。

<div ref={el => ref=el} /> 
Run Code Online (Sandbox Code Playgroud)

变量形式基本上是函数形式的语法糖。

由于 ref 最初不可用,因此 ref 元素的正确类型是:

let navigationOuterRef: HTMLDivElement | undefined;
Run Code Online (Sandbox Code Playgroud)

如果不输入undefined,则会出现类型错误:

Variable 'X' is used before being assigned
Run Code Online (Sandbox Code Playgroud)

一旦 DOM 节点可用,函数形式就会接收 DOM 元素:

Variable 'X' is used before being assigned
Run Code Online (Sandbox Code Playgroud)

编译后的代码在创建 DOM 树时调用 ref 函数。

https://www.solidjs.com/docs/latest#ref