Build a React Native Twitter UI Replica

For this app, we will need access to a simple api we can get random data from so we will go with RandomUser Api.
React native is very powerful and its amazing the amount of magic that can be achieved with it.
Lets setup a fresh react native environment:
react-native init Twitter
Cd into our project folder and run the fresh app on either IOS or Androidemulator. We will use the android emulator in the course of this article.
cd Twitter
Command to run our app on the android emulator (Make sure you have your android emulator already running) :
react-native run-android
For IOS:
react-native run-ios
Great! Now that our environment is set up, lets get our hands dirty. We will install all dependencies needed to build our Twitter app. We will be making use of React Navigation — a routing and navigation helper for React Native apps built to replace the now deprecated NavigatorExperimental
and the not so powerful Navigator
, a JS-based solution launched with React Native.
We will also be using Axios — a promise based http client for javascript — to make api calls for data fetching, and also React Native Vector Icons.
To install these dependencies, run the following command in your Twitter
directory:
npm install react-navigation axios react-native-vector-icons
Run npm install
again incase you encounter any errors after refresh
We want to create a LoadingScreen
component. This is usually where authentication and necessary local app data fetching is done before switching to the main app. We wont be performing any authentication but we will be having a screen that displays the huge twitter bird, the one that comes on when the Twitter app is opened. Let’s create a LoadingScreen
component for this:
Create a Loading.js
file in your /screens
folder. We will use the Entypo twitter logo, which will be placed at the center of the screen. The Loading.js file should look like this:
Now lets go back to our App.js file. We will remove the export default
in front of the App
class, then export in its stead the AppNavigator
, a SwitchNavigator
that switches between the loading screen and the app screen, setting the LoadingScreen
as the initial route, that is when we open the app, the LoadingScreen
is displayed first.
Make sure you import the LoadingScreen
and the SwitchNavigator
:
import {SwitchNavigator} from ‘react-navigation’
import LoadingScreen from ‘./screens/Loading’
Lets reload the app to see changes made:

Note: if you are using an android emulator and the twitter icon happens to not show, add the following line to your andoid/app/build.gradle
file:
apply from: “../../node_modules/react-native-vector-icons/fonts.gradle”
save, then run react-native run-android
again.
😀 Our SwitchNavigator
now works perfectly, switching between the LoadingScreen
and the App
Creating the App
As everyone who has or is using the Twitter app knows, Twitter uses a slidable drawer navigator. Lets implement this in our App
stack.
create a AppStack
drawer Navigator with the createDrawerNavigator
function provided by react-navigation
:
The AppStack
component will contain links to the Home and Profile page.
Replace the App
component to which the App route in our previous AppNavigator
component points to with our newly created AppStack
component. This way, when the SwitchNavigator, switches from the LoadingScreen
to the App screen, it points to the AppStack
component.
{
AuthLoading: LoadingScreen,
App: AppStack,
}
Make sure you import the createStackNavigation
function from react-navigation
:
import {SwitchNavigator, createDrawerNavigator} from 'react-navigation'
Lets refresh our app to see these changes; do this by hitting the ‘R’ key twice on your keyboard, if your are using an emulator, or otherwise by shaking your physical device.

Our drawer navigator now works.
React Native offers a default look for drawer navigators but in this case we need to design this to look as it would in a real Twitter app.
This is where the custom content component for React Navigation drawers come in.
We can achieve this by specifying a custom component with the contentComponent
property of the createDrawerNavigator
function:
We tell createDrawerNavigator
through its contentComponent
props to use the DrawerContainer
component we will be creating as its default look.
Now lets create the DrawerContainer
component:
Create a screens/DrawerContainer.js
file:
Import the DrawerContainer
:
import DrawerContainer from './screens/DrawerContainer'
Lets refresh the app to see the changes:

