反应forwardRef和callback ref,ref变为undefined

问题描述 投票:0回答:2

这不是 Mapbox 相关问题,您不需要任何地图或相关知识来帮助。我的问题与 React refs 有关。

我正在使用

react-map-gl
(React 的 Mapbox)和
@mapbox/mapbox-gl-draw
,允许用户在地图上绘制几何图形。该应用程序有 2 个组件:
DrawControl
,用于公开绘制功能;
AllPastures
,用于渲染地图并管理创建/更新/删除绘制的几何图形。

当用户绘制多边形时,它会触发执行

DrawControl
onCreate
方法
onCreateOrUpdate
。我正在通过
forwardRef
DrawControl
AllPastures
进行抽奖。

这是一个

DrawControl
组件:

export const DrawControl = React.forwardRef<MapboxDraw, DrawControlProps>(
  (props: DrawControlProps, ref) => {
    const drawRef: MapboxDraw = useControl<MapboxDraw>(
      () => new MapboxDraw(props),
      ({ map }) => {
        map.on('draw.create', props.onCreate);
        map.on('draw.update', props.onUpdate);
        map.on('draw.delete', props.onDelete);
        map.on('draw.modechange', props.onModeChange);
      },
      ({ map }) => {
        map.off('draw.create', props.onCreate);
        map.off('draw.update', props.onUpdate);
        map.off('draw.delete', props.onDelete);
        map.off('draw.modechange', props.onModeChange);
      },
      {
        position: props.position,
      }
    );

    // exposing drawRef outside the component by Ref
    React.useImperativeHandle(ref, () => drawRef, [drawRef]);

    return null;
  }

这是

AllPastures
组件的一部分:

export const AllPastures = () => {
  ...
  const [drawRef, setDrawRef] = React.useState<MapboxDraw>();

  // here I’m using callback ref to react to drawRef changes
  const onDrawRef = React.useCallback((ref: MapboxDraw | null) => {
    if (ref) {
      setDrawRef(ref);
    }
  }, []);

  React.useEffect(() => {
    // it's ok here, drawRef is not undefined
    console.log('useEffect drawRef when app is loading', drawRef);
  }, [map, drawRef]);

  const onCreateOrUpdate = (e: { features: Feature[] }) => {
    // Why drawRef is undefined here????????????????????
    console.log('drawRef under onCreateOrUpdate method', drawRef);
  };

  ...

  return (
      <DrawControl
        ref={onDrawRef}
        position="top-right"
        displayControlsDefault={false}
        controls={{
          polygon: true,
          trash: true,
        }}
        defaultMode="simple_select"
        onCreate={onCreateOrUpdate}
        onUpdate={onCreateOrUpdate}
      />
  );
};

我的问题是,发现为什么当方法

onCreateOrUpdate
drawRef
未定义时?


这是一个模拟该问题的相关沙箱: https://stackblitz.com/edit/vitejs-vite-bvutvb?file=src%2FAllPastures.tsx

只需在地图上绘制任何多边形并检查console.log

drawRef under onCreateOrUpdate method
未定义。

请更改代码后,按F5完成刷新页面并再次测试。

reactjs mapbox-gl-js react-ref react-forwardref mapbox-gl-draw
2个回答
0
投票
const onCreateOrUpdate = React.useCallback((e: { features: Feature[] }) => {
  // Here drawRef would not be undefined
  console.log('drawRef under onCreateOrUpdate method', drawRef);
}, [drawRef]);

0
投票

对于其他正在寻找解决方案的人,我找到了一种使用

drawRef
DrawControl
forwardRef
转发到
useImperativeHandle
之外的方法,并将该引用附加到我的
<DrawControl>

下面的工作示例以及完整的解决方案:https://stackblitz.com/edit/vitejs-vite-bvutvb?file=src%2FDraw.tsx

export const Draw = () => {
  const { current: map } = useMap();
  const [drawMode, setDrawMode] = React.useState<DrawMode>('simple_select');
  const drawRef = React.useRef<MapboxDraw>(null);

  if (!map) {
    return null;
  }

  React.useEffect(() => {
    // it's ok here, drawRef is not undefined
    console.log('useEffect drawRef when app is loading', drawRef);
  }, [drawRef]);

  const onCreateOrUpdate = React.useCallback(
    (e: { features: Feature[] }) => {
      // Here drawRef would not be undefined
      console.log('drawRef under onCreateOrUpdate method', drawRef);
    },
    [drawRef]
  );

  return (
    <DrawControl
      ref={drawRef}
      position="top-right"
      displayControlsDefault={false}
      controls={{
        polygon: true,
        trash: true,
      }}
      defaultMode="simple_select"
      modes={{ ...MapboxDraw.modes, draw_rectangle: DrawRectangle }}
      onCreate={onCreateOrUpdate}
      onUpdate={onCreateOrUpdate}
    />
  );
};
© www.soinside.com 2019 - 2024. All rights reserved.