1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【ReactNatve】Platform.OSが必ずiosになった話

Posted at

TL;TR

  • Platform.OSの値が常にiosになってしまった
  • 原因は初歩的なタイプミスだった
  • コミットの粒度はなるべく小さくしよう

何が起こったか

ざっくり説明するとReactNative製アプリをAndroidで動かした時に、iOSでしか表示されないUIが表示されていました。
下記のようにPlatform.OSを表示させてみると、出力されるのはios
なぜかOSの種類に関わらずiosとして扱われてしまっているようでした。

import { Platform } from 'react-native';

console.log('os : ', Platform.OS); // --> "os : ios" と出力される・・・

react-nativeの不具合ならもっとIssueで大々的に騒がれてそうだけど、そんな気配もない。
となると何らかのバグなのだが、Platform.OSの値が必ずiosになってしまうってどんな状況やねん・・・

と思いながら直近のコミットを細かく見ていくと、

import { Platform } from 'react-native';

if(Platform.OS = "ios") {
    // iOS限定の処理をつらつらと
}

ああああああああ!!!!
Platform.OS = "ios"って書いてるうぅぅぅ!!!!

この処理以降、Platform.OSを参照しても代入されたiosが取れてしまうわけです。

補足

結果的に比較演算子のタイプミスだったわけですが、そもそもこの書き方でif分岐がどうなるかを解説します。

if...else - JavaScript | MDNによると下記のような記述があります。

条件式の中での代入

代入はコードを眺めたときに等式と混同される可能性があるの?で、条件式の中で単純な代入を使わないほうが望ましいです。たとえば、次のコードを使わないでください。

if (x = y) {
   /* do the right thing */
}

なるほど、使わない方がいいけど文法的にはアリみたいです。

ちなみにこの場合、ifの評価は代入された後の変数で行うらしく、下記のような結果になります。

var a = 0;

if(a){
  // 通らない
}
else {
  // 通る
}

if(a = 10){
  // 通る
}
else {
  // 通らない
}

if(a = undefined){
  // 通らない
}
else {
  // 通る
}

つまり先のタイプミスをした

if(Platform.OS = "ios") {
    // iOS限定の処理をつらつらと
}

は評価としてはtrueになります。

まとめ

結果的に原因は初歩的なタイプミスだったわけです。
気付いてみればなんてことないんですが、大規模なコミットに埋もれていたため見落としてしまいました。
テストで発見できればよかったのですが、Android端末で問題となった処理を行った後でないとPlatform.OSが書き換わらないのですり抜けてしまったようです。

教訓としては、コミットの粒度を小さくしてタイプミスを発見できるようにする。です。

1
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?