launchdarkly / js-core

LaunchDarkly monorepo for JavaScript SDKs
Other
14 stars 16 forks source link

React Native / Expo - LDProvider causes errors in React Devtools #488

Closed mateuszroth closed 2 months ago

mateuszroth commented 3 months ago

Is this a support request? This issue tracker is maintained by LaunchDarkly SDK developers and is intended for feedback on the code in this library. If you're not sure whether the problem you are having is specifically related to this library, or to the LaunchDarkly service overall, it may be more appropriate to contact the LaunchDarkly support team; they can help to investigate the problem and will consult the SDK team if necessary. You can submit a support request by going here and clicking "submit a request", or by emailing support@launchdarkly.com.

Note that issues filed on this issue tracker are publicly accessible. Do not provide any private account information on your issues. If your problem is specific to your account, you should submit a support request as described above.

Describe the bug React Native / Expo LDProvider causes errors in React Devtools and blocks possibility to use it in the Expo application.

Uncaught Error: Cannot add child "110" to parent "66" because parent node was not found in the Store.
Dismiss
The error was thrown at http://xxx:8081/_expo/react-devtools/standalone.js:2:1012287
    at f.emit (http://xxx:8081/_expo/react-devtools/standalone.js:2:984358)
    at http://xxx:8081/_expo/react-devtools/standalone.js:2:985900
    at http://xxx:8081/_expo/react-devtools/standalone.js:2:1359186
    at Array.forEach (<anonymous>)
    at U_.e.onmessage (http://xxx:8081/_expo/react-devtools/standalone.js:2:1359169)

To reproduce

  1. Create Expo application with LDProvider
  2. Start the project
  3. Then press shift + m to open the list of available dev tools plugins. Select React devtools
  4. The tree in the React devtools stops at LDProvider and produces errors.

Expected behavior No error thrown and it should be possible to use React Devtools without issues.

Logs If applicable, add any log output related to your problem.

SDK version "@launchdarkly/react-native-client-sdk": "^10.0.3",

Language version, developer tools

System:
  OS: macOS 14.5
  CPU: (12) arm64 Apple M2 Pro
  Memory: 1.69 GB / 16.00 GB
  Shell:
    version: "5.9"
    path: /bin/zsh
Binaries:
  Node:
    version: 20.14.0
    path: ~/.nvm/versions/node/v20.14.0/bin/node
  Yarn:
    version: 1.22.17
    path: /usr/local/bin/yarn
  npm:
    version: 10.7.0
    path: ~/.nvm/versions/node/v20.14.0/bin/npm
  Watchman:
    version: 2022.11.14.00
    path: /usr/local/bin/watchman
Managers:
  CocoaPods:
    version: 1.15.2
    path: /Users/mateuszroth/.rbenv/shims/pod
SDKs:
  iOS SDK:
    Platforms:
      - DriverKit 23.5
      - iOS 17.5
      - macOS 14.5
      - tvOS 17.5
      - visionOS 1.2
      - watchOS 10.5
  Android SDK: Not Found
IDEs:
  Android Studio: 2023.3 AI-233.14808.21.2331.11709847
  Xcode:
    version: 15.4/15F31d
    path: /usr/bin/xcodebuild
Languages:
  Java:
    version: 17.0.10
    path: /usr/bin/javac
  Ruby:
    version: 2.7.5
    path: /Users/mateuszroth/.rbenv/shims/ruby
npmPackages:
  "@react-native-community/cli": Not Found
  react:
    installed: 18.2.0
    wanted: 18.2.0
  react-native:
    installed: 0.74.2
    wanted: 0.74.2
  react-native-macos: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: true
  newArchEnabled: false
iOS:
  hermesEnabled: true
  newArchEnabled: false

OS/platform OS: macOS 14.5, details above

Additional context

kinyoklion commented 2 months ago

Hello @mateuszroth,

This appears that it may be an intermittent issue related to the dev tools. I was able to get the same error, but with different node numbers, by reloading the application a few times.

That issue included a banner which directed to this issue with the dev tools: https://github.com/facebook/react/issues/27728

Additionally the callstack is entirely within the react dev tools. That said it is possible that we trigger some situation that increases the probability of this happening.

Thank you, Ryan

mateuszroth commented 2 months ago

Thank you. Actually the issue was caused on our side I believe. We were mapping flags and we forgot about null case, sorry:

import { type LDFlagSet } from '@launchdarkly/react-native-client-sdk';
import { camelCase } from 'change-case';

/**
 * Converts flags map provided by LaunchDarkly to our custom flags map. Changes flag key case to camelCase.
 * Ensures no extra flags are set.
 */
export function mergeFeatureFlags<T>(newFlags: LDFlagSet, defaultFlags: T): T {
  const allFlags = Object.entries(newFlags).reduce(
    (acc, [flagKey, flagValue]) => {
      const normalizedFlagKey = camelCase(flagKey);

      const isValidKey = normalizedFlagKey in (defaultFlags as object);
      if (!isValidKey) {
        return acc;
      }

      return { ...acc, [normalizedFlagKey]: flagValue };
    },
    { ...defaultFlags },
  );

  return allFlags;
}