react-native .toLocaleString()不适用于android

时间:2016-12-31 11:47:32

标签: react-native

我在反应原生中使用.toLocaleString()作为我的号码输出。所有关于IOS的工作但似乎不适用于Android。这是正常的还是?我需要使用小数函数吗?

disabling forking

13 个答案:

答案 0 :(得分:16)

而不是使用polyfill或外部依赖项,而是更改构建您的android应用程序所使用的JSC。对于react-native的较新版本,请在app/build.gradle

中添加或覆盖以下行
def jscFlavor = 'org.webkit:android-jsc-intl:+'

答案 1 :(得分:5)

您可以使用

number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")

答案 2 :(得分:3)

在RN >0.62的较新版本上,您可以更改JSC(JavaScriptCore)构建变体以支持/包括 ICU i18n 库和允许使用的必需数据,例如Date.toLocaleStringString.localeCompare

将此行替换为android/app/build.gradle文件中的

def jscFlavor = 'org.webkit:android-jsc:+'

与此行

def jscFlavor = 'org.webkit:android-jsc-intl:+'

清理构建并react-native run android

注意

每个体系结构此变量比默认变量大6MiB。 因此,如果使用def enableSeparateBuildPerCPUArchitecture = true,则每个APK架构版本的APK大小预计会增加约4MB,如果禁用每个架构的单独版本,则APK会更大。

答案 3 :(得分:2)

其原因是react-native使用的JavaScriptCore的版本非常旧。 iOS嵌入了自己的版本,这就是为什么它在那里可以正常工作的原因。

问题仍然存在(有关https://github.com/facebook/react-native/issues/19737前进方向的一些读物)

以及来自Airbnb开发者的更多信息 https://medium.com/airbnb-engineering/react-native-at-airbnb-the-technology-dafd0b43838(搜索“ JavaScriptCore不一致”)

答案 4 :(得分:1)

这是Java内核的问题,该内核用于在Android中运行本机响应,而不是本机本身。为了克服这个问题,您必须将最新的javascript内核集成到您的android构建中,或将本机更新到0.59。

详细信息记录在JSC Android Buildscripts存储库中。

现在,对于那些希望在不需要集成整个javascript核心的情况下进行语言环境字符串格式化的人来说,Javascript具有 Internationalization API (国际化API),可让您将数字格式设置为语言敏感格式。 MDN

上的文档

此API在android中不可用,需要使用Intl

进行填充。

在您的项目根目录中,安装Intl库

from_tensor_slices()

然后在项目的索引文件(index.js)中,在文件顶部添加以下代码:

yarn add intl

完成上述两个步骤后,您现在可以使用以下方法在项目中的任何位置获取语言环境字符串

if(Platform.OS === 'android') { // only android needs polyfill
  require('intl'); // import intl object
  require('intl/locale-data/jsonp/en-IN'); // load the required locale details
}

如果您需要为另一个语言环境代码设置编号格式,则所有语言环境代码详细信息都位于new Intl.NumberFormat('en-IN', { style: 'currency', currency: 'INR' }).format(10000000); 目录下。只需在index.js文件中要求您的文件即可。

答案 5 :(得分:1)

一种非常简单直接的方法是使用polyfill: 首先需要安装它:

npm i number-to-locale-string-polyfill

这必须添加到您的代码中,最好是在您要使用.toLocaleString()的类/函数之外。

require('number-to-locale-string-polyfill');

答案 6 :(得分:1)

(value) => {
    if (typeof value === 'number') {
      const [currency, cents] = (value / 100).toFixed(2).toString().split('.');

      return `${currency.replace(/\B(?=(\d{3})+(?!\d))/g, '.')},${cents}`;
    }

    return '0,00';
  }

答案 7 :(得分:0)

您也可以像这样使用Intl.NumberFormat

new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(amount)

答案 8 :(得分:0)

这是较新的且较轻巧的,请检查

  1. 首次安装:

纱线添加@ formatjs / intl-getcanonicallocales @ formatjs / intl-locale @ formatjs / intl-pluralrules @ formatjs / intl-numberformat

  1. 检查是否需要polyfill

import {shouldPolyfill} from '@formatjs/intl-numberformat/should-polyfill'

if (shouldPolyfill()) {
    require('@formatjs/intl-getcanonicallocales/polyfill');
    require('@formatjs/intl-locale/polyfill');
    require('@formatjs/intl-pluralrules/polyfill');
    require('@formatjs/intl-numberformat/polyfill');
    require('@formatjs/intl-numberformat/locale-data/en-US');
}

请参见源:https://formatjs.io/docs/polyfills/intl-numberformat/

答案 9 :(得分:0)

我使用自定义函数解决了这个问题

function numberToMoney(amount, simbol = '$', decimalCount = 2, decimal 
   = ".", thousands = ",") {
   decimalCount = Math.abs(decimalCount)
   decimalCount = isNaN(decimalCount) ? 2 : decimalCount

   const negativeSign = amount < 0 ? "-" : ""

   const i = parseInt(amount = Math.abs(Number(amount) || 
             0).toFixed(decimalCount)).toString()
   const j = (i.length > 3) ? i.length % 3 : 0

   return simbol + negativeSign + (j ? i.substr(0, j) + thousands : '') + 
   i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + thousands) + (decimalCount ? 
   decimal + Math.abs(amount - i).toFixed(decimalCount).slice(2) : "")
};

无需安装额外的软件包

答案 10 :(得分:0)

合并来自此线程的一些响应,您可以使用此代码来自定义格式化响应

const defaultOptions = {
  significantDigits: 2,
  thousandsSeparator: ',',
  decimalSeparator: '.',
  symbol: '$'
}

const currencyFormatter = (value, options) => {
  if (typeof value !== 'number') value = 0.0
  options = { ...defaultOptions, ...options }
  value = value.toFixed(options.significantDigits)

  const [currency, decimal] = value.split('.')
  return `${options.symbol} ${currency.replace(
    /\B(?=(\d{3})+(?!\d))/g,
    options.thousandsSeparator
  )}${options.decimalSeparator}${decimal}`
}

答案 11 :(得分:0)

function numberWithCommas(x) {
   return x.toString().replace(/\B(?<!\.\d*)(?=(\d{3})+(?!\d))/g, ",");
}

这将删除小数点后的逗号

答案 12 :(得分:-1)

轻松解决30秒:使用此polyfill