react-native icon indicating copy to clipboard operation
react-native copied to clipboard

Add static platform check props

Open ryanlntn opened this issue 2 years ago • 7 comments

Summary:

I've noticed that a lot of RN projects have something along the lines of the following in them:

export const isAndroid = Platform.OS === 'android'
export const isIOS = Platform.OS === 'ios'

This seems common enough that I think it makes sense to just export these from RN itself. Platform already has isPad and isTV. This would add another way to express platform checks with that API.

Changelog:

[GENERAL] [ADDED] - Adds isAndroid, isIOS, isMacOS, isNative, isWeb, and isWindows static properties to Platform

Test Plan:

I just patched these into a demo app. Here's a screenshot:

Screenshot 2023-06-13 at 7 39 06 PM

ryanlntn avatar Jun 14 '23 01:06 ryanlntn

Platform Engine Arch Size (bytes) Diff
android hermes arm64-v8a 8,755,105 -147
android hermes armeabi-v7a 8,067,667 -159
android hermes x86 9,247,692 -161
android hermes x86_64 9,096,829 -156
android jsc arm64-v8a 9,316,217 -243
android jsc armeabi-v7a 8,506,127 -231
android jsc x86 9,379,701 -246
android jsc x86_64 9,632,951 -238

Base commit: c870a529fe78ea1cc780f6b7c6f1b0940f4eb8df Branch: main

analysis-bot avatar Jun 14 '23 02:06 analysis-bot

@NickGerleman Good to know. What do you think about something like Platform.is('ios') that just wraps the Platform.OS condition? That could use PlatformOSType for now and would still read similar. Not sure if Babel transforms would still be a problem with that.

ryanlntn avatar Jun 14 '23 13:06 ryanlntn

@ryanlntn

What do you think about something like Platform.is('ios') that just wraps the Platform.OS condition?

My main question here is "why?" What does this achieve from a user's perspective that Platform.OS === 'ios' doesn't?

I don't mean to sound harsh. It's just that, considering the extra effort required to optimise and then teach this proposed new API, I'm afraid such an API wouldn't be all that valuable. (If anything we should be looking at ways to deprecate and then remove the existing Platform.isPad and Platform.isTV.)

I think we'd certainly be open to a new API if one is warranted, but we should probably discuss the motivation and design in an RFC before going any further with an implementation.

motiz88 avatar Jun 14 '23 13:06 motiz88

@motiz88

My main question here is "why?" What does this achieve from a user's perspective that Platform.OS === 'ios' doesn't?

In terms of functionality it doesn't accomplish anything new. And yet as stated above almost every RN project I've seen has something along the lines of const isAndroid = Platform.OS === 'android' in it. So there's something about expressing one off platform checks that way that appeals to people.

I don't mean to sound harsh. It's just that, considering the extra effort required to optimise and then teach this proposed new API, I'm afraid such an API wouldn't be all that valuable. (If anything we should be looking at ways to deprecate and then remove the existing Platform.isPad and Platform.isTV.)

I'm curious about these optimizations. I was unaware that there was a babel transform stripping dead code based on Platform.OS conditions. Would people assigning const isAndroid = Platform.OS === 'android' and checking against isAndroid break that or would it still work in that case? Is this documented somewhere?

I think we'd certainly be open to a new API if one is warranted, but we should probably discuss the motivation and design in an RFC before going any further with an implementation.

Fair enough.

ryanlntn avatar Jun 14 '23 14:06 ryanlntn

Can confirm, having isAndroid etc is definitely common among our clients over the past 7+ years of doing RN consulting.

jamonholmgren avatar Jun 14 '23 15:06 jamonholmgren

Opened an RFC.

ryanlntn avatar Jun 14 '23 19:06 ryanlntn

I'm curious about these optimizations. I was unaware that there was a babel transform stripping dead code based on Platform.OS conditions. Would people assigning const isAndroid = Platform.OS === 'android' and checking against isAndroid break that or would it still work in that case? Is this documented somewhere?

I'm not sure this is documented, but here is a link to where Platform.OS is replaced with the platform being bundled for. https://github.com/facebook/metro/blob/c6a94bc170cf95a6bb21b5638929ec3311a9a5b7/packages/metro-transform-plugins/src/inline-plugin.js#L152

So, a condition might be transformed to a constant comparison like if ('android' === 'ios') { which is is able to be optimized away. I think the same would apply to the above example, but I am less familiar with the other transforms and optimizations to know if it has the same overall effect if used in a condition (Moti may know more). You can always inspect the bundled JS to know for sure what was emitted.

I tend to agree though, that adding Platform.is('android') doesn't seem to enable more than the existing Platform.OS === 'android', beyond saving a couple of keystrokes.

NickGerleman avatar Jun 14 '23 23:06 NickGerleman

This PR is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 7 days.

github-actions[bot] avatar Dec 12 '23 05:12 github-actions[bot]

This PR was closed because it has been stalled for 7 days with no activity.

github-actions[bot] avatar Dec 19 '23 05:12 github-actions[bot]