In this tutorial we are going to be building a simple mobile app using React Native called ‘Music News’ which will pull posts from a WordPress website via the WP REST API and display them to the user every time they tap to read more about the news. We’ll start with this and you can dig more and do more by reading and understanding the documentation.
As mobile developers, integrating a data source is a very important aspect of building mobile apps. Having an organized data source ready for integration would make development easy and also reduce the time taken to build and develop mobile apps.
WordPress as a backend can be very effective if you're building mobile applications that have a lot of consumable content such as a mobile application for a blog, e-commerce website, and so on.
It can provide standard endpoints to return the data you need and also provides standard documentation for all the endpoints you'll require.
To follow through with this lesson, a basic understanding of the following are required:
You also need to have the following installed:
WordPress is the easiest and fastest way to build your website. It's free and open source and it's based off two very popular technologies, PHP and MySQL.
It is stated that over 29% of websites on the internet are WordPress powered websites.
WordPress is also a content management tool. It allows you to manage content posted on your website easily without the need for you to know anything technical and that's great because you don't have to be a programmer to be able to create and manage your website by yourself. There's a wide variety of websites you can build using WordPress and some of them includes:
WordPress can be an excellent tool to create your website because:
React Native is a mobile JavaScript framework for building real native mobile applications for iOS and Android. It’s based on React made by Facebook's engineering team which is a JavaScript library for building user interfaces.
Unlike a hybrid application that allows you to write your code in HTML and CSS and then renders it in a native web view container or component, React Native calls Objective-C and Java APIs respectively to render your JSX (a combination of JavaScript and XML-esque markup which is the standard way React applications are written) codes into user interface components on your device.
Some of the known pros of React Native:
Some of the known cons of React Native:
API stands for Application Programming Interface. It can be seen as a component that allows for interaction between two programming languages, software libraries, software tools, and so on. It also specifies a set of rules that should be followed in order to interact and communicate with underlying data.
An API could mean something else, depending on the context used and in this context, an API refers to a software component we will interact with to provide us with relevant raw data to be used inside our application.
To get started, the first step would be to install the WordPress REST API plugin to our already existing WordPress installation. My WordPress site is on my local device so I'll be installing it there.
We can now proceed to make more Music News posts on our WordPress normally and then visit the endpoint to see it translated into raw data that can be used in our mobile app.
To get started on this, you can follow the official docs on how to set up your React Native environment on your computer.
Once that is done, we need to initiate and create our application project.
$ react-native init MusicNews
Once that is completed, we need to compile and build the application.
1$ react-native run-ios 2 # if using android, you can run the command below 3 $ react-native run-android
How our users navigate around our mobile app is important as developers, we should make navigation as easy and smooth as possible. To configure navigation in our Music News app, we'll use the react-native-router-flux
library to manage navigation between the screens of our app where all the music news posts are, to the screen where we'll read each individual post.
React-native-router-flux is an API on top of React Navigation and it allows you to define routes in one central place for easy management and configuration. To get started with react-native-router-flux
$ npm install react-native-router-flux --save
Now that we have it installed, we go ahead and create our route file and configure all application routing. In the root directory of our Music News app, create a Routes.js
file and the contents would look like:
1// Routes.js 2 import React, { Component } from 'react'; 3 import {Platform} from 'react-native'; 4 5 // import components from react-native-router-flux 6 import {Router, Stack, Scene} from 'react-native-router-flux'; 7 8 // import our screens as components 9 import Home from './screens/Home'; 10 import ViewNews from './screens/ViewNews'; 11 12 export default class Routes extends Component<{}> { 13 14 render() { 15 return( 16 <Router> 17 <Stack key="root" hideNavBar={true}> 18 <Scene key="home" component={Home} title="Home" /> 19 <Scene key="viewnews" component={ViewNews} title="View News"/> 20 </Stack> 21 </Router> 22 ) 23 } 24 }
Also, edit your App.js
file to look like this:
1//App.js 2 import React, { Component } from 'react'; 3 4 import { 5 StyleSheet, 6 View, 7 StatusBar, 8 } from 'react-native'; 9 10 import Routes from './Routes'; 11 12 export default class App extends Component<{}> { 13 14 render() { 15 return ( 16 <View style={styles.container}> 17 <StatusBar 18 backgroundColor="#fff" 19 barStyle="dark-content" 20 /> 21 <Routes/> 22 </View> 23 ); 24 } 25 } 26 27 const styles = StyleSheet.create({ 28 container : { 29 flex: 1, 30 } 31 });
React Native offers inbuilt UI components like the FlatList
, Modal
, Slider
, Text
, and so on. For the design of our home page, we will be using the Shoutem UI
and react-native-render-html
to render all the posts fetched from our WordPress backend.
Now that we've successfully configured routing, we need to create the screens as specified in the Routes file. We'll create a screen folder and create the files as seen below:
1$ npm install --save react-native-render-html 2 $ npm install --save @shoutem/ui 3 $ react-native link 4 $ mkdir screens && cd screens 5 $ touch Home.js ViewNews.js
Copy the code below and paste into your /screens/Home.js
1//screens/Home.js 2 import React, { Component } from 'react'; 3 import { 4 StyleSheet, 5 SafeAreaView, 6 } from 'react-native'; 7 8 import { 9 Subtitle, 10 Screen, 11 Divider, 12 View, 13 Row, 14 ListView, 15 } from '@shoutem/ui'; 16 17 import {Actions} from 'react-native-router-flux'; 18 19 export default class Home extends Component<{}> { 20 21 home(){ 22 Actions.home(); 23 } 24 25 viewNews(newspost){ 26 Actions.viewnews({newspost: newspost}); 27 } 28 29 componentWillMount() { 30 this.fetchMusicNews(); 31 } 32 33 fetchMusicNews = async () => { 34 const response = await fetch("http://localhost/wordpress/wp-json/wp/v2/posts/"); 35 const json = await response.json(); 36 this.setState({ musicNews: json, isLoadingMusicNews: false }); 37 }; 38 39 constructor(props) { 40 super(props); 41 this.renderRow = this.renderRow.bind(this); 42 this.state = { 43 isLoadingMusicNews: true, 44 musicNews: [], 45 } 46 } 47 48 renderRow(post) { 49 const regex = /(<([^>]+)>)/ig; 50 let newspost = { 51 postId: post.id, 52 postDate: post.date, 53 postLink: post.guid.rendered, 54 postTitle: post.title.rendered, 55 postExcerpt: post.excerpt.rendered, 56 postContent: post.content.rendered, 57 postCategory: post.categories, 58 } 59 return ( 60 <Row style={{height: 80}}> 61 <View styleName="vertical stretch space-between"> 62 <Subtitle 63 numberOfLines={2} 64 newspost={newspost} 65 onPress={() => this.viewNews(newspost)}> 66 {post.title.rendered.replace(regex, '').toUpperCase()} 67 </Subtitle> 68 </View> 69 </Row> 70 ); 71 } 72 73 render() { 74 const regex = "/(<([^>]+)>)/ig" 75 const musicNews = this.state.musicNews; 76 return ( 77 <SafeAreaView style={styles.safeArea}> 78 <Screen> 79 <View> 80 <ListView 81 data={musicNews} 82 renderRow={this.renderRow} 83 /> 84 </View> 85 </Screen> 86 </SafeAreaView> 87 ); 88 } 89 } 90 91 const styles = StyleSheet.create({ 92 container: { 93 flexDirection: 'column', 94 backgroundColor: '#fff' 95 }, 96 safeArea: { 97 flex: 1, 98 backgroundColor: '#fff' 99 }, 100 });
In the Home.js
file, we import all the necessary components to build our interface. We create routing functions so we can navigate from page to page. The fetchMusicNews()
is an asynchronous function that allows us to fetch data from our API configured WordPress backend and the componentWillMount()
allows us to fetch the async data after the screen is rendered.
The fetched data is stored in the musicNews state and will be passed to our component during rendering.
In the renderRow()
we define a prop that holds data fetched from our WordPress API and we pass it to the ViewNews
page so we don't have to do a network fetch to get the same data on the next screen. The data fetched is rendered as a list view using the ListView
component imported from our UI library and the data is also rendered accordingly.
Our render()
function renders the screen and we use the SafeAreaView
component to handle the screens of newer device screen like the ones of the iPhone X and higher so the screen doesn't overlap. Our styles are also defined for different components and the applied to style individual components based on the defined rules.
Copy the code below and paste into your /screens/ViewNews.js
1// screens/ViewNews.js 2 import React, { Component } from 'react'; 3 import { 4 StyleSheet, 5 SafeAreaView, 6 ScrollView, 7 Dimensions, 8 } from 'react-native'; 9 10 import { 11 Tile, 12 Title, 13 Screen, 14 Divider, 15 View, 16 Overlay 17 } from '@shoutem/ui'; 18 19 import {Actions} from 'react-native-router-flux'; 20 import HTML from 'react-native-render-html'; 21 22 export default class ViewNews extends Component<{}> { 23 24 home(){ 25 Actions.reset('home'); 26 Actions.home(); 27 } 28 29 constructor(props) { 30 super(props); 31 this.state = { 32 newspost: [], 33 } 34 } 35 render() { 36 const news = this.state.newspost; 37 const regex = /[!@#$%^&*<>0-9;]/g; 38 console.log("newspost: "+this.props.newspost); 39 return ( 40 <SafeAreaView style={styles.safeArea}> 41 <Screen style={{ flex: 1 }}> 42 <ScrollView> 43 { 44 <View> 45 <Tile> 46 <Overlay styleName="image-overlay"> 47 <Title style={{color: '#fff', fontWeight: '800'}} styleName="md-gutter-bottom">{this.props.newspost.postTitle.replace(regex, "").toUpperCase()}</Title> 48 </Overlay> 49 </Tile> 50 <Screen style={{paddingLeft: 15, paddingRight: 15, paddingTop: 15, paddingBottom: 15, width:375}} styleName="paper"> 51 <HTML 52 tagsStyles={{ 53 body: {fontSize: 20}, 54 p: {fontSize: 20, fontWeight: "normal"}, 55 strong: {fontSize: 20,}, 56 blockquote: {fontSize: 20}, 57 a: {fontSize: 20, color: "#000"}, 58 em: {fontSize: 20,}, 59 img: {height: 250, width: 350}, 60 }} 61 styleName="paper md-gutter multiline" 62 html={this.props.newspost.postContent} 63 imagesMaxWidth={Dimensions.get('window').width} 64 ignoredStyles={['width', 'height', 'video']} 65 onLinkPress={(evt, href) => this.onLinkPress(href)} 66 /> 67 <Divider styleName="line" /> 68 </Screen> 69 </View> 70 } 71 </ScrollView> 72 </Screen> 73 74 </SafeAreaView> 75 ); 76 } 77 }; 78 79 const styles = StyleSheet.create({ 80 container: { 81 flex: 1, // 1:1 82 flexDirection: 'column', 83 backgroundColor: '#fff' 84 }, 85 safeArea: { 86 flex: 1, 87 backgroundColor: '#fff' 88 }, 89 });
In the ViewNews.js
file, we also import all the necessary components to build our interface. We create routing functions so we can navigate from page to page. The regex variable is a regular expression. We use it to remove some unwanted characters and symbols from our WordPress data.
In the render()
function, we go ahead to fetch the data we stored in props from our Home.js
and render it using our HTML component. The HTML component is used to render the data because the news item body sent from our WordPress API is sent with an HTML format and we can perform some extra functions like setting image size and dimensions, ignore styles, etc.
To build and compile our code:
1$ react-native run-ios 2 # If you want to build for android,you can use the command below 3 $ react-native run-android
If you are running this on your local host, chances are that you would get a network error. This is because
localhost
and127.0.0.1
would refer to the internal React native app. You should replace them with the public IP of your machine or tunnel your localhost via ngrok
If you want to tunnel your WordPress app via ngrok, you can take the following steps:
wp-config
:
define('WP_SITEURL', 'http://' . $_SERVER['HTTP_HOST']);
define('WP_HOME', 'http://' . $_SERVER['HTTP_HOST']);After the build is successful, your application should look like
We can see how easy it is to use our WordPress data in our mobile application using the WP REST API Plugin. Our data can be integrated with any mobile development framework and web development framework also.
Our Music News app is simple right now, but you can go ahead to add some more styling and explore the Plugin documentation more to be able to build complex and robust applications on top of your WordPress data.
The code base to this tutorial is available in a publicly hosted GitHub repository. Feel free to experiment around with it.