Refs
目的
与 React DOM 这样的框架或原生 JavaScript不一样的是,在小程序没有办法修改DOM节点。 但是仍然有一情况下,开发者需要访问一个特定节点的实例。 例如,wx. ReateIntersectionObserver API 返回了一个监听器,它监听页面滚动,当目标节点的交点改变时触发。
Refs
因为 GojijS 使用 React 组件而不是小程序 自定义组件,根据运行时不同一个节点可能会在页面上或者自定义组件中渲染。
例如这段代码,在微信小程序里 view-a 渲染在页面中但 view-b 渲染在Subtree 组件中渲染。
Subtree是一个特殊的内置组件,它告诉GojiJS 在另一个自定义组件中渲染 children。 它在非WeChat平台上等同于Fragment。
const Comp = () => {
  const refA = useRef<GojiPublicInstance | null>();
  const refB = useRef<GojiPublicInstance | null>();
  return (
    <View className="view-a" ref={refA}>
      <Subtree>
        <View className="view-b" ref={refB}>
          hi
        </View>
      </Subtree>
    </View>
  );
};
render(<Comp />);
所以我们应该使用 refA 来监听 view-a ,使用 refB 监听 view-b。
useRenderedEffect
小程序和 Web 应用之间有一个主要区别,即所有DOM 修改都是异步生效的。 setData 的第二个参数是一个回调,每次 DOM 更改完成后它都会运行。
userRenderEffect 等价于 setData 的回调。 这个钩子在 DOM 更新完成后运行。 这也是最早可以访问refs的时机。 如果在useEffect中使用refs, ref.current 可能是 undefined。
请记住,我们建议除非要访问refs,在任何时候都使用 useEffect ,。
用法
下面是一个示例:
getComponentInstance 返回渲染它的自定义组件的 this。
如果节点是在页面中渲染的,getComponentInstance将返回undefined。
import React, { useRef } from 'react';
import { View, useRenderedEffect, GojiPublicInstance } from '@goji/core';
const Comp = () => {
  const viewRef = useRef<GojiPublicInstance | null>();
  useRenderedEffect(() => {
    const init = async () => {
      if (viewRef.current) {
        const componentInstance = await viewRef.current.getComponentInstance();
        const observe = componentInstance
          ? componentInstance.createIntersectionObserver()
          : wx.createIntersectionObserver();
        observer.relativeToViewport(...);
      }
    };
    init();
  }, []);
  return <View ref={viewRef}>hello, world!</View>;
}; componentInstance.createIntersectionObserver()
          : wx.createIntersectionObserver();
        observer.relativeToViewport(...);
      }
    };
    init();
  }, []);
  return <View ref={viewRef}>hello, world!</View>;
};