Repository navigation
Description
Description
We use the Settings API to store various user settings in our app. For some of those, reverting to the default device setting is an option, e.g. language and theme. When a user selects default, we use Settings to set that key to null. Prior to upgrading to new architecture, that worked fine. Now, if you change the setting to something, then change back to default, it will be stuck on the previous setting, i.e. setting to null does nothing. If I turn new arch back off it works again and setting to null clears the value.
We do not use Expo, but this is seen through the expo snack provided.
Steps to reproduce
Use this expo snack
Press Set to 1. Notice the setting is displayed as 1
Press Set to null. Notice the setting is displayed as null
Open the expo dev menu and press Reload
Notice the setting has reverted back to 1
If you switch the expo SDK from v52 to v51 and repeat the above steps, setting to null will clear the value and it will be back to undefined when reloading the app. v51 used the old architecture.
React Native Version
0.79.1
Affected Platforms
Runtime - iOS
Areas
TurboModule - The New Native Module System
Output of npx @react-native-community/cli info
System:
OS: macOS 15.4.1
CPU: (10) arm64 Apple M1 Max
Memory: 1.09 GB / 64.00 GB
Shell:
version: "5.9"
path: /bin/zsh
Binaries:
Node:
version: 22.14.0
path: /opt/homebrew/bin/node
Yarn:
version: 1.22.22
path: /opt/homebrew/bin/yarn
npm:
version: 10.9.2
path: /opt/homebrew/bin/npm
Watchman:
version: 2025.04.14.00
path: /opt/homebrew/bin/watchman
Managers:
CocoaPods:
version: 1.15.2
path: /Users/.../.rbenv/shims/pod
SDKs:
iOS SDK:
Platforms:
- DriverKit 24.4
- iOS 18.4
- macOS 15.4
- tvOS 18.4
- visionOS 2.4
- watchOS 11.4
Android SDK:
API Levels:
- "34"
- "35"
Build Tools:
- 34.0.0
- 35.0.0
System Images:
- android-29 | Google Play ARM 64 v8a
- android-34 | Google APIs ARM 64 v8a
- android-34 | Google Play ARM 64 v8a
- android-35 | Google Play ARM 64 v8a
Android NDK: 22.1.7171670
IDEs:
Android Studio: 2024.3 AI-243.24978.46.2431.13363775
Xcode:
version: 16.3/16E140
path: /usr/bin/xcodebuild
Languages:
Java:
version: 17.0.15
path: /usr/bin/javac
Ruby:
version: 3.4.3
path: /Users/.../.rbenv/shims/ruby
npmPackages:
"@react-native-community/cli":
installed: 18.0.0
wanted: 18.0.0
react:
installed: 19.0.0
wanted: 19.0.0
react-native:
installed: 0.79.1
wanted: 0.79.1
react-native-macos: Not Found
npmGlobalPackages:
"*react-native*": Not Found
Android:
hermesEnabled: true
newArchEnabled: true
iOS:
hermesEnabled: true
newArchEnabled: true
Stacktrace or Logs
NA
MANDATORY Reproducer
https://snack.expo.dev/EFzAocYOcozcgkRg83AVT
Screenshots and Videos
No response
Activity
react-native-bot commentedon May 2, 2025
Tip
Newer version available: You are on a supported minor version, but it looks like there's a newer patch available - 0.79.2. Please upgrade to the highest patch for your minor or latest and verify if the issue persists (alternatively, create a new project and repro the issue in it). If it does not repro, please let us know so we can close out this issue. This helps us ensure we are looking at issues that still exist in the most recent releases.
react-native-bot commentedon May 2, 2025
Tip
Newer version available: You are on a supported minor version, but it looks like there's a newer patch available - undefined. Please upgrade to the highest patch for your minor or latest and verify if the issue persists (alternatively, create a new project and repro the issue in it). If it does not repro, please let us know so we can close out this issue. This helps us ensure we are looking at issues that still exist in the most recent releases.
gfreeman-karmak commentedon May 2, 2025
confirmed, still an issue in 0.79.2
cipolleschi commentedon May 6, 2025
HI @gfreeman-karmak, thanks for opening the issue. This is a change in the semantic of how modules handles
nullvalues between the Old and the New Architecture. This might be a deliberate design decision, made before my time.We already have a lot of code depending on this behavior and external libraries might relies on that too. By changing this semantic, we might break a lot of libraries that now relies on the null values being stripped out.
I'm not saying that we can't change this, but it requires a bit of discussion internally.
gfreeman-karmak commentedon May 6, 2025
@cipolleschi hey thanks for the update. I see the PR is iOS specific, so does that mean the Android implementation of turbo modules does not strip
nullvalues out? I haven't converted our own native modules to turbo modules yet, but the platforms should be consistent.cipolleschi commentedon May 9, 2025
@gfreeman-karmak Settings is supported only on iOS, as you can see from here and by exploring the SettingsFallback.js.
I need to setup a couple of more complex reproducers to verify that on Android, but yes, it could be an iOS only bug.
cipolleschi commentedon May 9, 2025
I can confirm that this is an iOS bug only. As you see in the image, the Android implementeation won't drop the null value.
I also checked what a legacy native module would receive.
On the Legacy architecture, it receives a dictionary like this:
In the New Architecture, it receives a dictionary like this:
I believe that the New Arch has been implemented like that because if you try to put the value of
"<null>"in some places, e.g. user defaults and collections, the app might crash. However, the proper approach would be to keep the"<null>"and handle the null value properly.Note: the
"<null>"string is the string representation of[NSNull null].