Recreating Spotify using GraphQL & React Native

Recreating Spotify using GraphQL & React Native

In this post we look at how to recreate Spotify Playlists using the popular data query and manipulation language for APIs GraphQL and React Native

If you learn anything then please subscribe!

Vue is a progressive framework for building user interfaces. The core library is focused on the view layer only, and is easy to pick up and integrate with other libraries or existing projects. Vue is also perfectly capable of powering sophisticated Single-Page Applications when used in combination with modern tooling and supporting libraries.

GUI Automation using Python| Python Automation

30 Days of Python | Unlock your Python Potential

Complete Python Programming with examples for beginners

Selenium WebDriver and Python: WebTest Automation Course

In 2015 Facebook released their internally built data query and manipulation language for APIs GraphQL and it has since risen to the forefront of our minds, in part due to the adoption by big names such as Twitter, Paypal and the New York Times. In fact, the State of JavaScript 2018 listed GraphQL second only to Redux as the world’s favourite Data Layer technology.

With that in mind, it’s useful to understand where GraphQL strengths and weaknesses lie. In this tutorial i’m going to guide you through creating a screen that hopefully a lot of you are familar with; the Spotify Playlist. With any luck you’ll get a better understanding of how GraphQL can benefit your applications and drive you to explore the technology in more detail.

Creating the View

As with any (good) application we’re going to need to piece together a great looking frontend experience to display our data in a way that appeals to our users, Spotify is no different. To get us going we’re going to use React Native to build our mobile application, running Expo to make development on our devices easier. We’ll get to the GraphQL part later on in this tutorial, once we have our application up and running.

First off we’ll install Expo and get our React Native template created. To install Expo simply run:

npm install -g expo-cli

Now to set up the folder structure and all the necessary files needed you run:

expo init spotify-playlist

  • When asked to ‘Choose a template’ select ‘blank
  • When prompted to “enter a few initial configuration values” change the application name to ‘Spotify Playlist

After the inital setup has completed you can start up your application by navigating to your newly created folder and running:

npm start

If you’re new to Expo it’s easy to get started. After running npm start you’ll be presented with all the instructions on how to test your application with your device/simulator. To test on your device it’s as simple as scanning the QR code using the Expo iOS/Android App.

Once running you should see the default screen saying “Open up App.js to start working on your app!”

Let’s start by creating the basic container for the application. The Spotify Playlist screen consists of two main elements, a header with a gradient background and a list of all the playlist items. To recreate these two elements open up your App.js and replace it with the following:

import React from 'react';
import { StyleSheet, ScrollView, FlatList } from 'react-native';
import { LinearGradient } from 'expo';

export default class App extends React.Component {
  render() {
    return (
      <ScrollView contentContainerStyle={styles.container}>
        <LinearGradient colors={['#3f6b6b', '#121212']} style={styles.header} />
        <FlatList style={styles.list} />
      </ScrollView>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    alignItems: 'center',
    justifyContent: 'center',
  },
  header: {
    width: '100%',
    height: 500
  },
  list: {
    width: '100%',
    height: 800,
    backgroundColor: '#121212'
  }
});

App.js

Here we’re creating the two elements; a <LinearGradient /> component from Expo and a <FlatList /> from React Native itself. We’ve added some basic styling and hardcoded the height values just for the time being (we’ll change this height to auto once we’ve got some data in).

Save your file, Expo should hot reload your application which should now look something like this:

We’re now ready to start inserting some placeholder data into our application to start getting the header elements styling correct. For this we’ll need two fonts gibson-regular and gibson-bold which you can download here and here. Add the fonts to the /assetsfolder in your project and we’re ready to start putting the header components together.

Because we are using external fonts we’ll need to load them asyncronously before rendering our components otherwise the fonts won’t yet exist and the application will error. Luckily Expo gives us a nice way of doing this. Add the following to App.js:

import React from 'react';
import { StyleSheet, ScrollView, FlatList, View, Image, Text, TouchableOpacity } from 'react-native';
import { Font, LinearGradient } from 'expo';

export default class App extends React.Component {
  state = { fontLoaded: false };

  async componentDidMount() {
    await Font.loadAsync({
      'gibson-regular': require('./assets/gibson-regular.ttf'),
      'gibson-bold': require('./assets/gibson-bold.ttf')
    });

    this.setState({ fontLoaded: true });
  }

  render() {
    return (
      <View>
        <ScrollView contentContainerStyle={styles.container}>
          <LinearGradient colors={['#3f6b6b', '#121212']} style={styles.header} />
          <FlatList style={styles.list} />
        </ScrollView>
        {this.state.fontLoaded ? (
          <View style={styles.playlistDetails}>
            <Image style={styles.playlistArt} source={{ uri: 'https://github.com/jamiemaison/hosted/blob/master/placeholder.jpg?raw=1' }} />

            <Text style={styles.playlistTitle}>Playlist Name</Text>
            <Text style={styles.playlistSubtitle}>{'BY USER • 000,000 FOLLOWERS'}</Text>
            <TouchableOpacity style={styles.playlistButton}><Text style={styles.playlistButtonText}>SHUFFLE PLAY</Text></TouchableOpacity>
          </View>)
          : null}
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    alignItems: 'center',
    justifyContent: 'center',
  },
  header: {
    width: '100%',
    height: 600
  },
  list: {
    width: '100%',
    height: 800,
    backgroundColor: '#121212'
  },
  playlistDetails: {
    width: '100%',
    height: 600,
    position: 'absolute',
    top: 90,
    display: 'flex',
    alignItems: 'center'
  },
  playlistArt: {
    width: 180,
    height: 180,
  },
  playlistTitle: {
    fontFamily: 'gibson-bold',
    color: '#fff',
    fontSize: 30,
    marginTop: 50
  },
  playlistSubtitle: {
    fontFamily: 'gibson-regular',
    color: '#b9bdbe',
    fontSize: 12,
    marginTop: 15,
    textTransform: 'uppercase'
  },
  playlistButton: {
    backgroundColor: '#2ab759',
    width: 230,
    height: 50,
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
    borderRadius: 100,
    marginTop: 40
  },
  playlistButtonText: {
    fontFamily: 'gibson-bold',
    fontSize: 12,
    color: '#fff',
    letterSpacing: 2
  }
});

App.js

See how we load the font async in componentDidMount and then not render the relevant components until this.state.fontLoaded = true? You may also notice that our playlist items are not children of the <LinearGradient /> component we created earlier. This is because if you look at the Spotify app the playlist items move independently to the top gradient. This parallax effect is one of those subtle things that make some apps look so appealing.

Save your App.js, you should now have something that looks like this.

Recreating the Playlist

Now for the all important part of any playlist, the songs themselves! We’ll achieve this by using a React Native <FlatList />. Again, we’ll just add some mock data for the time being until we set up GraphQL. Modify your App.js to the following:

import React from 'react';
import { StyleSheet, ScrollView, FlatList, View, Image, Text, TouchableOpacity } from 'react-native';
import { Font, LinearGradient } from 'expo';

export default class App extends React.Component {
  state = { fontLoaded: false };

  async componentDidMount() {
    await Font.loadAsync({
      'gibson-regular': require('./assets/gibson-regular.ttf'),
      'gibson-bold': require('./assets/gibson-bold.ttf')
    });

    this.setState({ fontLoaded: true });
  }

  render() {
    return (
      <View>
        <ScrollView contentContainerStyle={styles.container}>
          <LinearGradient colors={['#3f6b6b', '#121212']} style={styles.header} />
          {this.state.fontLoaded ? (
          <FlatList style={styles.list}
            data={[{key: '0', title: 'Title', artist: 'Artist', album: 'Album'}, {key: '1', title: 'Title', artist: 'Artist', album: 'Album'}, {key: '2', title: 'Title', artist: 'Artist', album: 'Album'}, {key: '3', title: 'Title', artist: 'Artist', album: 'Album'}, {key: '4', title: 'Title', artist: 'Artist', album: 'Album'}, {key: '5', title: 'Title', artist: 'Artist', album: 'Album'}, {key: '6', title: 'Title', artist: 'Artist', album: 'Album'}, {key: '7', title: 'Title', artist: 'Artist', album: 'Album'}, {key: '8', title: 'Title', artist: 'Artist', album: 'Album'}, {key: '9', title: 'Title', artist: 'Artist', album: 'Album'}]}
            renderItem={({item}) => (
              <View style={styles.playlistItem}>
                <Text style={styles.playlistItemTitle}>{item.title}</Text>
                <Text style={styles.playlistItemMeta}>{`${item.artist} • ${item.album}`}</Text>
              </View>
            )}
          />) : null }
        </ScrollView>
        {this.state.fontLoaded ? (
          <View style={styles.playlistDetails}>
            <Image style={styles.playlistArt} source={{ uri: 'https://github.com/jamiemaison/hosted/blob/master/placeholder.jpg?raw=1' }} />

            <Text style={styles.playlistTitle}>Playlist Name</Text>
            <Text style={styles.playlistSubtitle}>{'BY USER • 000,000 FOLLOWERS'}</Text>
            <TouchableOpacity style={styles.playlistButton}><Text style={styles.playlistButtonText}>SHUFFLE PLAY</Text></TouchableOpacity>
          </View>)
          : null}
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    alignItems: 'center',
    justifyContent: 'center',
  },
  header: {
    width: '100%',
    height: 510
  },
  list: {
    width: '100%',
    height: 800,
    backgroundColor: '#121212'
  },
  playlistDetails: {
    width: '100%',
    height: 510,
    position: 'absolute',
    top: 90,
    display: 'flex',
    alignItems: 'center'
  },
  playlistArt: {
    width: 180,
    height: 180,
  },
  playlistTitle: {
    fontFamily: 'gibson-bold',
    color: '#fff',
    fontSize: 30,
    marginTop: 50
  },
  playlistSubtitle: {
    fontFamily: 'gibson-regular',
    color: '#b9bdbe',
    fontSize: 12,
    marginTop: 15
  },
  playlistButton: {
    backgroundColor: '#2ab759',
    width: 230,
    height: 50,
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
    borderRadius: 100,
    marginTop: 40
  },
  playlistButtonText: {
    fontFamily: 'gibson-bold',
    fontSize: 12,
    color: '#fff',
    letterSpacing: 2
  },
  playlistItem: {
    marginLeft: 25,
    marginBottom: 25
  },
  playlistItemTitle: {
    fontFamily: 'gibson-bold',
    fontSize: 18,
    color: '#fff'
  },
  playlistItemMeta: {
    fontFamily: 'gibson-regular',
    color: '#b9bdbe',
    fontSize: 15
  }
});

App.js

In this code snippet we are iterating over our data and creating a simple view with a couple of Text components for each piece of data.

If you load up the real Spotify app now you’ll see that upon scrolling the view there’s a little trickery that goes on to hide the playlist text as your thumb moves up the screen as well as gently fading out the album art. There’s a few ways to achieve this effect but i’ll show you one way that uses a combination of CSS & JS which hopefully is simple.

Again, open up your App.js and we’ll make a few modifications so that it now looks like this:

import React from 'react';
import { StyleSheet, ScrollView, FlatList, View, Image, Text, TouchableOpacity } from 'react-native';
import { Font, LinearGradient } from 'expo';

export default class App extends React.Component {
  state = { fontLoaded: false, currentScrollPos: 0 };

  async componentDidMount() {
    await Font.loadAsync({
      'gibson-regular': require('./assets/gibson-regular.ttf'),
      'gibson-bold': require('./assets/gibson-bold.ttf')
    });

    this.setState({ fontLoaded: true });
  }

  render() {
    return (
      <View>
        <ScrollView contentContainerStyle={styles.container} onScroll={(event) => {
          console.log(event.nativeEvent.contentOffset.y);
          this.setState({ currentScrollPos: event.nativeEvent.contentOffset.y })
        }}>
          <LinearGradient colors={['#3f6b6b', '#121212']} style={styles.header} />
          {this.state.fontLoaded ? (
            <FlatList style={styles.list}
              data={[{ key: '0', title: 'Title', artist: 'Artist', album: 'Album' }, { key: '1', title: 'Title', artist: 'Artist', album: 'Album' }, { key: '2', title: 'Title', artist: 'Artist', album: 'Album' }, { key: '3', title: 'Title', artist: 'Artist', album: 'Album' }, { key: '4', title: 'Title', artist: 'Artist', album: 'Album' }, { key: '5', title: 'Title', artist: 'Artist', album: 'Album' }, { key: '6', title: 'Title', artist: 'Artist', album: 'Album' }, { key: '7', title: 'Title', artist: 'Artist', album: 'Album' }, { key: '8', title: 'Title', artist: 'Artist', album: 'Album' }, { key: '9', title: 'Title', artist: 'Artist', album: 'Album' }]}
              renderItem={({ item }) => (
                <View style={styles.playlistItem}>
                  <Text style={styles.playlistItemTitle}>{item.title}</Text>
                  <Text style={styles.playlistItemMeta}>{`${item.artist} • ${item.album}`}</Text>
                </View>
              )}
            />) : null}
        </ScrollView>
        {this.state.fontLoaded ? (
          <View style={{...styles.playlistDetails, height: this.calculatePlaylistHeight()}} pointerEvents="none">
            <Image style={this.calculateArtSize()} source={{ uri: 'https://github.com/jamiemaison/hosted/blob/master/placeholder.jpg?raw=1' }} />

            {this.state.currentScrollPos < 103 ? <Text style={styles.playlistTitle}>Playlist Name</Text> : null}
            {this.state.currentScrollPos < 53 ? <Text style={styles.playlistSubtitle}>{'BY USER • 000,000 FOLLOWERS'}</Text> : null}
          </View>) : null}
          {this.state.fontLoaded ? (<TouchableOpacity style={{ ...styles.playlistButton, top: this.calculateButtonPos() }}><Text style={styles.playlistButtonText}>SHUFFLE PLAY</Text></TouchableOpacity>) : null }
      </View>
    );
  }

  calculatePlaylistHeight = () => {
    if (this.state.currentScrollPos > 173) {
      const height = 160 - (this.state.currentScrollPos - 172);
      return height >= 0 ? height : 0;
    }
    return 510; 
  }

  calculateButtonPos = () => {
    return this.state.currentScrollPos < 376 ? 420 - this.state.currentScrollPos : 44;
  }

  calculateArtSize = () => {
    return {
      width: (185 - (this.state.currentScrollPos / 10)),
      height: (185 - (this.state.currentScrollPos / 10)),
      opacity: (1 - (this.state.currentScrollPos / 350))
    };
  }
}

const styles = StyleSheet.create({
  container: {
    alignItems: 'center',
    justifyContent: 'center',
  },
  header: {
    width: '100%',
    height: 510
  },
  list: {
    width: '100%',
    height: 800,
    backgroundColor: '#121212'
  },
  playlistDetails: {
    width: '100%',
    position: 'absolute',
    top: 90,
    display: 'flex',
    alignItems: 'center',
    overflow: 'hidden'
  },
  playlistTitle: {
    fontFamily: 'gibson-bold',
    color: '#fff',
    fontSize: 30,
    marginTop: 50
  },
  playlistSubtitle: {
    fontFamily: 'gibson-regular',
    color: '#b9bdbe',
    fontSize: 12,
    marginTop: 15
  },
  playlistButton: {
    backgroundColor: '#2ab759',
    width: 230,
    height: 50,
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
    borderRadius: 100,
    position: 'absolute',
    left: 90
  },
  playlistButtonText: {
    fontFamily: 'gibson-bold',
    fontSize: 12,
    color: '#fff',
    letterSpacing: 2
  },
  playlistItem: {
    marginLeft: 25,
    marginBottom: 25
  },
  playlistItemTitle: {
    fontFamily: 'gibson-bold',
    fontSize: 18,
    color: '#fff'
  },
  playlistItemMeta: {
    fontFamily: 'gibson-regular',
    color: '#b9bdbe',
    fontSize: 15
  }
});

App.js

Great! We should now have a fully functioning app that behaves just like the playlist section in the Spotify app. A few things to note about the above code:

  • When asked to ‘Choose a template’ select ‘blank
  • When prompted to “enter a few initial configuration values” change the application name to ‘Spotify Playlist

Now that we’ve got the app looking and behaving how we want it’s now time to start introducing GraphQL to the equation to handle the data!

Data Insertion using GraphQL

Before we get into the how let’s understand the what and why. GraphQL is sold as “front end queries made easy”. At its very core, GraphQL is a typed query language that gives developers an easier way to describe and ultimately obtain the data they need.

For the purposes of this tutorial we need some sort of server running where the actual data is going to be stored. This is easily enough done using apollo-server however you’re not here to start writing server code! So just like magic, i’ve created a Apollo Server playground on codesandbox.io that we can use for the purposes of this example. If you’re interested in the code you can view it herehowever if you just want to skip ahead all you need to do is open your favourite browser and navigate to https://rqvj0qw34.sse.codesandbox.io/ - launching this will start the server at that address so be sure to leave it open in the background for the duration of your development!

Now, back to our Spotify App — we’ll want to install the following dependencies for the next part of the tutorial:

  • When asked to ‘Choose a template’ select ‘blank
  • When prompted to “enter a few initial configuration values” change the application name to ‘Spotify Playlist

Which can be installed by running:

npm install --save apollo-boost react-apollo graphql-tag graphql

Now that is sorted let’s get our data from our GraphQL server and display it using the following data query:

{
    playlist {
        name
        creator
        followers
        albumArt
        songs {
            key
            title
            artist
            album
       }
    }
}

GraphQL Query

Hopefully you can see how simple GraphQL makes data queries look, in this example we’re simply requesting one playlist object which has the properties name, creator, followers, albumArt and songs and that songs have key, title, artist and album values.

Let’s fetch and display this data using react-apollo by modiying our App.js to the following:

import React from 'react';
import { StyleSheet, ScrollView, FlatList, View, Image, Text, TouchableOpacity } from 'react-native';
import { Font, LinearGradient } from 'expo';
import ApolloClient from 'apollo-boost';
import { ApolloProvider } from 'react-apollo';
import { Query } from 'react-apollo'
import gql from 'graphql-tag'

const client = new ApolloClient({
  uri: 'https://rqvj0qw34.sse.codesandbox.io/',
})

export default class App extends React.Component {
  state = { fontLoaded: false, currentScrollPos: 0 };

  async componentDidMount() {
    await Font.loadAsync({
      'gibson-regular': require('./assets/gibson-regular.ttf'),
      'gibson-bold': require('./assets/gibson-bold.ttf')
    });

    this.setState({ fontLoaded: true });
  }

  render() {
    return (
      <ApolloProvider client={client}>
        <Query
          query={gql`
              {
                playlist {
                  name
                  creator
                  followers
                  albumArt
                  songs {
                    key
                    title
                    artist
                    album
                  }
                }
              }
            `}
        >
          {({ loading, error, data }) => {
            if (loading || error) return <View />
            return <View>
              <ScrollView contentContainerStyle={styles.container} onScroll={(event) => {
                console.log(event.nativeEvent.contentOffset.y);
                this.setState({ currentScrollPos: event.nativeEvent.contentOffset.y })
              }}>
                <LinearGradient colors={['#3f6b6b', '#121212']} style={styles.header} />
                {this.state.fontLoaded ? (
                  <FlatList style={styles.list}
                    data={data.playlist.songs}
                    renderItem={({ item }) => (
                      <TouchableOpacity style={styles.playlistItem}>
                        <Text style={styles.playlistItemTitle}>{item.title}</Text>
                        <Text style={styles.playlistItemMeta}>{`${item.artist} • ${item.album}`}</Text>
                      </TouchableOpacity>
                    )}
                  />) : null}
              </ScrollView>
              {this.state.fontLoaded ? (
                <View style={{ ...styles.playlistDetails, height: this.calculatePlaylistHeight() }} pointerEvents="none">
                  <Image style={this.calculateArtSize()} source={{ uri: data.playlist.albumArt }} />

                  {this.state.currentScrollPos < 103 ? <Text style={styles.playlistTitle}>{data.playlist.name}</Text> : null}
                  {this.state.currentScrollPos < 53 ? <Text style={styles.playlistSubtitle}>{`BY ${data.playlist.creator} • ${data.playlist.followers} FOLLOWERS`}</Text> : null}
                </View>) : null}
              {this.state.fontLoaded ? (<TouchableOpacity style={{ ...styles.playlistButton, top: this.calculateButtonPos() }}><Text style={styles.playlistButtonText}>SHUFFLE PLAY</Text></TouchableOpacity>) : null}
            </View>
          }}
        </Query>
      </ApolloProvider>
    );
  }

  calculatePlaylistHeight = () => {
    if (this.state.currentScrollPos > 173) {
      const height = 160 - (this.state.currentScrollPos - 172);
      return height >= 0 ? height : 0;
    }
    return 510;
  }

  calculateButtonPos = () => {
    return this.state.currentScrollPos < 376 ? 420 - this.state.currentScrollPos : 44;
  }

  calculateArtSize = () => {
    return {
      width: (185 - (this.state.currentScrollPos / 10)),
      height: (185 - (this.state.currentScrollPos / 10)),
      opacity: (1 - (this.state.currentScrollPos / 350))
    };
  }
}

const styles = StyleSheet.create({
  container: {
    alignItems: 'center',
    justifyContent: 'center',
  },
  header: {
    width: '100%',
    height: 510
  },
  list: {
    width: '100%',
    backgroundColor: '#121212'
  },
  playlistDetails: {
    width: '100%',
    position: 'absolute',
    top: 90,
    display: 'flex',
    alignItems: 'center',
    overflow: 'hidden'
  },
  playlistTitle: {
    fontFamily: 'gibson-bold',
    color: '#fff',
    fontSize: 30,
    marginTop: 50
  },
  playlistSubtitle: {
    fontFamily: 'gibson-regular',
    color: '#b9bdbe',
    fontSize: 12,
    marginTop: 15
  },
  playlistButton: {
    backgroundColor: '#2ab759',
    width: 230,
    height: 50,
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
    borderRadius: 100,
    position: 'absolute',
    left: 90
  },
  playlistButtonText: {
    fontFamily: 'gibson-bold',
    fontSize: 12,
    color: '#fff',
    letterSpacing: 2
  },
  playlistItem: {
    marginLeft: 25,
    marginBottom: 25,
    width: '90%'
  },
  playlistItemTitle: {
    fontFamily: 'gibson-bold',
    fontSize: 18,
    color: '#fff'
  },
  playlistItemMeta: {
    fontFamily: 'gibson-regular',
    color: '#b9bdbe',
    fontSize: 15
  }
});

App.js

In the above code we’re using the <Query /> component from react-apollo to request the data and on data being returned we’re rendering all of our received information. The component also allows us to handle loading or error state which we’re just rendering a blank view at the moment but you can see how this can be used to provide a greater user experience.

Save and run the application now, you should see a fully functioning Spotify Playlist application using data straight from your GraphQL server!

Further Reading

That’s about it for this tutorial, if you have any GraphQL or React quieres you can always reach out on Twitter or Email and i’ll do my best to help! For further reading here’s some other articles that I found interesting:

  • When asked to ‘Choose a template’ select ‘blank
  • When prompted to “enter a few initial configuration values” change the application name to ‘Spotify Playlist

Got a project that you’re looking to get started, think you may need my help with something or simpy want to reach out? Get in touch!

30s ad

React JS and Redux Bootcamp - Master React Web Development

React Tutorial and Projects Course

PHP Symfony 4 API Platform + React.js Full Stack Masterclass

Beginner React (2019). Create a Movie Web App

Master JavaScript from Scratch (with jQuery and React JS)

How to Share Code Between React and React Native

How to Share Code Between React and React Native

Learn how to share code between React and React Native to avoid duplicating logic. Sharing Code Between React and React-Native: What Not to Share. This question of sharing code between React and React Native, in fact, one of the hot topics among React and React native developers all over the world. React and React-Native allow a learn once write anywhere paradigm. This is great, because one tech team can build both your web app and native mobile experience. The problem is developers hate writing things twice. There have been a couple of efforts to build a unifying technology to write an application once and have it work on both web and native.

How to Share Code Between React and React Native

Sharing Code Between React and React-Native: What Not to Share - Ben Ellerby

React and React-Native allow a learn once write anywhere paradigm. This is great, because one tech team can build both your web app and native mobile experience. The problem is developers hate writing things twice. There have been a couple of efforts to build a unifying technology to write an application once and have it work on both web and native. Yet this is not always the best approach. There is value in only sharing your business and state logic; keeping your render code separate.

In this talk I will give real examples from my work with MADE.COM, migrating their web and mobile application to React and React-Native with code sharing as a primary objective.

How to Share Code Between React and React Native

Learn how to share code between React and React Native to avoid duplicating logic

Sharing Code Between React and React Native

React and React-Native allow a learn once write anywhere paradigm. This is great, because one tech team can build both your web app and native mobile experience. The problem is developers hate writing things twice. There have been a couple of efforts to build a unifying technology to write an application once and have it work on both web and native. Yet this is not always the best approach. There is value in only sharing your business and state logic; keeping your render code separate.

React Native vs Flutter | Difference Between React Native & Flutter

React Native vs Flutter | Difference Between React Native & Flutter

This video on React Interview Questions will help you crack your next React interview with ease. React is the most popular front-end JavaScript library today and is being adopted by many big companies like Netflix, Airbnb, New York Times, and many more...

This video on React Interview Questions will help you crack your next React interview with ease. React is the most popular front-end JavaScript library today and is being adopted by many big companies like Netflix, Airbnb, New York Times, and many more. It is also used in small projects by web developers to showcase their skills in the field of web development. The video includes general React interview questions as well as questions focused on Redux, Hooks, and Styling. This video is ideal for both beginners as well as experienced professionals who are appearing for React web development job interviews. Learn the most important React interview questions and answers and know what will set you apart in the interview process.

React Native Tutorial : Build Dota 2 fan app in React Native

React Native Tutorial : Build Dota 2 fan app in React Native

In this video I'll talk about my approach on how I built a react native app, that I've been working on as a side project for ~1 week, for ios and android and what it can do.

In this video I'll talk about my approach on how I built a react native app, that I've been working on as a side project for ~1 week, for ios and android and what it can do.

The idea for the app was basically to help dota fans quickly browse vods of ongoing/previous tournaments, check upcoming matches, read news and play a little prediction mini game.

In the video I explain why I decided not to publish it.

I used a bunch of web scraping(cheerio) from my node backend to get the content needed for the app and a mongo database to store the data.