Using Diffusion with React Native

React Native is one of the most popular front-end frameworks for cross-platform mobile development used today, allowing developers to quickly build modern mobile applications using JavaScript or TypeScript.

The Diffusion JavaScript client is designed to function as a cross-platform library, but there are a couple of configuration steps to be taken before it can be used seamlessly with React Native. If you are new to Diffusion or React Native, we recommend reading through the Diffusion Quick Start Guide and the React Native Quick Start Guide first.

This guide will help you set up a Diffusion + React Native app from scratch, guiding you past some of the hurdles you may come across along the way.

Note that this guide was tested with React Native 0.16.4 and Diffusion 6.4.2.

Set Up

To begin, you'll need a React Native project to work against. If you already have a pre-existing React Native project, feel free to skip to the next section; otherwise, follow the steps below to get a basic project up and running. For ease of use the examples will use Expo to help generate & build the project, but this tutorial is applicable for any type of React Native project.

First, install the Expo CLI

npm install -g expo-cli

Once installed, use it to initialise a new project

expo init diffusion-react-native

Follow the CLI instructions and select an appropriate project type when prompted; if you're unsure, the Blank Managed Workflow option should be fine for most purposes.

Once the project has been initialised, cd into the project directory that was just created. 

Before you begin installing Diffusion, let's start Expo to watch for file changes and run the app in a simulator or on your own device:

expo start

For more information on how to use Expo to test your app, we recommend following the Expo Walkthrough.

Installing Diffusion

To get Diffusion running in React Native, you'll need to add two dependencies: Diffusion and node-libs-react-native. The node-libs-react-native package provides implementations of certain core NodeJS modules that the Diffusion client depends on.

npm install -s diffusion node-libs-react-native

You can now import Diffusion into your React Native project, but it will cause a 'Unable to resolve module zlib" build error due to missing dependencies.

article7_image1

To resolve this error, you'll need to configure the project to make use of the node-libs-react-native package .

Configuring React Native Packager

To use node-libs-react-native within React Native, you'll need to configure the project to make use of the modules it provides as part of the build process.

Create a metro.config.js file in the root directory of the React Native project and set resolver.extraNodeModules:

module.exports = {
  resolver: {
    extraNodeModules: require('node-libs-react-native'),
  },
};

This will address the first build error, but if you have Diffusion installed you'll still see a 'ReferenceError: Can't find variable: Buffer' error.

article7_image2

Importing Globals

To resolve the reference error, the node-libs-react-native package provides a global shim for certain modules. Add the following line to the very start of App.js (or whichever file is the entry point for your app)

import 'node-libs-react-native/globals';

This ensures that the Buffer module can be accessed by Diffusion. You only need to import this package once; it provides access to modules globally across the rest of the project. 

Using Diffusion

With the global shim installed, you can now safely import and use Diffusion. Add the following line to App.js (or whichever file you wish to use Diffusion in) after the rest of the import statements:

import { connect } from 'diffusion';

Use this function to connect to Diffusion within your app. Here's a basic example of how to use Diffusion in combination with React Hooks to manage asynchronous connection state.  This demonstrates how to use the useEffect hook to connect to Diffusion once when the component is mounted, while using useState to pass asynchronous changes to connection status.

import 'node-libs-react-native/globals';

import React, { useState, useEffect } from 'react';
import { StyleSheet, Text, View } from 'react-native';

import { connect } from 'diffusion';

export default function App() {
const [connected, setConnected] = useState(false);

useEffect(() => {
connect({
host:'Your Diffusion hostname',
principal:'Your username',
credentials:'Your password'
}).then(session => {
session.on('disconnect', () => setConnected(false));
session.on('close', () => setConnected(false));

setConnected(true);
});
}, []);

return (
<View style={styles.container}>
<Text>Open up App.js to start working on your app!</Text>
<Text>Diffusion state: {connected ? 'connected' : 'not connected'}</Text>
</View>
);
}

const styles = StyleSheet.create({
container: {
flex:1,
backgroundColor:'#fff',
alignItems:'center',
justifyContent:'center',
},
});