We now have a custom drawer navigator.
For y’all Twitter DayMode lovers, sorry NightMode fan here 😜
The custom drawer component receives the navigation
props from the Drawer Navigator. This enables the routing to the other screens in the drawer by calling itsnavigate
method, for instance:
onPress={() => navigation.navigate('Profile')}
The above code routes the user to the Profile
route registered in the Drawer Navigator.
You can specify your own image in the stead of the avatar.png image used in the drawer navigator.
Now that our Drawer Navigator
is up and running, lets design the home page, which will contain a TabNavigator
of four tabs: Home, Search, Notifications, DM.
The TabNavigator
in React Native provides a tab-based style of navigation, one very common on most mobile apps. They can be positioned either at the top or at the bottom of the screen.
Twitter uses a bottom tab navigator, so we will be creating a bottom tab navigator with the createTabNavigator
function, which has other derivates like the createMaterialBottomTabNavigator and createMaterialTopTabNavigator, although outside the scope of this article. But you can refer to the official React Navigation documentation for a more comprehensive information.
Lets create a Tab Navigator:
The HomeTabs
component is created with the createTabNavigator
function which takes objects as arguments, specifying the route name and their corresponding components, and also the navigation options through the object’s navigationOptions
property.
We have specified icons that will represent each of these tabs through the navigationOptions
property, which is a function that accepts an object argument with atabBarIcon
props.
Lets import all the react-native-vector-icons
types used :
import Ionicons from 'react-native-vector-icons/Ionicons'
import Octicons from 'react-native-vector-icons/Octicons'
import EvilIcons from 'react-native-vector-icons/EvilIcons'
import FontAwesome from 'react-native-vector-icons/FontAwesome'
For this article, we will only design the Home tab, which is your regular timeline with series of tweets. We will however create a dummy page for the rest of the tabs (Search, Notifications and DM).
Dummy Page:
The Dummy page is a component that displays a blank page with the huge twitter icon at its center, just like we did for the LoadingScreen
component.
Don’t forget to import the Entypo
icon:
import Entypo from 'react-native-vector-icons/Entypo'
Now that we have our DummyScreen
for the rest of the tabs, lets create a simple page for the home tab then check to see what our app looks like:
- Replace the yet to exist
Home
component that the Home route of ourHomeTabs
component points to with a page that displays ‘hello, this is your timeline’:
Home: {
screen: ()=> <View>
<Text>Hello, this is your timeline</Text>
</View>,
},
Search: {
.
.

We are getting there!!
We have successfully set up our tab navigator.
On clicking the home icon, we are taken to the screen that shows “Hello, this is your timeline”.
We will now redesign this page to contain tweets like it would on a timeline.
Designing the Timeline:
The timeline will be a ListView
which we will give a padding at the top that equals the navigation bar — which will have an absolute positioning — in height.
We will have 3 animated values:
scrollAnimatedValue
: representing the current scroll y position of ourListView
navOffsetAnimatedValue
: this will help us position the navigation bar. With it, we can decide to show or hide the navigation bar at the end of each scroll, depending on the direction of said scroll.clampedScroll
: This will help us animate the navigation bar. It is the result of the addition ofscrollAnimatedValue
andnavOffsetAnimatedValue
given to theAnimated.diffClamp
function. It will help show the navigation bar when scrolling up and to hide it when scrolling down.
Read more about Animated.diffClamp here
Now lets attach the animated values to the views and also add some interpolations in order to map them to the translation of the navigation bar view.
Read more about React native Animated here
When the user stops scrolling, and the navigation bar is half collapsed, it will look better to render it either to a fully displayed state or a fully hidden state. We will achieve this by adding functionalities to detect the event at which a scroll ends :onScrollEndDrag
,onMomentumScrollBegin
and onMomentumScrollEnd
functions.
A short timer is started at onScrollEndDrag
and its cleared in onMomentumScrollBegin
.
When the user scrolls normally, the method that handles animating the navigation bar is delayed for some milliseconds before its called. On the other hand, if its a fast/momentous scroll, the timer is cleared and our method will get called in onMomentumScrollEnd
.
That said, we need to know whether to hide or show the navigation bar, which requires that we know the values of the Animated values used.
We will achieve this by adding listeners to said values then save it in an instance variable to be accessed in the onMomentumScrollEnd
method. Note that the same calculations done in diffClamp will be done manually because the values returned from Animated.diffClamp
does not support the addition of listeners.
componentWillUnmount() {
this.state.scrollAnim.removeAllListeners();
this.state.offsetAnim.removeAllListeners();
}
The onMomentumScrollEnd
method contains the logic to hide or show the navigation bar. We will animate the offset. By adding to its current value, the navigation bar is hidden, while its shown by subtracting from its current value:
We check the clampedScrollValue whether or not it’s passed half of the navigation bar. We will also make sure we don’t hide it while we haven’t scrolled yet, to avoid showing a blank space where the navigation bar is supposed to be.
Now that we have setup the animation for the timeline, we can proceed to implement a ListView of tweets.
Creating a reusable tweet component
Create a screens/Tweet.js file. Tweet.js
will be a reusable component used across the app which displays a singular tweet as shown in the image below.

We will design our Tweet.js
component like the above then import it to the home screen (Home.js
)
Tweet.js uses Random Words module module to generate random words of a certain number as tweet content.
Now that we have a reusable tweet component, we will get random user profiles from the randomuser.me api, and we will generate words as tweet with the Random Words module then pass these data to the tweet component through the ListView
which will serve as our timeline.
Here is the final code for our Home.js
component:

We are making some progress!
Our timeline screen now contains a ListView of series of tweets generated by fetching random user data and random words to form sentences that acts as their respective tweets.
Here is a link to the Git repo:
GitHub is where people build software. More than 28 million people use GitHub to discover, fork, and contribute to over…github.com
Conclusion:
We have designed a night mode Twitter React Native Replica that utilizes the Random User Api to get random user data and also the Random Words module to generate random sentences in form of tweets. In the Part II of this article, we will design the user profile page, the create tweet screen and the tweet thread screen.
Comments and suggestions are highly welcome.
