PIYO - Tech & Life -

React NativeアプリでAndroidでstartsWith関数の実行結果が異なる(っぽい)のにハマった

ReactNative Android

React Nativeのアプリで、ある文字列が特定の文字列で始まる場合に何かするみたいな、↓こんなif文を書いていたんですが、Androidの実機で動かないケースに遭遇しました。

if(text.startsWith('xxxx')) {
  // do something
}

正確にいうと、実機デバッグ中Remote Debuggerにつないでいるときは想定通りの動きをするものの、Remote Debugger無しで動かすとif文の中に入ってくれないというものでした。

最初これに気がつくまで苦労しました。デバッグしたら必ず動くからなんだこれ?、と。Remote DebuggerにつなぐとJSの実行環境がDebuggerに載っているものに変わるようですね。

タイトルに(っぽい)とつけたのは、実際に値を確認してはいないからです。デバッグできないとなると結果の確認も少々面倒でして。


これに気づいて調べてみるとissueがいくつか見つかりました。

Different String.startsWith behaviour on Android vs iOS · Issue #11370 · facebook/react-native · GitHub
Description I'm using the startsWith method on JavaScript strings to compare some values. Specifically the string contains emoji characters, but not at the beginning of the string. On iOS: 'Fish and Chips 🐟🍟'.startsWith('F') // true The ...
string `startsWith` produces false negatives · Issue #19699 · facebook/react-native · GitHub
Review the documentation: https://facebook.github.io/react-native Search for existing issues: https://github.com/facebook/react-native/issues Use the latest React Native version: https://github.com/facebook/react-native/releases Run reac...

ざっくり読んだ感じ、JavaScriptCoreっていうJSのエンジン的なものが古いから一部挙動がおかしいけど、最新を使うように直そうとしているよ、ということです。

そして実際に修正コミットが2018年末にされているようなので近い内にリリースされるはずです。

RN本体のアップグレードはそれなりに大変なので、アップグレードするまではstartsWithは使わないように回避するとよさそうです。

↓のようにindexOfを使って回避しました。

if(text.startsWith('xxxx')) {
  // do something
}



if(text.indexOf('xxxx') === 0) {
  // do something
}