【问题标题】:How to make useRef not null when creating component with Suspense使用 Suspense 创建组件时如何使 useRef 不为空
【发布时间】:2020-08-06 07:34:06
【问题描述】:

我有点纠结于如何实现这一点。

我正在渲染一张地图,我需要 useRef 在创建地图时将元素传递给地图。

首先要做的是下载源文件,然后mapkit 类可以使用。我用悬念来解决这个问题:

<Suspense fallback={<MapFallback />}>
  <InternalMap {...props}></InternalMap>
</Suspense>

真正的好处是InternalMapmapkit 未准备好时抛出一个承诺,因此会显示回退,并且在InternalMap 内部我可以假设mapkit 已定义。然后在InternalMap里面我有:

const mapDivRef = useRef<HTMLDivElement>(null);

// This does not work because mapDivref.current is null, unless I decide to
//  put it inside of a useEffeect, at which point I have to verify it's created.
const map = new mapkit.Map(mapDivRef.current, options);


return (
  <div ref={mapRef} style={{ width: '100%', height: '100%' }}>
    {children}       
  </div>
);

这里的问题是我需要使用useEffect 来创建我的地图,因为在渲染发生之前mapDivRefnull。有没有办法在渲染之前定义 mapDivRef.current 或抛出错误,以便发生悬念回退?我要解决的问题是我的代码的 1/5 是 if (!map) return ...。我认为悬念会对此有所帮助,就像在初始加载 mapkit 时一样。我知道 mapkit 现在定义了如果我的组件被渲染。我现在正在尝试对map 做同样的事情。

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    首先,我们不应该直接在功能组件内创建任何实例,因为它将在每次重新渲染时创建。

    Refs 在初始渲染后被赋值。您使用useEffect 创建map 实例的方法是正确的。

    要正确使用地图实例,请执行以下操作:

    • 保持状态说map
    • 在useEffect中创建地图实例并保存在map状态
    • 将地图实例作为渲染道具传递,然后渲染一个子组件,该子组件可以包含您的所有逻辑if (!map) return ... 等。

    内部地图组件

    const InternalMap = props => {
      const [map, setMap] = useState(null);
    
      const myRef = useRef(null);
      console.log(myRef.current);
    
      useEffect(() => {
        const myMap = new mapkit.Map(mapDivRef.current, options);
        setMap(myMap);
      }, []);
    
      return <div ref={mapRef} style={{ width: '100%', height: '100%' }}>
        {props.children(map)}
      </div>;
    };
    

    用法:

    <Suspense fallback={<MapFallback />}>
      <InternalMap>
        {map => <ChildComponent {...props} map={map} />}  
      </InternalMap>
    </Suspense>
    

    【讨论】:

    • 我真的很想在因为悬念而总是定义地图的地方这样做......但我认为这是不可能的,因为尚未定义容器。
    猜你喜欢
    • 2020-01-08
    • 2021-01-22
    • 2023-01-03
    • 2020-12-20
    • 2020-12-16
    • 1970-01-01
    • 2020-11-23
    • 1970-01-01
    • 2019-11-20
    相关资源
    最近更新 更多