useFormat
React hook that provides internationalized formatting functions for numbers, dates, lists, and more in React Native.
React hook that provides internationalized formatting functions for numbers, dates, lists, and more using the JavaScript Intl API in React Native.
import { View, Text } from 'react-native'
import { useFormat } from '@terai/react-native'
function Component() {
const format = useFormat()
return (
<View>
<Text>{format.number(1234.56, { style: 'currency', currency: 'USD' })}</Text>
<Text>{format.date(new Date(), { dateStyle: 'long' })}</Text>
</View>
)
}Return Value
Returns an object with formatting functions that automatically use the current locale:
number
Format numbers with locale-aware formatting.
- Type:
(value: number, options?: Intl.NumberFormatOptions) => string
Examples:
const format = useFormat()
// Currency
format.number(1234.56, { style: 'currency', currency: 'USD' })
// Result: '$1,234.56' (en), '1.234,56 $' (es), etc.
// Percentage
format.number(0.85, { style: 'percent' })
// Result: '85%'
// Compact notation
format.number(1234567, { notation: 'compact' })
// Result: '1.2M' (en), '1,2 M' (es), etc.
// Custom decimal places
format.number(3.14159, { minimumFractionDigits: 2, maximumFractionDigits: 4 })
// Result: '3.1416'date
Format dates with locale-aware formatting.
- Type:
(value: Date | number, options?: Intl.DateTimeFormatOptions) => string
Examples:
const format = useFormat()
const date = new Date('2024-03-15')
// Long date style
format.date(date, { dateStyle: 'long' })
// Result: 'March 15, 2024' (en), '15 de marzo de 2024' (es)
// Custom format
format.date(date, {
year: 'numeric',
month: 'long',
day: 'numeric',
weekday: 'long'
})
// Result: 'Friday, March 15, 2024' (en)
// Time only
format.date(new Date(), { timeStyle: 'short' })
// Result: '2:30 PM' (en), '14:30' (es)
// Date and time
format.date(new Date(), {
dateStyle: 'short',
timeStyle: 'short'
})
// Result: '3/15/24, 2:30 PM' (en)list
Format lists with locale-aware conjunctions and separators.
- Type:
(value: Iterable<string>, options?: Intl.ListFormatOptions) => string
Examples:
const format = useFormat()
const items = ['apples', 'oranges', 'bananas']
// Default (conjunction)
format.list(items)
// Result: 'apples, oranges, and bananas' (en), 'apples, oranges y bananas' (es)
// Disjunction
format.list(items, { type: 'disjunction' })
// Result: 'apples, oranges, or bananas' (en)
// Unit
format.list(['5 pounds', '12 ounces'], { type: 'unit' })
// Result: '5 pounds, 12 ounces' (en)relativeTime
Format relative time with locale-aware phrases.
- Type:
(value: [number, Intl.RelativeTimeFormatUnit], options?: Intl.RelativeTimeFormatOptions) => string
Examples:
const format = useFormat()
// Past
format.relativeTime([-3, 'day'])
// Result: '3 days ago' (en), 'hace 3 días' (es)
// Future
format.relativeTime([2, 'hour'])
// Result: 'in 2 hours' (en), 'dentro de 2 horas' (es)
// Narrow style
format.relativeTime([-1, 'week'], { style: 'narrow' })
// Result: '1 wk. ago' (en)
// Auto numeric (uses 'yesterday', 'tomorrow', etc.)
format.relativeTime([-1, 'day'], { numeric: 'auto' })
// Result: 'yesterday' (en), 'ayer' (es)displayNames
Format display names for languages, regions, currencies, etc.
- Type:
(value: string, options: Intl.DisplayNamesOptions) => string | undefined
Examples:
const format = useFormat()
// Language names
format.displayNames('es', { type: 'language' })
// Result: 'Spanish' (en), 'español' (es)
// Region names
format.displayNames('US', { type: 'region' })
// Result: 'United States' (en), 'Estados Unidos' (es)
// Currency names
format.displayNames('USD', { type: 'currency' })
// Result: 'US Dollar' (en), 'dólar estadounidense' (es)
// Script names
format.displayNames('Arab', { type: 'script' })
// Result: 'Arabic' (en)Options
locale
- Type:
Locale | undefined - Default: Current locale from
useLocale()
Override the locale for formatting. Useful when you need to format in a different locale than the current one.
const format = useFormat({ locale: 'es' })
// Always formats in Spanish, regardless of current locale
format.number(1234.56, { style: 'currency', currency: 'EUR' })
// Result: '1.234,56 €'Use Cases
Price Display
import { View, Text, StyleSheet } from 'react-native'
import { useFormat } from '@terai/react-native'
function PriceTag({ amount, currency }) {
const format = useFormat()
return (
<View style={styles.container}>
<Text style={styles.price}>
{format.number(amount, { style: 'currency', currency })}
</Text>
</View>
)
}
const styles = StyleSheet.create({
container: {
padding: 8,
},
price: {
fontSize: 24,
fontWeight: 'bold',
},
})Event Date Display
import { View, Text } from 'react-native'
import { useFormat } from '@terai/react-native'
function EventDate({ startDate, endDate }) {
const format = useFormat()
return (
<View>
<Text>
{format.date(startDate, { dateStyle: 'medium' })}
{' - '}
{format.date(endDate, { dateStyle: 'medium' })}
</Text>
</View>
)
}Shopping Cart Summary
import { View, Text, StyleSheet } from 'react-native'
import { useFormat, useTs } from '@terai/react-native'
function CartSummary({ items, total, currency }) {
const format = useFormat()
const { ts } = useTs()
return (
<View style={styles.container}>
<Text style={styles.items}>
{format.list(items.map(item => item.name))}
</Text>
<Text style={styles.total}>
{ts`Total`}: {format.number(total, { style: 'currency', currency })}
</Text>
</View>
)
}
const styles = StyleSheet.create({
container: {
padding: 16,
backgroundColor: '#f5f5f5',
borderRadius: 8,
},
items: {
fontSize: 14,
marginBottom: 8,
},
total: {
fontSize: 18,
fontWeight: 'bold',
},
})Post Timestamp
import { Text } from 'react-native'
import { useFormat } from '@terai/react-native'
function PostTimestamp({ createdAt }) {
const format = useFormat()
const now = Date.now()
const diff = createdAt - now
// Calculate appropriate unit
const minutes = Math.floor(diff / 60000)
const hours = Math.floor(diff / 3600000)
const days = Math.floor(diff / 86400000)
let value: [number, Intl.RelativeTimeFormatUnit]
if (Math.abs(days) >= 1) {
value = [days, 'day']
} else if (Math.abs(hours) >= 1) {
value = [hours, 'hour']
} else {
value = [minutes, 'minute']
}
return <Text>{format.relativeTime(value, { numeric: 'auto' })}</Text>
}Language Selector Display
import { View, Text, TouchableOpacity, StyleSheet } from 'react-native'
import { useFormat, useLocale, setLocale } from '@terai/react-native'
const LANGUAGES = ['en', 'es', 'fr', 'de', 'ja']
function LanguageSelector() {
const format = useFormat()
const currentLocale = useLocale()
return (
<View style={styles.container}>
{LANGUAGES.map((lang) => (
<TouchableOpacity
key={lang}
style={[
styles.option,
currentLocale === lang && styles.selectedOption,
]}
onPress={() => setLocale(lang)}
>
<Text style={styles.optionText}>
{format.displayNames(lang, { type: 'language' })}
</Text>
</TouchableOpacity>
))}
</View>
)
}
const styles = StyleSheet.create({
container: {
padding: 16,
},
option: {
padding: 12,
borderRadius: 8,
marginBottom: 8,
backgroundColor: '#f5f5f5',
},
selectedOption: {
backgroundColor: '#e3f2fd',
},
optionText: {
fontSize: 16,
},
})Performance
- Formatting functions are locale-aware and automatically update when locale changes
- Uses native
IntlAPI for optimal performance - Memoized internally to prevent unnecessary recreations
React Native Considerations
The Intl API is available in React Native through:
- Hermes: Full
Intlsupport in recent versions - JavaScriptCore: Limited
Intlsupport, may need polyfills - Android: Ensure Android API level 24+ for full
Intlsupport
For older Android versions or JSC, consider using a polyfill like @formatjs/intl-* packages.
Requirements
- Must be called inside a React component
- Requires
setupTeraito be called first - Requires
IntlAPI support (Hermes recommended)
Related
useLocale- Hook to get the current localesetupTerai- Configure global format options- MDN Intl API - JavaScript internationalization API