Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
ourdudekyle opened this issue Nov 4, 2024 · 8 comments
Labels
bug 🪲 Something isn't working

Comments

@ourdudekyle
Copy link

ourdudekyle commented Nov 4, 2024

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 ourdudekyle added the bug 🪲 Something isn't working label Nov 4, 2024
@ourdudekyle ourdudekyle changed the title [Bug]: PointAnnotation Throwing an Error with Nested Children [Bug]: PointAnnotation Throwing an Error with Nested Children on RN 0.76 with New Architecture Nov 6, 2024
@matiastang
Copy link

I have the same problem

@matiastang
Copy link

<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>

@thomasgrivet
Copy link

Hello, we have the same issue!

@matiastang
Copy link

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

@ourdudekyle
Copy link
Author

@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
Copy link
Author

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

@mfazekas
Copy link
Contributor

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

@mfazekas mfazekas reopened this Dec 27, 2024
@ourdudekyle
Copy link
Author

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug 🪲 Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants