Kingsley Ubah 21. Web Developer. Technical Writer. African in Tech.

Creating a resume builder app in React Native

7 min read 2006

The most effective way to learn how to code is by building real-life applications and putting yourself through actual project work. You’ll understand the syntax better, learn to research more effectively, become a better problem-solver, hone your UI/UX design skills, and understand the nuances that merely watching a tutorial won’t provide you.

Keeping this in mind, let’s build a resume builder app using React Native. In this tutorial, you’ll learn some important practical skills and techniques for mobile development.

Jump ahead:

Resume builder app project overview

A resume, or CV, is a document used by a person to present their skills, work experience, and accomplishments to a prospective employer. Resume builder apps make it easier to do so by prompting the user to fill in various fields with the appropriate information, then generating a clean, styled resume with that information.

In this project, we will create a resume builder app in React Native. The app’s user interface will include two screens.

The first screen will contain various input fields containing prompts for the user to provide information relevant to their resume, including their name, contact details, and past work experience:

Resume Builder App Form Screen With Input Fields Separated Into Sections Such As Personal Details And Contact Details. App Background Is Dark Blue. Section Title Text Is Yellow. All Other Text Is White. Teal Line Separates App Title From Form Fields

Depending on the size of the user’s device, the number of fields shown in the viewport at any given time may vary. Once the user scrolls to the end of the form, they should see a button to submit their information:

End Of Resume Builder App Form With Final Fields And Teal Button To Create Resume

After the user submits the form, we’ll collect all that information and display the resume on a second screen, as shown in the image below:

Resume Builder App Showing Beginning Of Final Generated Resume

See the full source code for this project on Expo Snack.

Creating the form inputs for collecting user data

At this point, you should have your Expo Snack project ready to edit. If so, create a new folder named screen in the root folder of your project. Next, create two files in the screen folder —  ResumeForm.js and ShowCV.js.

Inside ResumeForm.js, start by importing React, the useState() Hook, and the various components for building out the UI, then define a barebone ResumeForm component function as follows:

import * as React from 'react';
import { Text, View, StyleSheet, TextInput, Button, TouchableOpacity } from 'react-native';
import { useState } from 'react'


export default function ResumeForm({ navigation }) {
    return (
        // JSX goes here
    )
}

Before we start specifying the elements to render in return, let’s define the component state with the useState() Hook.

Add the following code just before the return statement:

  const [userDetails, setUserDetails] = useState({
    fullName: '',
    avatarUrl: '',
    profTitle: '',
    phoneNo: '',
    email: '',
    website: '',
    company: '',
    jobTitle: '',
    jobStartDate: '',
    jobEndDate: '',
    experience: '',
    profSummary: '',
    certificate: '',
    collegeName: '',
    colStartDate: '',
    colEndDate: '',
    skill: '',
    hobby: ''
  });

This object contains the information the user is required to provide via the form inputs. At the moment, it’s all empty. But we’ll use the setter method — setUserDetails — to populate each state branch as the user types into their corresponding form inputs.

Next, in the return statement, create the container <View> element and a title text inside of it:

<View style={styles.container}>      
   <View style={styles.header}>
      <Text style={styles.headerText}>Resume Builder</Text>        
   </View>

   // Input groups will go here
</View>

Now we need to start creating the different input groups.

Creating the various resume input groups

The first input group is for collecting the user’s personal information — name, avatar URL, and job title.

We are collecting the data using React Native’s TextInput element. Here’s the code to achieve this, which you should add inside the container View:

<View style={styles.details}>
         <Text style={styles.titleText}>Personal Details</Text>        
          <TextInput 
            style={styles.textinput} 
            placeholder="Enter your full name" 
            value={userDetails.fullName}          
            onChangeText={(e) => {
              setUserDetails(userDetails => ({
                ...userDetails, ...{'fullName': e}
              }));
            }}
          />
          <TextInput 
            style={styles.textinput} 
            placeholder="Enter your avatar URL" 
            value={userDetails.avatarUrl}  
            onChangeText={(e) => {
              setUserDetails(userDetails => ({
                ...userDetails, ...{'avatarUrl': e}
              }));
            }}        
          />
          <TextInput style={styles.textinput} 
            placeholder="Enter your professional title" 
            value={userDetails.profTitle} 
            onChangeText={(e) => {
                setUserDetails(userDetails => ({
                  ...userDetails, ...{'profTitle': e}
                }));
              }}         
          />
</View>

Each TextInput has an onChangeText property, which updates the state in real-time as the user types into the form input. Each setUserDetails call updates only the corresponding branch in the state.

Let’s look at the third form input group as another example. The third form group is for collecting the user’s work experience information — previous job, start and end date, and a description of that job experience:

<View style={styles.details}>
         <Text style={styles.titleText}>Previous Job</Text>                  
          <TextInput 
            style={styles.textinput} 
            placeholder="Enter company name" 
            value={userDetails.company}
            onChangeText={(e) => {
              setUserDetails(userDetails => ({
                ...userDetails, ...{'company': e}
              }));
            }}
          />                  
          <TextInput style={styles.textinput} placeholder="Enter job title" value={userDetails.jobTitle}               
          onChangeText={(e) => {
              setUserDetails(userDetails => ({
                ...userDetails, ...{'jobTitle': e}
              }));
            }}
          />                    
          <TextInput style={styles.textinput} placeholder="Enter start date (e.g. 11/11/2022)" value={userDetails.jobStartDate}              
          onChangeText={(e) => {
              setUserDetails(userDetails => ({
                ...userDetails, ...{'jobStartDate': e}
              }));
            }}
          />
          <TextInput style={styles.textinput} placeholder="Enter end date (e.g. 12/11/2022)" value={userDetails.jobEndDate}
          onChangeText={(e) => {
              setUserDetails(userDetails => ({
                ...userDetails, ...{'jobEndDate': e}
              }));
            }}
          />
          <TextInput style={styles.textinput} placeholder="Describe your experience" value={userDetails.experience}                   
          onChangeText={(e) => {
              setUserDetails(userDetails => ({
                ...userDetails, ...{'experience': e}
              }));
            }}
          />
 </View>

To keep things simple, we used TextInput for the dates. You can integrate a React Native date picker library like react-native-date-picker to make the project more interesting.

The second and fourth form groups use the same format as the ones covered so far, so I’ve excluded them to keep things short. You can refer to the Expo Snack repo to see what else we included in this example resume builder app.

Creating the button to submit resume information

Below the form input groups, let’s create the button for submitting the form using React Native’s Button component:

  <Button
        title="Create Resume"
         style={styles.button}
         onPress={() => navigation.navigate('ShowCV', userDetails)}
         >           
  </Button>

Here, we specified that when the user presses the button, we want to navigate them to the ShowCV screen, passing along the user’s resume information as the parameter. We will render the resume details to the user on the ShowCV screen.



We’ll create ShowCV.js in the next section. But first, let’s add some styling to our React Native resume builder app.

Underneath the Resume function, paste the following stylesheet to make the form look better:

const styles = StyleSheet.create({
  cont: {
    flex: 1,    
    backgroundColor: '#36485f',
    paddingLeft: 40,
    paddingRight: 40,        
    paddingTop: 40
  },  
  header: {    
    marginBottom: 20,
    alignSelf: 'stretch'
  },
  details: {
    marginBottom: 15
  },
  headerText: {
    fontSize: 24,
    color: '#fff',    
    borderBottomColor: '#199187',
    paddingBottom: 10,
    borderBottomWidth: 1
  },  
  titleText: {
    fontWeight: 'bold',
    color: 'yellow',
    fontSize: 15,
    marginBottom: 10
  },
  textinput: {
    alignSelf: 'stretch',
    height: 40,
    color: '#d3d3d3',
    marginBottom: 20,
    borderBottomColor: '#f8f8f8',
    borderBottomWidth: 1
  },
  button: {
    alignSelf: 'stretch',
    alignItems: 'center',
    padding: 10,
    backgroundColor: '#59cbbd',
    marginTop: 5,
    marginBottom: 20,    
  }
});

Your application should now look like this:

Resume Builder App Form Screen With Input Fields Separated Into Sections Such As Personal Details And Contact Details. App Background Is Dark Blue. Section Title Text Is Yellow. All Other Text Is White. Teal Line Separates App Title From Form Fields

Next up, let’s create ShowCV.js.

Rendering the resume

In this section, we’ll create the ShowCV screen to show the user their full resume. Go into your screens/ShowCV.js file and include the following code:

import * as React from 'react';
import { Text, View, StyleSheet, TextInput, Button, TouchableOpacity } from 'react-native';
import { useState } from 'react'


export default function ShowCV({ route }) {
    let dataObj = route.params

    return (
        <View style={styles.container}>      
           <View style={styles.header}>
              <Text style={styles.headerText}>Your Resume</Text>        
           </View>

           // Resume details go here
        </View>
    )
}

When navigating from one screen to another, the destination screen has access to the root object. We’ll set up React Navigation in the next section.

Inside the ShowCV function above, we assigned the route.params object passed from the ResumeForm screen to a new variable.

Next, render the details on the screen, starting with the user’s personal details  —  name, avatar image, and job title:

<View style={styles.details}>
         <Text style={styles.titleText}>Personal Details</Text>        
         <Image
          source={{ uri: dataObj.avatarUrl }}
          style={{ width: 80, height: 80 }}
          /> 
          <Text style={styles.text}>
            <Text style={styles.key}>Name: </Text>
            <Text>{dataObj.fullName}</Text>
          </Text>    

          <Text style={styles.text}>
            <Text style={styles.key}>Professional Title: </Text>
            <Text>{dataObj.profTitle}</Text>
          </Text>  
</View>

We get the image URL from the avatarUrl property, the name from the fullName property, and the title from the profTitle property.

The rest of the form groups are rendered in a similar way. We nest two Text elements inside the main one. One contains the name of the property, such as Professional Title. The other contains the actual value from dataObj, such as Web Developer.

Once again, you can refer to the Expo Snack project to get the full source code.

When you’re done with the view, the next step is to make it look good. Paste the following stylesheet code underneath the ShowCV function:

const styles = StyleSheet.create({
  cont: {
    flex: 1,    
    backgroundColor: '#36485f',
    paddingLeft: 40,
    paddingRight: 40,        
    paddingTop: 40
  },  
  header: {    
    marginBottom: 20,
    alignSelf: 'stretch'
  },
  details: {
    marginBottom: 15
  },
  headerText: {
    fontSize: 24,
    color: '#fff',    
    borderBottomColor: '#199187',
    paddingBottom: 10,
    borderBottomWidth: 1
  },  
  titleText: {
    fontWeight: 'bold',
    color: 'yellow',
    fontSize: 15,
    marginBottom: 10
  },
  key: {
    fontWeight: 'bold'
  },
  text: {
     color: '#d3d3d3',
  }
});

Both screens are now set. The next step is to create a screen navigator in App.js to connect both screens together.

Connecting the two screens

Inside App.js, start by importing the following dependencies:

import * as React from 'react';
import ResumeForm from './screens/ResumeForm'
import ShowCV from './screens/ShowCV'

import { NavigationContainer } from "@react-navigation/native"
import { createNativeStackNavigator } from "@react-navigation/native-stack"

On lines two and three, we imported the two screens we just created. Then, we imported NavigationContainer from @react-navigation/native and createNativeStackNavigator from @react-navigation/native-stack to help us connect the screens.


More great articles from LogRocket:


We need to install both of those libraries before we can use them.

If you’re following this tutorial on Expo Snack, you’ll get a message at the bottom of the screen prompting you to install both libraries. Accept all the prompts, including the prompts to install react-native-screens and react-native-safearea — both are needed for react-navigation to work.

Next, call createNativeStackNavigator to retrieve the Stack:

const Stack = createNativeStackNavigator()

This Stack allows you to “stack up” the screens you want to transition between in your app.
Create the App component function and return both screens in the <Stack.Navigation> as shown below. Make sure to wrap the Stack.Navigator in the <NavigationProvider> or it won’t work:

export default function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen 
          name="Resume"
          component = {ResumeForm}
        />

        <Stack.Screen 
          name="ShowCV"
          component = {ShowCV}
        />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

The ResumeForm screen is placed on top of the stack, meaning the app will first render the ResumeForm component when it finishes loading.

Now everything is set. You can test the app by filling out the form and clicking the Create Resume button. You should see all the information in the ShowCV screen as follows:

Resume Builder App Showing Beginning Of Final Generated Resume

Conclusion

Now you know all it takes to build a resume builder app in React Native. We covered the technique for navigating between screens in React Native applications.

I recommend that you just don’t stop here — build on this React Native tutorial to customize and enhance this resume builder app. For example, you can validate the form inputs to make sure that they are filled before the form can be submitted.

Also, you can integrate a date picker library like react-native-date-picker to enforce custom rules for the start and end dates in your form or ensure that the dates are valid. Both are great opportunities to learn new things.

Thanks for following and have a great week.

LogRocket: Instantly recreate issues in your React Native apps.

LogRocket is a React Native monitoring solution that helps you reproduce issues instantly, prioritize bugs, and understand performance in your React Native apps.

LogRocket also helps you increase conversion rates and product usage by showing you exactly how users are interacting with your app. LogRocket's product analytics features surface the reasons why users don't complete a particular flow or don't adopt a new feature.

Start proactively monitoring your React Native apps — .

Kingsley Ubah 21. Web Developer. Technical Writer. African in Tech.

Leave a Reply