Multi-language Text with React Native & React Context

State management in React has been a very turbulent landscape since the very beginning of the React era. With an overwhelming number of options, hopefully react context will change this in time.

Photo from: pixabay.com

User satisfaction and comfortability is at the forefront of all the applications we build at Inspired Ideas, including our free telemedicine service Dr. Elsa.

Working primarily with an audience that is split between English and Swahili speakers, supporting the two languages was a no-brainer. In this post I will share how simple it is to support two languages in React Native using the finally supported react context (officially supported on react 16.3.0 and up).

I am assuming you already have a react-native app running, and are familiar with the basics of react. For a primer on react context please read this amazing post on it: https://medium.com/dailyjs/reacts-%EF%B8%8F-new-context-api-70c9fe01596b.

The full source code for both the context and the Text element can be found at the end of the post. Let’s jump into code!

1. Creating Our Context

We are going to create our language context in a file called LanguageContext.js. We create it in a separate file for easy reusability.

First the only necessary import: React.

import React from 'react';

Next we create and export the LanguageContext context:

export const LanguageContext = React.createContext({
language: 'swahili', // default language is Swahili
changeLanguage: () => null
});

We then move on to creating the consumer LanguageConsumer:

export const LanguageConsumer = LanguageContext.Consumer;

Now for the provider, LanguageProvider:

export class LanguageProvider extends Component {
constructor(props) {
super(props);
this.state = { language: 'swahili' }
this.changeLanguage = this.changeLanguage.bind(this);
}
changeLanguage() {
this.setState({
language: this.state.language === "swahili" ? "english":"swahili"
});
}
render() {
return (
<LanguageContext.Provider
value={{
language: this.state.language,
changeLanguage: this.changeLanguage
}}>
{this.props.children}
</LanguageContext.Provider>
)
}
}

The provider above simply creates a container class, LanguageProvider that defines the language in its state and a changeLanguage method that toggles between the Swahili and English languages. The provider then returns a Context Provider element that wraps over the children that we will later pass into it, providing the children with access to the current language as well as the changeLanguage method.

2. Creating Our Custom Text Element

To create our Text element, we will extend from React.Component and return a language aware presentation component that will render the correct language text. The text element will be inside a file we will call CustomText.js, again, for easy reusability.

import React, { Component } from 'react';
import { Text } from 'react-native';
import {
LanguageProvider,
LanguageConsumer
} from './LanguageContext';
export default function CustomText (textArray) {
return (
<LanguageProvider>
<LanguageConsumer>
{
({ language })=> (
<Text>
{
language === 'swahili' ?
textArray[0] : textArray[1]
}
</Text>
)
}
</LanguageConsumer>
</LanguageProvider>
)
}

The above function, CustomText, takes in an array with two strings, one in Swahili and the other one in English in the the form:

textArray = ["Mambo Dunia!", "Hello World!"];

The CustomText function wraps a react-native <Text> component with the LanguageConsumer which then passes the current language and the changeLanguage functions, as val to the <Text> component. To render the correct string, we only need access to the current language.

The native <Text> element consists of a simple if statement, in the form of a ternary operator that returns a string in the textArray based on the current language. If the language is Swahili, it will return text[0] if the language is English it will return text[1]. It’s that simple.

3. Using Our Text Element

We can now import and use our CustomText element the same way we would use the native Text element.

import React, { Component } from 'react';
import CustomText from './CustomText.js';
export default class ExampleClass extends Component {
render() {
return (
<CustomText text={["Mambo Dunia", "Hello World"]} />
)
}
}

The above code snippet is an example of a react component that renders a string according to the current language settings.

And thats how simple it is now with react context!

Full Source Code:

The file LanguageContext.js:

import React from 'react'export const LanguageContext = React.createContext({
language: 'swahili', // default language is Swahili
changeLanguage: () => null
});
export class LanguageProvider extends Component {
constructor(props) {
super(props);
this.state = { language: 'swahili' }
this.changeLanguage = this.changeLanguage.bind(this);
}
changeLanguage() {
this.setState({
language: this.state.language === "swahili" ? "english":"swahili"
});
}
render() {
return (
<LanguageContext.Provider
value={{
language: this.state.language,
changeLanguage: this.changeLanguage
}}>
{this.props.children}
</LanguageContext.Provider>
)
}
}

The file CustomText.js:

import React, { Component } from 'react';
import { Text } from 'react-native';
import {
LanguageProvider,
LanguageConsumer
} from './LanguageContext';
export default function CustomText (textArray) {
return (
<LanguageProvider>
<LanguageConsumer>
{
({ language }) => (
<Text>
{
language === 'swahili' ?
textArray[0] : textArray[1]
}
</Text>
)
}
</LanguageConsumer>
</LanguageProvider>
)
}

And how we use our new CustomText component:

import React, { Component } from 'react';
import CustomText from './CustomText.js';
export default class ExampleClass extends Component {
render() {
return (
<CustomText text={["Mambo Dunia", "Hello World"]} />
)
}
}

Bonus: Toggling the Current Language

To toggle the current language is done by calling the changeLanguage function that is also provided by the LanguageConsumer:

class AnotherClass extends Component {
render() {
return (
<LanguageProvider>
<LanguageConsumer>
{
({ changeLanguage }) => (
<TouchableOpacity
onPress={changeLanguage}
>
<CustomText
text={[
"Badilisha Lugha",
"Change Language"
]} />
</TouchableOpacity>
)
}
</LanguageConsumer>
</LanguageProvider>
)
}
}

React Context is an amazing way to avoid “prop drilling” and just pass props to the element that needs it the most.

Working at the intersection of technology and impact. Love for anything technology, passionate about anything Africa.