using multiple languages in a react native app - react-native

I have a react native app that I'm building as project for a company. the company wants to provide the option of choosing the language on set up and then changing it if needed from the settings page, same way the phone language on android works.
I first thought about saving the text in JSON file and loading the text from there when the app starts, and when I made my search I only found solution about localization rather than using multiple languages the way I'm doing.
So I was wondering if anyone can confirm that the JSON file solution I thought of is a good and useful idea and if there is other better solutions to use instead?

There are many solutions to this in react native. One would be to use i18n combined with your localization JSON files to create a multi language solution.
Example In Practice:
import React, { Component } from 'react';
import {
View,
Text
} from 'react-native';
import { strings } from '../locales/i18n';
class Screen extends Component {
render() {
return (
<View>
<Text>{strings('screenName.textName')}</Text>
</View>
);
}
}
Full Explanation: https://medium.com/#danielsternlicht/adding-localization-i18n-g11n-to-a-react-native-project-with-rtl-support-223f39a8e6f2

Project react-native-i18n is deprecated now. Read this article Internationalization in React Native which doesn't required any linking or any configuration except for this little configuration.
import i18n from 'i18n-js';
import en from './locales/en.json';
import de from './locales/de.json';
i18n.defaultLocale = 'en';
i18n.locale = 'en';
i18n.fallbacks = true;
i18n.translations = { en, de };
export default i18n;
To display internationalized information on the page we can use i18n.t() function by passing a translation key as an argument. e.g. i18n.t("home.welcome")

using multilanguage (HINDI,ENGLISH) in react native app
frist create 2 json file
main folder...Language
1..hi.json
{
name:'Name'
Address:'Address'
}
2..en.json
{
name:'नाम'
Address:'पता'
}
3.then install this... i18n
4..create a file i18n.js
import i18n from 'i18next';
import {initReactI18next} from 'react-i18next';
import en from '../Language/en.json';
import hi from '../Language/hi.json';
i18n.use(initReactI18next).init({
lng: 'en',
fallbackLng: 'en',
resources: {
en: en,
hi: hi,
},
interpolation: {
escapeValue: false
}
});
export default i18n;
5...App.js import this lines
import './Language/i18n';
import {useTranslation} from 'react-i18next';
6...App.js code
function HomeScreen() {
const {t,i18n} = useTranslation();
const [currentLanguage,setLanguage] =useState('en');
const changeLanguage = value => {
i18n
.changeLanguage(value)
.then(() => setLanguage(value))
.catch(err => console.log(err));
};
return (
<View style={{flex:1,backgroundColor:'#ccc'}}>
<Text>{t("name")}</Text>
<View>
<TouchableOpacity onPress={()=>changeLanguage('en')}>
<Text> ENGLISH</Text>
</TouchableOpacity>
<TouchableOpacity onPress={()=>changeLanguage('hi')}>
<Text>हिन्दी</Text>
</TouchableOpacity>
</View>
</View>
);
}
export default HomeScreen;

Related

React Native Paper Theming Fails to Apply

I'm fairly new to React Native, so apologies if this is a basic question. I'm trying to apply a Dark Theme using React Native Paper, but it won't work for some reason. My code is as follows:
import React from 'react';
import { SafeAreaProvider } from 'react-native-safe-area-context';
import { DarkTheme, Provider as PaperProvider } from 'react-native-paper';
import { Main } from './src/main';
const theme = {
...DarkTheme,
};
export default function App() {
return (
<SafeAreaProvider>
<PaperProvider theme={theme}>
<Main />
</PaperProvider>
</SafeAreaProvider>
);
}
It seems like this should be relatively simple. Am I missing something? Any help would be greatly appreciated.
I added the below to the theme and it now works.
colors: {
...DarkTheme.colors
}

i18next how to use the Trans component in React Native

How to apply a bold weight to certain parts of the translation using the Trans component in React Native?
Since HTML tags like <strong></strong> don't work, we have to create our own custom <Strong/> component that applies certain text styling to the translation, but I don't know how to do that despite reading the docs?
Docs:
import { Trans } from 'react-i18next';
function MyComponent({ person, messages }) {
const { name } = person;
const count = messages.length;
return (
<Trans i18nKey="userMessagesUnread" count={count}>
Hello <strong title={t('nameTitle')}>{{name}}</strong>, you have {{count}} unread message. <Link to="/msgs">Go to messages</Link>.
</Trans>
);
}
i guess you can use <Text style={{fontWeight: 'bold'}}>{{name}}</Text> instead of <strong title={t('nameTitle')}>{{name}}</strong>.
or using useTranslation
import React from 'react';
import { useTranslation } from 'react-i18next';
export function MyComponent() {
const { t, i18n } = useTranslation();
// or const [t, i18n] = useTranslation();
return <Text style={{fontWeight: 'bold'}}>{t('my translated text')}</Text>
}
don't test yet

Pdf downloader in React Native

I need a solution to download app screen as pdf in React native. The below code is not working for me, and it is not a exact solution.
import React, { Component } from 'react';
import {
Text,
TouchableHighlight,
View,
} = from 'react-native';
import RNHTMLtoPDF from 'react-native-html-to-pdf';
class Example extends Component {
async createPDF() {
let options = {
html: '<h1>PDF TEST</h1>',
fileName: 'test',
directory: 'docs',
};
let file = await RNHTMLtoPDF.convert(options)
console.log(file.filePath);
},
render() {
<View>
<TouchableHighlight onPress={this.createPDF}>
<Text>Create PDF</Text>
</TouchableHighlight>
</View>
}
}
You just copy-pasted some code snippet from the readme file of react-native-html-to-pdf, it is appreciated if you actually do some effort ...
To answer your question: this library will not help you in any way since a react-native screen does not consist out of html/css.
If you want a pdf from a react-native screen you probably first want to take a screenshot, and afterwards convert that jpeg image to pdf.

