maps icon indicating copy to clipboard operation
maps copied to clipboard

[Bug]: PointAnnotation Throwing an Error with Nested Children on RN 0.76 with New Architecture

Open ourdudekyle opened this issue 1 year ago • 8 comments

Mapbox Implementation

Mapbox

Mapbox Version

default

React Native Version

0.76

Platform

iOS, Android

@rnmapbox/maps version

10.1.33

Standalone component to reproduce

import React from 'react';
import Mapbox from '@rnmapbox/maps';
import { StyleSheet, Text, View } from 'react-native';

const ANNOTATION_SIZE = 50;

const defaultCamera = {
  centerCoordinate: [-73.98004319979121, 40.75272669831773],
  zoomLevel: 17,
};

const corners = [
  {
    coordinate: [-73.980313714175, 40.75279456928388],
    anchor: { x: 0, y: 1 },
  },
  {
    coordinate: [-73.9803415496257, 40.75275624885313],
    anchor: { x: 0, y: 0 },
  },
  {
    coordinate: [-73.98048535932631, 40.752816154647235],
    anchor: { x: 1, y: 0 },
  },
  {
    coordinate: [-73.98045541426053, 40.75285444197175],
    anchor: { x: 1, y: 1 },
  },
];

const sides = [
  {
    coordinate: [-73.97952569308393, 40.75274356459241],
    anchor: { x: 1 / 3, y: 0 },
  },
  {
    coordinate: [-73.98082017858928, 40.75329086324669],
    anchor: { x: 1 / 3, y: 1 },
  },
  {
    coordinate: [-73.97985980165191, 40.752286242917535],
    anchor: { x: 0, y: 1 / 3 },
    containerStyle: { flexDirection: 'row' },
  },
];

const styles = {
  small: {
    backgroundColor: 'blue',
    height: ANNOTATION_SIZE,
    justifyContent: 'center',
    width: ANNOTATION_SIZE,
    flex: 1,
  },
  large: {
    borderColor: 'blue',
    backgroundColor: 'transparent',
    borderWidth: StyleSheet.hairlineWidth,
    height: ANNOTATION_SIZE * 2,
    justifyContent: 'center',
    width: ANNOTATION_SIZE * 2,
    flex: 1,
  },
  text: {
    position: 'absolute',
    fontSize: 10,
  },
  matchParent: {
    flex: 1,
  },
};

const PointAnnotationAnchors = (props) => {
  return (
    <Mapbox.MapView style={styles.matchParent}>
      <Mapbox.Camera defaultSettings={defaultCamera} />
      {corners.map((p, i) => (
        <Mapbox.PointAnnotation
          key={`square-${i}`}
          id={`square-${i}`}
          coordinate={p.coordinate}
          anchor={p.anchor}
        >
          <View style={styles.small}>
            <Text style={[styles.text, { color: 'white' }]}>
              x={p.anchor.x.toPrecision(2)}, y={p.anchor.y.toPrecision(2)}
            </Text>
          </View>
        </Mapbox.PointAnnotation>
      ))}
      {sides.map((p, i) => {
        let { x, y } = p.anchor;
        if (x === 1) {
          x = 0;
        }
        if (y === 1) {
          y = 0;
        }
        return (
          <Mapbox.PointAnnotation
            key={`triangle-${i}`}
            id={`triangle-${i}`}
            coordinate={p.coordinate}
            anchor={p.anchor}
          >
            <View style={[styles.large, p.containerStyle]}>
              <View
                style={{
                  height: ANNOTATION_SIZE * 2,
                  width: ANNOTATION_SIZE * 2 * x,
                  backgroundColor: 'green',
                }}
              />
              <View
                style={{
                  height: ANNOTATION_SIZE * 2 * y,
                  width: ANNOTATION_SIZE * 2,
                  backgroundColor: 'green',
                }}
              />
              <Text style={[styles.text, { color: 'black' }]}>
                x={p.anchor.x.toPrecision(2)}, y={p.anchor.y.toPrecision(2)}
              </Text>
            </View>
          </Mapbox.PointAnnotation>
        );
      })}
    </Mapbox.MapView>
  );
};

export default PointAnnotationAnchors;

/* end-example-doc */

/** @type ExampleWithMetadata['metadata'] */
const metadata = {
  title: 'Point Annotation Anchors',
  tags: ['PointAnnotation'],
  docs: `
Point annotation anchors test
`,
};
PointAnnotationAnchors.metadata = metadata;

Observed behavior and steps to reproduce

With RN 0.76 and the New Architecture, PointAnnotations with nested children (like a View with a Text component inside it) through an error of: Mapbox [error] PointAnnotation supports max 1 subview other than a callout, and don't render completely. On iOS, this results in the View being rendered, but not the Text inside the view. This can be seen in the Point Annotation Anchors example: Screenshot 2024-11-04 at 3 29 17 PM

Expected behavior

PointAnnotations structured like this would load the View and the Text component inside it.

Notes / preliminary analysis

The parent view and its children are getting flattened, and _createViewSnapshot is being called with with the first subview in reactSubviews which on iOS ends up being the parent view if you pass something like:

          <View style={styles.small}>
            <Text style={[styles.text, { color: 'white' }]}>
              x={p.anchor.x.toPrecision(2)}, y={p.anchor.y.toPrecision(2)}
            </Text>
          </View>

to PointAnnotation

Additional links and references

No response

ourdudekyle avatar Nov 04 '24 21:11 ourdudekyle

I have the same problem

matiastang avatar Dec 13 '24 07:12 matiastang

<PointAnnotation key={square-${i}} id={square-${i}} coordinate={p.coordinate} anchor={p.anchor}

{/* collapsable={false} off view flattening */}
<View style={styles.small} collapsable={false}>
    <Text style={[styles.text, { color: 'white' }]}>
        x={p.anchor.x.toPrecision(2)}, y={p.anchor.y.toPrecision(2)}
    </Text>
</View>

matiastang avatar Dec 13 '24 07:12 matiastang

Hello, we have the same issue!

thomasgrivet avatar Dec 16 '24 09:12 thomasgrivet

@thomasgrivet you can add collapsable={false} to a component to disable flattening.

matiastang avatar Dec 26 '24 09:12 matiastang

@matiastang, good callout, it looks like there were changes around this prop in RN-0.76. I'll test this out on my project to see if it fixes my issue, and report back. Thanks!

ourdudekyle avatar Dec 26 '24 15:12 ourdudekyle

Confirmed, setting collapsable={false} on the view inside of PointAnnotation fixed my issue. Thanks @matiastang

ourdudekyle avatar Dec 26 '24 20:12 ourdudekyle

I think it's still a valid issue we either need to fix this or at least document it.

mfazekas avatar Dec 27 '24 09:12 mfazekas

I think it's still a valid issue we either need to fix this or at least document it.

@mfazekas, yeah documenting it would be a good idea, since the issue is stemming from a change in how RN handles optimizing the view hierarchy in 0.76. I can try to get a PR up for this later

ourdudekyle avatar Dec 27 '24 15:12 ourdudekyle