Font loading error when using the ShoutemUI/TextInput component in a Exponent react-native framework

I'm trying to use shoutem/ui with exponent and I’m getting an error using the shoutem/ui textinput component, where I get the following error message fontFamily Rubik is not a system font and has not been loaded through Exponent.Font.loadAsync
However I loaded all the custom shoutem fonts that were listed in the blog post https://blog.getexponent.com/using-react-native-ui-toolkits-with-exponent-3993434caf66#.iyiwjpwgu
Using the Exponent.Font.loadAsync method.
fonts: [
FontAwesome.font,
{'space-mono': require('./assets/fonts/SpaceMono-Regular.ttf')},
{'Rubik-Black': require('./node_modules/#shoutem/ui/fonts/Rubik-Black.ttf')},
{'Rubik-BlackItalic': require('./node_modules/#shoutem/ui/fonts/Rubik-BlackItalic.ttf')},
{'Rubik-Bold': require('./node_modules/#shoutem/ui/fonts/Rubik-Bold.ttf')},
{'Rubik-BoldItalic': require('./node_modules/#shoutem/ui/fonts/Rubik-BoldItalic.ttf')},
{'Rubik-Italic': require('./node_modules/#shoutem/ui/fonts/Rubik-Italic.ttf')},
{'Rubik-Light': require('./node_modules/#shoutem/ui/fonts/Rubik-Light.ttf')},
{'Rubik-LightItalic': require('./node_modules/#shoutem/ui/fonts/Rubik-LightItalic.ttf')},
{'Rubik-Medium': require('./node_modules/#shoutem/ui/fonts/Rubik-Medium.ttf')},
{'Rubik-MediumItalic': require('./node_modules/#shoutem/ui/fonts/Rubik-MediumItalic.ttf')},
{'Rubik-Regular': require('./node_modules/#shoutem/ui/fonts/Rubik-Regular.ttf')},
{'rubicon-icon-font': require('./node_modules/#shoutem/ui/fonts/rubicon-icon-font.ttf')},
],
});
Looking through the code I couldn't find the obvious fix - had trouble even finding where the style was set to throw the error.
The code above seem to be missing one line. Try adding this line to the array list:
{'Rubik': require('./node_modules/#shoutem/ui/fonts/Rubik-Regular.ttf')}
Use this code from the link
import React, { Component } from 'react';
import { StatusBar } from 'react-native';
import { Font, AppLoading } from 'expo';
import { View, Examples } from '#shoutem/ui';
export default class App extends React.Component {
state = {
fontsAreLoaded: false,
};
async componentWillMount() {
await Font.loadAsync({
'Rubik': require('./node_modules/#shoutem/ui/fonts/Rubik-Regular.ttf'),
'Rubik-Black': require('./node_modules/#shoutem/ui/fonts/Rubik-Black.ttf'),
'Rubik-BlackItalic': require('./node_modules/#shoutem/ui/fonts/Rubik-BlackItalic.ttf'),
'Rubik-Bold': require('./node_modules/#shoutem/ui/fonts/Rubik-Bold.ttf'),
'Rubik-BoldItalic': require('./node_modules/#shoutem/ui/fonts/Rubik-BoldItalic.ttf'),
'Rubik-Italic': require('./node_modules/#shoutem/ui/fonts/Rubik-Italic.ttf'),
'Rubik-Light': require('./node_modules/#shoutem/ui/fonts/Rubik-Light.ttf'),
'Rubik-LightItalic': require('./node_modules/#shoutem/ui/fonts/Rubik-LightItalic.ttf'),
'Rubik-Medium': require('./node_modules/#shoutem/ui/fonts/Rubik-Medium.ttf'),
'Rubik-MediumItalic': require('./node_modules/#shoutem/ui/fonts/Rubik-MediumItalic.ttf'),
'Rubik-Regular': require('./node_modules/#shoutem/ui/fonts/Rubik-Regular.ttf'),
'rubicon-icon-font': require('./node_modules/#shoutem/ui/fonts/rubicon-icon-font.ttf'),
});
this.setState({ fontsAreLoaded: true });
}
render() {
if (!this.state.fontsAreLoaded) {
return <AppLoading />;
}
return (
<View styleName="flexible">
<Examples />
<StatusBar barStyle="default" hidden={false} />
</View>
);
}
}

What is the recommended way to apply styles to an extended React Native component?

I have extended the Text component in order to have a reusable text component with a custom font.
My custom component should accept the styles passed to it and add the custom font to it.
I'm currently doing this:
MyText.js
import React from 'react'
import {
Text,
StyleSheet
} from 'react-native';
export default class MyText extends React.Component {
render() {
const style =
Object.assign( {},
StyleSheet.flatten(this.props.style),
{fontFamily: "My Font"}
);
return (
<Text style={style}>
{this.props.children}
</Text>
);
}
}
While this works as expected, having to flatten the stylesheet every time seems wrong. The above is a trivial example, and I can think of other components on which I could use this pattern. For that reason, I want to make sure I'm not ignoring a more suitable approach.
Well it depends on how much you would want to customize. In this case , if it is just a different font, it could be something like
import React from 'react'
import {
Text,
StyleSheet
} from 'react-native';
import _ from 'lodash';
export default class MyText extends React.Component {
render() {
const filteredProps = _.omit(this.props, 'style');
return (
<Text style={[{fontFamily: "My Font"}, this.props.style]} {...filteredProps} />
);
}
}