{"id":5593,"date":"2023-02-12T07:44:45","date_gmt":"2023-02-12T07:44:45","guid":{"rendered":"https:\/\/dianapps.com\/blog\/?p=5593"},"modified":"2023-02-17T06:05:33","modified_gmt":"2023-02-17T06:05:33","slug":"building-a-twitter-clone-app-in-react-native","status":"publish","type":"post","link":"https:\/\/www.dianapps.com\/blog\/building-a-twitter-clone-app-in-react-native\/","title":{"rendered":"Building a Twitter Clone App in React Native"},"content":{"rendered":"<p><span style=\"font-weight: 400;\">Getting your hands on new programming languages or frameworks is one of the greatest methods to learn them.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Therefore, we made the decision to build a Twitter clone app while learning <\/span><b>React Native app development<\/b><span style=\"font-weight: 400;\">. In order to demonstrate how to build this app, we will first quickly outline our experience with React Native before getting into the code.<\/span><\/p>\n<h1><span class=\"ez-toc-section\" id=\"Our-Experience-with-React-Native\"><\/span><span style=\"font-weight: 400;\">Our Experience with React Native<\/span><span class=\"ez-toc-section-end\"><\/span><\/h1>\n<h3><span class=\"ez-toc-section\" id=\"1-Code-Excellence\"><\/span><span style=\"font-weight: 400;\">1. Code Excellence<\/span><span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p><span style=\"font-weight: 400;\">When using<\/span> React Native app development services<span style=\"font-weight: 400;\">, brute forcing a solution will leave you with a tonne of source code and little understanding of how it functions. If you fix one item, another will break.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Yes, it&#8217;s not very encouraging, but on the good side, you&#8217;ll have to keep the code quality at a good scale.<\/span><\/p>\n<h3><span class=\"ez-toc-section\" id=\"2-Ease-of-Development\"><\/span><span style=\"font-weight: 400;\">2. Ease of Development<\/span><span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p><span style=\"font-weight: 400;\">A basic understanding of Javascript is required, else, at first glance React Native can appear to be complex science. But be assured, it isn&#8217;t. <\/span>React Native app development<span style=\"font-weight: 400;\"> framework stands apart from other Javascript frameworks in major part because it doesn&#8217;t introduce a tonne of abstraction levels. It keeps you rather near to JavaScript&#8217;s fundamentals.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">So, if you are comfortable with all fundamental DOM and JavaScript ideas, React Native is for you!<\/span><\/p>\n<p><span style=\"font-weight: 400;\">After working on a few projects, you&#8217;ll see that React Native gives you a lot of freedom without significantly increasing the complexity of your work.<\/span><\/p>\n<h3><span class=\"ez-toc-section\" id=\"3-Performance\"><\/span><span style=\"font-weight: 400;\">3. Performance\u00a0<\/span><span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p><span style=\"font-weight: 400;\">React Native compiles JavaScript code into a fully native app, in contrast to previous mobile technologies that offer you a &#8220;mobile app&#8221; that is actually running in webview.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">React Native was found to perform better in a recent performance comparison between an app created using Swift and an identical app created with Swift.<\/span><\/p>\n<h3><span class=\"ez-toc-section\" id=\"4-Community-Support\"><\/span><span style=\"font-weight: 400;\">4. Community Support<\/span><span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p><span style=\"font-weight: 400;\">For their projects, several well-known businesses, start-ups, and independent developers use React Native. The React Native community has grown dramatically over the last several years.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">It gives you the support to create something helpful and enhance an open-source project created by another <\/span>mobile app developer<b>.<\/b><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<h2><span class=\"ez-toc-section\" id=\"Building-a-Twitter-Clone-App-in-React-Native\"><\/span><span style=\"font-weight: 400;\">Building a Twitter Clone App in React Native<\/span><span class=\"ez-toc-section-end\"><\/span><\/h2>\n<h3><span class=\"ez-toc-section\" id=\"1-Getting-Started\"><\/span><strong>1. Getting Started<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p><span style=\"font-weight: 400;\">Node.js, yarn, or NPM must all be installed. We used yarn and node v8.1.2 for our project.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">A new React Native project can be started in a variety of methods; for this one, we used create-react-native-app. Run the following commands to launch a new project and instal CRNA globally:<\/span><\/p>\n<pre class=\"theme:turnwall font-size-enable:false font-size:14 height-set:true height:250 lang:default decode:true\">$ yarn global add create-react-native-app\r\n\r\n$ create-react-native-app twitter-clone\r\n\r\n$ cd twitter-clone\/\r\n\r\n$ yarn start<\/pre>\n<p><span style=\"font-weight: 400;\">Additionally, we have utilized the<\/span><a href=\"https:\/\/expo.io\/\"><span style=\"font-weight: 400;\"> Expo SDK<\/span><\/a><span style=\"font-weight: 400;\"> to avoid having to build both Xcode and Android Studio. Additionally, this will give me access to tools that will facilitate the loading of typefaces and the ability for users to add photographs to the app. Please consult the documentation to get Expo up and running.<\/span><\/p>\n<h3><span class=\"ez-toc-section\" id=\"2-Dependencies\"><\/span><strong>2. Dependencies<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p><span style=\"font-weight: 400;\">We&#8217;ll discuss a few of the most important tools we&#8217;ll be using for this project below.<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">With the help of the <\/span><a href=\"https:\/\/nativebase.io\/\"><span style=\"font-weight: 400;\">Native Base<\/span><\/a><span style=\"font-weight: 400;\"> component library, we can easily create a cross-platform user interface that looks great.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">We may move between the various displays of our app with the aid of <\/span><a href=\"https:\/\/github.com\/aksonov\/react-native-router-flux\"><span style=\"font-weight: 400;\">React Native Router Flux.<\/span><\/a><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><a href=\"https:\/\/github.com\/reactjs\/react-redux\"><span style=\"font-weight: 400;\">React-Redux<\/span><\/a><span style=\"font-weight: 400;\"> will link the various parts of our program to our store, where we&#8217;ll maintain information about its current state.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">We will use <\/span><a href=\"https:\/\/github.com\/mzabriskie\/axios\"><span style=\"font-weight: 400;\">Axios<\/span><\/a><span style=\"font-weight: 400;\">, a promised-based HTTP client, to perform our requests to the Cosmic JS API.<\/span><\/li>\n<\/ul>\n<p><span style=\"font-weight: 400;\">Look at the code below you can make use of your package.json and then run yarn install again.\u00a0<\/span><\/p>\n<pre class=\"theme:turnwall font-size-enable:false font-size:14 height-set:true height:250 lang:default decode:true\">{\r\n\r\n\u00a0\"name\": \"twitter-clone\",\r\n\r\n\u00a0\"version\": \"1.0.0\",\r\n\r\n\u00a0\"private\": true,\r\n\r\n\u00a0\"devDependencies\": {\r\n\r\n\u00a0\u00a0\u00a0\"jest-expo\": \"~1.0.1\",\r\n\r\n\u00a0\u00a0\u00a0\"react-native-scripts\": \"0.0.30\",\r\n\r\n\u00a0\u00a0\u00a0\"react-test-renderer\": \"16.0.0-alpha.6\"\r\n\r\n\u00a0},\r\n\r\n\u00a0\"main\": \".\/node_modules\/react-native-scripts\/build\/bin\/crna-entry.js\",\r\n\r\n\u00a0\"scripts\": {\r\n\r\n\u00a0\u00a0\u00a0\"start\": \"\"react-native-scripts start\",\r\n\r\n\u00a0\u00a0\u00a0\"eject\": \"react-native-scripts eject\",\r\n\r\n\u00a0\u00a0\u00a0\"android\": \"react-native-scripts android\",\r\n\r\n\u00a0\u00a0\u00a0\"ios\": \"react-native-scripts ios\",\r\n\r\n\u00a0\u00a0\u00a0\"test\": \"node node_modules\/jest\/bin\/jest.js --watch\"\r\n\r\n\u00a0},\r\n\r\n\u00a0\"jest\": {\r\n\r\n\u00a0\u00a0\u00a0\"preset\": \"jest-expo\"\r\n\r\n\u00a0},\r\n\r\n\u00a0\"dependencies\": {\r\n\r\n\u00a0\u00a0\u00a0\"@expo\/vector-icons\": \"^5.0.0\",\r\n\r\n\u00a0\u00a0\u00a0\"axios\": \"^0.16.1\",\r\n\r\n\u00a0\u00a0\u00a0\"expo\": \"^17.0.0\",\r\n\r\n\u00a0\u00a0\u00a0\"form-data\": \"^2.2.0\",\r\n\r\n\u00a0\u00a0\u00a0\"native-base\": \"^2.1.4\",\r\n\r\n\u00a0\u00a0\u00a0\"react\": \"16.0.0-alpha.6\",\r\n\r\n\u00a0\u00a0\u00a0\"react-native\": \"^0.44.0\",\r\n\r\n\u00a0\u00a0\u00a0\"react-native-router-flux\": \"^3.39.2\",\r\n\r\n\u00a0\u00a0\u00a0\"react-redux\": \"^5.0.5\",\r\n\r\n\u00a0\u00a0\u00a0\"redux\": \"^3.6.0\",\r\n\r\n\u00a0\u00a0\u00a0\"redux-devtools-extension\": \"^2.13.2\",\r\n\r\n\u00a0\u00a0\u00a0\"redux-logger\": \"^3.0.6\",\r\n\r\n\u00a0\u00a0\u00a0\"redux-thunk\": \"^2.2.0\",\r\n\r\n\u00a0}\r\n\r\n}<\/pre>\n<h3><span class=\"ez-toc-section\" id=\"3-Directory-Structure\"><\/span><strong>3. Directory Structure<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p><span style=\"font-weight: 400;\">CRNA is far less prescriptive about how we organize the files in our application than some other boilerplates; it just provides us with index.ios.js, index.android.js, and App.js as a starting point.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Our App.js file will refer to the app folder, which will include all of our components, layouts, configuration files, redux store, and reducers. The framework that we have discovered to be most effective for us is as follows. The source code has a complete list of the contents of every file, so let&#8217;s not go into it right now.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Here is how our application folder will appear:<\/span><\/p>\n<p><img decoding=\"async\" class=\"alignnone wp-image-5602 \" src=\"https:\/\/dianapps.com\/blog\/wp-content\/uploads\/2023\/02\/code.png\" alt=\"\" width=\"370\" height=\"888\" \/><\/p>\n<h3><span class=\"ez-toc-section\" id=\"4-Application\"><\/span><strong>4. Application\u00a0<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p><span style=\"font-weight: 400;\">Several events will take place in our App.js code. We&#8217;ll do:<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Draw in the paths that lead to our varied layouts.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Connect our provider to our store so that our layouts may access the status of our application.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Give users access to some of the typefaces used by Native Base<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">With AppRegistry, establish our root component.<\/span><\/li>\n<\/ul>\n<p><span style=\"font-weight: 400;\">The following may be copied and pasted into your project root&#8217;s App.js file:<\/span><\/p>\n<pre class=\"theme:turnwall font-size-enable:false font-size:14 height-set:true height:250 lang:default decode:true\">import React, { Component } from 'react';\r\n\r\nimport { AppRegistry, View } from 'react-native';\r\n\r\nimport { Provider, connect } from 'react-redux';\r\n\r\nimport { Font, AppLoading } from 'expo';\r\n\r\nimport store from '.\/app\/redux\/store';\r\n\r\nimport Router from '.\/app\/config\/routes';\r\n\r\nexport default class App extends Component {\r\n\r\n\u00a0constructor(){\r\n\r\n\u00a0\u00a0\u00a0super();\r\n\r\n\u00a0\u00a0\u00a0this.state = {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0isReady: false,\r\n\r\n\u00a0\u00a0\u00a0}\r\n\r\n\u00a0}\r\n\r\n\u00a0async componentWillMount() {\r\n\r\n\u00a0\u00a0\u00a0await Font.loadAsync({\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0'Roboto': require('native-base\/Fonts\/Roboto.ttf'),\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0'Roboto_medium': require('native-base\/Fonts\/Roboto_medium.ttf'),\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0'Pacifico': require('.\/app\/assets\/fonts\/Pacifico.ttf'),\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0'Ionicons': require('native-base\/Fonts\/Ionicons.ttf'),\r\n\r\n\u00a0\u00a0\u00a0});\r\n\r\n\u00a0\u00a0\u00a0this.setState({isReady: true});\r\n\r\n\u00a0}\r\n\r\n\u00a0render() {\r\n\r\n\u00a0\u00a0\u00a0if (!this.state.isReady) {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0return &lt;AppLoading \/&gt;;\r\n\r\n\u00a0\u00a0\u00a0}\r\n\r\n\u00a0\u00a0\u00a0return (\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0&lt;Provider store={store}&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;Router \/&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/Provider&gt;\r\n\r\n\u00a0\u00a0\u00a0);\r\n\r\n\u00a0}\r\n\r\n}\r\n\r\nAppRegistry.registerComponent('main', () =&gt; App);<\/pre>\n<p><span style=\"font-weight: 400;\">Next, let\u2019s take a look at our routes.js file:<\/span><\/p>\n<pre class=\"theme:turnwall font-size-enable:false font-size:14 height-set:true height:250 lang:default decode:true \">import React from 'react';\r\n\r\nimport { Scene, Router, Actions, ActionConst } from 'react-native-router-flux';\r\n\r\nimport Welcome from '..\/layouts\/welcome';\r\n\r\nimport Login from '..\/layouts\/login';\r\n\r\nimport Signup from '..\/layouts\/signup';\r\n\r\nimport NewPost from '..\/layouts\/newPost';\r\n\r\nimport Feed from '..\/layouts\/feed';\r\n\r\nconst scenes = Actions.create(\r\n\r\n\u00a0&lt;Scene key=\"root\"&gt;\r\n\r\n\u00a0\u00a0\u00a0&lt;Scene key=\"welcome\" component={Welcome} title=\"Welcome\" initial={true} \/&gt;\r\n\r\n\u00a0\u00a0\u00a0&lt;Scene key=\"login\" component={Login} title=\"Login\" type={ActionConst.REPLACE} \/&gt;\r\n\r\n\u00a0\u00a0\u00a0&lt;Scene key=\"signup\" component={Signup} title=\"Create New Account\" type={ActionConst.REPLACE} \/&gt;\r\n\r\n\u00a0\u00a0\u00a0&lt;Scene key=\"feed\" component={Feed} title=\"Your Feed\" type={ActionConst.REPLACE} hideNavBar \/&gt;\r\n\r\n\u00a0\u00a0\u00a0&lt;Scene key=\"newPost\" component={NewPost} title=\"Make a new post\" \/&gt;\r\n\r\n\u00a0&lt;\/Scene&gt;\r\n\r\n);\r\n\r\nexport default () =&gt; (\r\n\r\n\u00a0&lt;Router scenes={scenes} \/&gt;\r\n\r\n);<\/pre>\n<p><span style=\"font-weight: 400;\">We&#8217;ve just built a number of scenes that are accessible from wherever in our app using React Native Router Flux.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">The Welcome layout is the opening scene, where users can choose to log in or register a new account. It appears as follows:<\/span><\/p>\n<pre class=\"theme:turnwall font-size-enable:false font-size:14 height-set:true height:250 lang:default decode:true \">import React from 'react';\r\n\r\nimport {\r\n\r\n\u00a0Container,\r\n\r\n\u00a0Content,\r\n\r\n\u00a0Icon,\r\n\r\n\u00a0Text,\r\n\r\n\u00a0Button,\r\n\r\n} from 'native-base';\r\n\r\nimport { View } from 'react-native';\r\n\r\nimport { Actions } from 'react-native-router-flux';\r\n\r\nimport styles from '.\/styles';\r\n\r\nexport default () =&gt; (\r\n\r\n\u00a0&lt;Container style={styles.container}&gt;\r\n\r\n\u00a0\u00a0\u00a0&lt;Content&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0&lt;View style={styles.iconBox}&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;Icon\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0style={styles.icon}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0ios=\"ios-happy-outline\"\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0android=\"md-happy\"\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;Text style={styles.welcome}&gt;Welcome&lt;\/Text&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/View&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0&lt;View style={styles.buttonContainer}&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;Button\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0block\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0style={styles.button}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0onPress={() =&gt; Actions.login()}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;Text&gt;Log in&lt;\/Text&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/Button&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;Text style={styles.or}&gt;OR&lt;\/Text&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;Button\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0block\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0style={styles.button}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0onPress={() =&gt; Actions.signup()}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;Text&gt;Sign up&lt;\/Text&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/Button&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/View&gt;\r\n\r\n\u00a0\u00a0\u00a0&lt;\/Content&gt;\r\n\r\n\u00a0&lt;\/Container&gt;\r\n\r\n)<\/pre>\n<p><span style=\"font-weight: 400;\">Here, we&#8217;ve only used Native Base to construct two buttons that will direct users to the Login and Signup layouts.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">See what occurs when people create a new account by taking a peek at our Signup layout.<\/span><\/p>\n<pre class=\"theme:turnwall font-size-enable:false font-size:14 height-set:true height:250 lang:default decode:true \">import React, { Component } from 'react';\r\n\r\nimport { connect } from 'react-redux';\r\n\r\nimport { ImagePicker } from 'expo';\r\n\r\nimport { Actions } from 'react-native-router-flux';\r\n\r\nimport {View} from 'react-native';\r\n\r\nimport {\r\n\r\n\u00a0Container,\r\n\r\n\u00a0Content,\r\n\r\n\u00a0Button,\r\n\r\n\u00a0Text,\r\n\r\n\u00a0Form,\r\n\r\n\u00a0Thumbnail,\r\n\r\n\u00a0Icon\r\n\r\n} from 'native-base';\r\n\r\nimport axios from 'axios';\r\n\r\nimport TextField from '..\/..\/components\/TextField';\r\n\r\nimport styles from '.\/styles';\r\n\r\nimport { addUser } from '..\/..\/redux\/reducers\/users';\r\n\r\nimport cosmicConfig from '..\/..\/config\/cosmic';\r\n\r\nconst mapDispatchToProps = {addUser};\r\n\r\nconst validate = form =&gt; {\r\n\r\n\u00a0let errorMessage = '';\r\n\r\n\u00a0if (form.username.includes(\" \")){\r\n\r\n\u00a0\u00a0\u00a0errorMessage = \"Username cannot contain spaces\";\r\n\r\n\u00a0}\r\n\r\n\u00a0if (form.password.includes(\" \")){\r\n\r\n\u00a0\u00a0\u00a0errorMessage = \"Password cannot contain spaces\";\r\n\r\n\u00a0}\r\n\r\n\u00a0Object.keys(form).slice(0, 5).map(field =&gt; {\r\n\r\n\u00a0\u00a0\u00a0if (!form[field]){\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0errorMessage = 'All fields must be filled';\r\n\r\n\u00a0\u00a0\u00a0}\r\n\r\n\u00a0})\r\n\r\n\u00a0return errorMessage;\r\n\r\n}\r\n\r\nclass Signup extends Component {\r\n\r\n\u00a0constructor() {\r\n\r\n\u00a0\u00a0\u00a0super();\r\n\r\n\u00a0\u00a0\u00a0this.state = {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0firstName: '',\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0lastName: '',\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0username: '',\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0password: '',\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0image: null,\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0error: '',\r\n\r\n\u00a0\u00a0\u00a0};\r\n\r\n\u00a0}\r\n\r\n\u00a0onSubmit(){\r\n\r\n\u00a0\u00a0\u00a0const error = validate(this.state);\r\n\r\n\u00a0\u00a0\u00a0if (error) {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0this.setState({ error })\r\n\r\n\u00a0\u00a0\u00a0} else {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0this.checkUsername(this.state.username);\r\n\r\n\u00a0\u00a0\u00a0}\r\n\r\n\u00a0}\r\n\r\n\u00a0checkUsername(username){\r\n\r\n\u00a0\u00a0\u00a0axios.get(`https:\/\/api.cosmicjs.com\/v1\/${cosmicConfig.bucket.slug}\/object-type\/users\/search?metafield_key=username&amp;metafield_value=${username}`)\r\n\r\n\u00a0\u00a0\u00a0.then(res =&gt; res.data)\r\n\r\n\u00a0\u00a0\u00a0.then(data =&gt; {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0if (data.objects) {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.setState({ error: 'Username not available'})\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0} else {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.props.addUser(this.state);\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0}\r\n\r\n\u00a0\u00a0\u00a0})\r\n\r\n\u00a0}\r\n\r\n\u00a0uploadImage = async () =&gt; {\r\n\r\n\u00a0\u00a0\u00a0let result = await ImagePicker.launchImageLibraryAsync({\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0allowsEditing: true,\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0aspect: [4, 3],\r\n\r\n\u00a0\u00a0\u00a0});\r\n\r\n\u00a0\u00a0\u00a0if (!result.cancelled) {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0this.setState({ image: result.uri });\r\n\r\n\u00a0\u00a0\u00a0}\r\n\r\n\u00a0};\r\n\r\n\u00a0render(){\r\n\r\n\u00a0\u00a0\u00a0return (\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0&lt;Container style={styles.container}&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;Content&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;Form style={styles.mar10}&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;TextField\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0name=\"First Name\"\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0value={this.state.firstName}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0onChangeText={(text) =&gt; this.setState({firstName: text})}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;TextField\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0name=\"Last Name\"\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0value={this.state.lastName}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0onChangeText={(text) =&gt; this.setState({lastName: text})}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;TextField\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0name=\"Username\"\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0value={this.state.username}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0onChangeText={(text) =&gt; this.setState({username: text})}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;TextField\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0secureTextEntry\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0name=\"Password\"\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0value={this.state.password}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0onChangeText={(text) =&gt; this.setState({password: text})}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/Form&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;Text style={styles.addPic}&gt;Add a profile picture&lt;\/Text&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0!this.state.image &amp;&amp;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;Button\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0primary\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0bordered\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0onPress={this.uploadImage}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0style={styles.uploadButton}&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;Icon\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0ios='ios-camera'\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0android='md-camera'\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/Button&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.state.image &amp;&amp;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;Thumbnail\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0size={80}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0source={{uri: this.state.image}}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0style={styles.thumbnail}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;Button\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0block\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0style={styles.mar10}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0onPress={() =&gt; this.onSubmit()}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;Text&gt;Create account&lt;\/Text&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/Button&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;Text style={styles.formMsg}&gt;{this.state.error}&lt;\/Text&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;Button\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0transparent\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0style={styles.loginBtn}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0onPress={() =&gt; Actions.login()}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;Text style={styles.loginTxt}&gt;Already have an account?&lt;\/Text&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/Button&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/Content&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/Container&gt;\r\n\r\n\u00a0\u00a0\u00a0);\r\n\r\n\u00a0}\r\n\r\n}\r\n\r\nexport default connect(null, mapDispatchToProps)(Signup);<\/pre>\n<p><span style=\"font-weight: 400;\">Several events might happen in this situation:<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">As users fill out the form, the contents of the fields are kept in state.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">We perform some basic validation when users submit to make sure they have entered proper data into the fields.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">In order to confirm that the username they have chosen is not already in use, we then make our first call to the Cosmic JS API.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Finally, we utilize our addUserfunction to submit the form as a new user to the Cosmic JS API after all of the fields have valid input.<\/span><\/li>\n<\/ul>\n<p><span style=\"font-weight: 400;\">Our usersreducer contains a definition for the addUser method that looks like this:<\/span><\/p>\n<pre class=\"theme:turnwall font-size-enable:false font-size:14 height-set:true height:250 lang:default decode:true \">export const addUser = user =&gt; dispatch =&gt; {\r\n\r\n\u00a0let data = new FormData();\r\n\r\n\u00a0data.append('media', {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0uri: user.image,\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0type: 'image\/jpeg',\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0name: 'image'\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0});\r\n\r\n\u00a0return axios.post(`https:\/\/api.cosmicjs.com\/v1\/${cosmicConfig.bucket.slug}\/media`, data)\r\n\r\n\u00a0.then(res =&gt; res.data.media)\r\n\r\n\u00a0.then(media =&gt; {\r\n\r\n\u00a0\u00a0\u00a0return axios.post(`https:\/\/api.cosmicjs.com\/v1\/${cosmicConfig.bucket.slug}\/add-object`, {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0title: user.firstName + ' ' + user.lastName,\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0type_slug: 'users',\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0metafields: [\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0key: 'name',\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0type: 'text',\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0value: user.firstName + ' ' + user.lastName,\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0},\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0key: 'username',\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0type: 'text',\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0value: user.username,\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0},\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0key: 'password',\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0type: 'text',\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0value: user.password,\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0},\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0key: 'profile_picture',\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0type: 'file',\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0value: media.name,\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0]\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0)}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0)\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0.then(res =&gt; formatUser(res.data))\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0.then(formattedUser =&gt; dispatch(createUser(formattedUser)))\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0.then(() =&gt; Actions.feed())\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0.catch(err =&gt; console.error(`Creating user unsuccessful`, err))\r\n\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<p>Here, we use the Cosmic.js API for more than one time. The user\u2019s profile photo will be added to our bucket as media in response to the first request, and the user\u2019s complete information will be added as a new user in reaction to the second call using a reference to the picture we receive back.<\/p>\n<p><span style=\"font-weight: 400;\">The user can log in if they have previously registered an account by:\u00a0<\/span><\/p>\n<pre class=\"theme:turnwall font-size-enable:false font-size:14 height-set:true height:250 lang:default decode:true \">import React, { Component } from 'react';\r\n\r\nimport { connect } from 'react-redux';\r\n\r\nimport {\r\n\r\n\u00a0Container,\r\n\r\n\u00a0Content,\r\n\r\n\u00a0Icon,\r\n\r\n\u00a0Text,\r\n\r\n\u00a0Button,\r\n\r\n} from 'native-base';\r\n\r\nimport { View } from 'react-native';\r\n\r\nimport { Actions } from 'react-native-router-flux';\r\n\r\nimport TextField from '..\/..\/components\/TextField';\r\n\r\nimport styles from '.\/styles';\r\n\r\nimport { authenticate } from '..\/..\/redux\/reducers\/users';\r\n\r\nconst mapDispatchToProps = {authenticate};\r\n\r\nconst validate = form =&gt; {\r\n\r\n\u00a0let errorMessage = '';\r\n\r\n\u00a0if (form.username.includes(' ') || form.password.includes(' ')){\r\n\r\n\u00a0\u00a0\u00a0errorMessage = 'Username and password cannot contain spaces';\r\n\r\n\u00a0}\r\n\r\n\u00a0if (form.username === '' || form.password === ''){\r\n\r\n\u00a0\u00a0\u00a0errorMessage = 'All fields must be filled';\r\n\r\n\u00a0}\r\n\r\n\u00a0return errorMessage;\r\n\r\n}\r\n\r\nclass Login extends Component {\r\n\r\n\u00a0constructor(props) {\r\n\r\n\u00a0\u00a0\u00a0super(props);\r\n\r\n\u00a0\u00a0\u00a0this.state = {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0username: '',\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0password: '',\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0error: '',\r\n\r\n\u00a0\u00a0\u00a0};\r\n\r\n\u00a0}\r\n\r\n\u00a0onSubmit(){\r\n\r\n\u00a0\u00a0\u00a0const error = validate(this.state);\r\n\r\n\u00a0\u00a0\u00a0if (error) {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0this.setState({ error })\r\n\r\n\u00a0\u00a0\u00a0} else {\r\n\r\n\u00a0\u00a0\u00a0this.login();\r\n\r\n\u00a0\u00a0\u00a0}\r\n\r\n\u00a0}\r\n\r\n\u00a0login(){\r\n\r\n\u00a0\u00a0\u00a0this.props.authenticate(this.state)\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0.then(res =&gt; {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if (res === 'Username invalid' || res === 'Password invalid'){\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.setState({\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0error: res,\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0username: '',\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0password: '',\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0})\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0} else {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Actions.feed();\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0});\r\n\r\n\u00a0}\r\n\r\n\u00a0render(){\r\n\r\n\u00a0\u00a0\u00a0return (\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0&lt;Container style={styles.container}&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;Content&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;Text style={styles.formMsg}&gt;{this.state.error}&lt;\/Text&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;Icon\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0style={styles.icon}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0ios=\"ios-happy-outline\"\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0android=\"md-happy\"\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;View style={styles.loginBox}&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;TextField\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0name=\"Enter Username\"\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0type=\"big\"\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0value={this.state.username}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0onChangeText={(text) =&gt; this.setState({username: text})}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;TextField\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0secureTextEntry\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0name=\"Enter Password\"\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0type=\"big\"\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0value={this.state.password}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0onChangeText={(text) =&gt; this.setState({password: text})}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;Button\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0block\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0style={styles.button}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0onPress={() =&gt; this.onSubmit()}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;Text&gt;Log in&lt;\/Text&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/Button&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/View&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;Button\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0transparent\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0style={styles.signupBtn}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0onPress={() =&gt; Actions.signup()}&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;Text style={styles.signupTxt}&gt;Sign up for an account&lt;\/Text&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/Button&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/Content&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/Container&gt;\r\n\r\n\u00a0\u00a0\u00a0);\r\n\r\n\u00a0}\r\n\r\n}\r\n\r\nexport default connect(null, mapDispatchToProps)(Login);<\/pre>\n<p>Once more, we verify that the fields contain correct input before using our authenticatefunction to compare the login information to what is in our bucket:<\/p>\n<pre class=\"theme:turnwall font-size-enable:false font-size:14 height-set:true height:250 lang:default decode:true \">export const authenticate = user =&gt; dispatch =&gt; {\r\n\r\n\u00a0return axios.get(`https:\/\/api.cosmicjs.com\/v1\/${cosmicConfig.bucket.slug}\/object-type\/users\/search?metafield_key=username&amp;metafield_value=${user.username}`)\r\n\r\n\u00a0\u00a0\u00a0.then(res =&gt; res.data)\r\n\r\n\u00a0\u00a0\u00a0.then(data =&gt; {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0console.log('RESPONSE: ', data);\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0if (data.objects) {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0const userData = data.objects[0];\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0password: userData.metadata.password,\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0username: userData.metadata.username,\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0name: userData.metadata.name,\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0profilePicture: userData.metadata.profile_picture,\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0slug: userData.slug,\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0id: userData._id,\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0} else {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return 'Username invalid';\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0}\r\n\r\n\u00a0\u00a0\u00a0})\r\n\r\n\u00a0\u00a0\u00a0.then(data =&gt; {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0if (data === 'Username invalid'){\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return data;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0} else if (data.password === user.password){\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0dispatch(login({\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0name: data.name,\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0username: data.username,\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0profilePicture: data.profilePicture,\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0slug: data.slug,\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0id: data.id,\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}))\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0} else {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return 'Password invalid';\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0}\r\n\r\n\u00a0\u00a0\u00a0})\r\n\r\n\u00a0\u00a0\u00a0.catch(error =&gt; console.error('Login unsuccessful', error))\r\n\r\n}<\/pre>\n<p><span style=\"font-weight: 400;\">As a side note, we shouldn&#8217;t ordinarily store user credentials in our database directly without using encryption, but we&#8217;ll keep it that way for the time being as a quick example of how we may handle our data using the Cosmic API.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">After logging in, users are sent immediately to the Feed layout, which is as follows:<\/span><\/p>\n<pre class=\"theme:turnwall font-size-enable:false font-size:14 height-set:true height:250 lang:default decode:true \">import React, { Component } from 'react';\r\n\r\nimport { connect } from 'react-redux';\r\n\r\nimport { Actions } from 'react-native-router-flux';\r\n\r\nimport {\r\n\r\n\u00a0Container,\r\n\r\n\u00a0Content,\r\n\r\n\u00a0List,\r\n\r\n\u00a0Button,\r\n\r\n\u00a0Icon,\r\n\r\n\u00a0Text,\r\n\r\n} from 'native-base';\r\n\r\nimport SinglePost from '..\/..\/components\/SinglePost';\r\n\r\nimport FeedNavbar from '..\/..\/components\/FeedNavbar';\r\n\r\nimport { loadPosts } from '..\/..\/redux\/reducers\/posts';\r\n\r\nimport { logoutUser } from '..\/..\/redux\/reducers\/users';\r\n\r\nimport styles from '.\/styles';\r\n\r\nconst mapStateToProps = ({ posts }) =&gt; ({ posts });\r\n\r\nconst mapDispatchToProps = { loadPosts, logoutUser };\r\n\r\nconst renderPost = (post, index) =&gt; (\r\n\r\n\u00a0&lt;SinglePost\r\n\r\n\u00a0\u00a0\u00a0key={index}\r\n\r\n\u00a0\u00a0\u00a0name={post.name}\r\n\r\n\u00a0\u00a0\u00a0username={post.username}\r\n\r\n\u00a0\u00a0\u00a0profilePicture={post.profilePicture}\r\n\r\n\u00a0\u00a0\u00a0content={post.content}\r\n\r\n\u00a0\/&gt;\r\n\r\n)\r\n\r\nclass Feed extends Component {\r\n\r\n\u00a0componentDidMount(){\r\n\r\n\u00a0\u00a0\u00a0this.props.loadPosts();\r\n\r\n\u00a0}\r\n\r\n\u00a0render(){\r\n\r\n\u00a0\u00a0\u00a0const endMsg = this.props.posts.length === 0 ? \"There aren't any posts yet!\" : \"That's all the posts for now!\"\r\n\r\n\u00a0\u00a0\u00a0return (\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0&lt;Container&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;FeedNavbar logout={this.props.logoutUser} refresh={this.props.loadPosts} \/&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;Content&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;List&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0!!this.props.posts.length &amp;&amp; this.props.posts.map(renderPost)\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/List&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;Text style={styles.end}&gt;{endMsg}&lt;\/Text&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/Content&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;Button\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0rounded\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0style={styles.button}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0onPress={() =&gt; Actions.newPost()}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;Icon\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0name=\"create\"\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0style={{padding: 5}}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/Button&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/Container&gt;\r\n\r\n\u00a0\u00a0\u00a0);\r\n\r\n\u00a0}\r\n\r\n}\r\n\r\nexport default connect(mapStateToProps, mapDispatchToProps)(Feed);<\/pre>\n<p>We send a request to the Cosmic API when the Feed layout mounts in order to load all of the posts in our bucket into our app state. In our posts reduction, the loadPostsfunction looks like this:<\/p>\n<pre class=\"theme:turnwall font-size-enable:false font-size:14 height-set:true height:250 lang:default decode:true \">export const loadPosts = () =&gt; dispatch =&gt; {\r\n\r\n\u00a0return axios.get(`https:\/\/api.cosmicjs.com\/v1\/${cosmicConfig.bucket.slug}\/object-type\/posts`)\r\n\r\n\u00a0\u00a0\u00a0.then(res =&gt; res.data.objects ? formatPosts(res.data.objects) : [])\r\n\r\n\u00a0\u00a0\u00a0.then(formattedPosts =&gt; formattedPosts.sort(postSorter))\r\n\r\n\u00a0\u00a0\u00a0.then(sortedPosts =&gt; dispatch(init(sortedPosts)))\r\n\r\n\u00a0\u00a0\u00a0.catch(err =&gt; console.error(`Could not load posts`, err));\r\n\r\n};<\/pre>\n<p><span style=\"font-weight: 400;\">We extract all of the posts from our bucket, prepare them so we can easily access the information we need, and then put them into the state. They are then shown in the stream.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Users may create new posts by clicking a button on the feed. After that, they are sent to the NewPostlayout:<\/span><\/p>\n<pre class=\"theme:turnwall font-size-enable:false font-size:14 height-set:true height:250 lang:default decode:true \">import React, { Component } from 'react';\r\n\r\nimport { connect } from 'react-redux';\r\n\r\nimport {\r\n\r\n\u00a0Container,\r\n\r\n\u00a0Content,\r\n\r\n\u00a0Text,\r\n\r\n\u00a0Button,\r\n\r\n} from 'native-base';\r\n\r\nimport { View } from 'react-native';\r\n\r\nimport TextField from '..\/..\/components\/TextField';\r\n\r\nimport styles from '.\/styles';\r\n\r\nimport { createPost } from '..\/..\/redux\/reducers\/posts';\r\n\r\nconst mapStateToProps = state =&gt; ({\r\n\r\n\u00a0user: state.user,\r\n\r\n})\r\n\r\nconst mapDispatchToProps = { createPost };\r\n\r\nclass NewPost extends Component {\r\n\r\n\u00a0constructor(){\r\n\r\n\u00a0\u00a0\u00a0super();\r\n\r\n\u00a0\u00a0\u00a0this.state = {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0content: '',\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0error: '',\r\n\r\n\u00a0\u00a0\u00a0}\r\n\r\n\u00a0}\r\n\r\n\u00a0onSubmit() {\r\n\r\n\u00a0\u00a0\u00a0if (this.state.content){\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0this.props.createPost({\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0user: this.props.user,\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0content: this.state.content,\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0})\r\n\r\n\u00a0\u00a0\u00a0} else {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0this.setState({error: 'You have to write something!'});\r\n\r\n\u00a0\u00a0\u00a0}\r\n\r\n\u00a0}\r\n\r\n\u00a0render(){\r\n\r\n\u00a0\u00a0\u00a0return (\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0&lt;Container style={styles.container}&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;Content&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;Text style={styles.formMsg}&gt;{this.state.error}&lt;\/Text&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;View style={styles.input}&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;TextField\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0big\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0name=\"What's up?\"\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0value={this.state.post}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0onChangeText={(text) =&gt; this.setState({content: text})}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;Button\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0rounded\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0style={styles.button}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0onPress={() =&gt; this.onSubmit()}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;Text&gt;Post&lt;\/Text&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/Button&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/View&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/Content&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/Container&gt;\r\n\r\n\u00a0\u00a0\u00a0);\r\n\r\n\u00a0}\r\n\r\n}\r\n\r\nexport default connect(mapStateToProps,\r\nmapDispatchToProps)(NewPost);<\/pre>\n<p>&nbsp;<\/p>\n<p>We&#8217;ll add their post to our bucket as soon as they submit it:<\/p>\n<pre class=\"theme:turnwall font-size-enable:false font-size:14 height-set:true height:250 lang:default decode:true \">return axios.post(`https:\/\/api.cosmicjs.com\/v1\/${cosmicConfig.bucket.slug}\/add-object`, {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0title: post.user.username + ' post',\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0type_slug: 'posts',\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0content: post.content,\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0metafields: [\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0type: 'object',\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0title: 'User',\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0key: 'user',\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0object_type: 'users',\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0value: post.user.id\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0},\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0]\r\n\r\n\u00a0\u00a0\u00a0})\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0.then(res =&gt; formatPost(res.data, post))\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0.then(formattedPost =&gt; dispatch(create(formattedPost)))\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0.then(() =&gt; Actions.feed({type: 'popAndReplace'}))\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0.catch(error =&gt; console.error('Post unsuccessful', error))\r\n\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">And now we\u2019ll reroute to the feed once more, bringing up the most recent collection of posts. Users can log out of the Feed and refresh their feed to see any new entries.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Hurray! Our Twitter clone app using <\/span>React Native app development framework<span style=\"font-weight: 400;\"> is ready to launch!<\/span><\/p>\n<h2><span class=\"ez-toc-section\" id=\"Conclusion\"><\/span><span style=\"font-weight: 400;\">Conclusion<\/span><span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p><span style=\"font-weight: 400;\">We used React Native to create a Twitter-like app that made use of the Cosmic JS API to make it simple to manage all of the user and post data. With a few straightforward operations that POST and Be our data to\/from our Cosmic JS Bucket, we were able to get up and running quickly.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">It may not be easy to create a Twitter-like app alone, therefore, you need an experienced <\/span>React Native app development company <span style=\"font-weight: 400;\">to help you match your app ideation. Need to <\/span><a href=\"https:\/\/dianapps.com\/react-native-app-development\"><b>hire react native developer<\/b><\/a><span style=\"font-weight: 400;\">? Your search ends here! Get in touch with us to get all you have been looking for in one platform itself.\u00a0<\/span><\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Getting your hands on new programming languages or frameworks is one of the greatest methods to learn them. Therefore, we made the decision to build a Twitter clone app while learning React Native app development. In order to demonstrate how to build this app, we will first quickly outline our experience with React Native before [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":5653,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_wp_applaud_exclude":false,"footnotes":""},"categories":[3],"tags":[],"class_list":["post-5593","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-app-development"],"featured_image_src":{"landsacpe":["https:\/\/www.dianapps.com\/blog\/wp-content\/uploads\/2023\/02\/Twitter-Clone-1-1140x445.png",1140,445,true],"list":["https:\/\/www.dianapps.com\/blog\/wp-content\/uploads\/2023\/02\/Twitter-Clone-1-463x348.png",463,348,true],"medium":["https:\/\/www.dianapps.com\/blog\/wp-content\/uploads\/2023\/02\/Twitter-Clone-1-300x169.png",300,169,true],"full":["https:\/\/www.dianapps.com\/blog\/wp-content\/uploads\/2023\/02\/Twitter-Clone-1.png",2048,1152,false]},"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v20.12 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Building a Twitter Clone App in React Native<\/title>\n<meta name=\"description\" content=\"Want to create a twitter-like app using React Native? This blog is all you need to get started with the requirement instantly.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.dianapps.com\/blog\/building-a-twitter-clone-app-in-react-native\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Building a Twitter Clone App in React Native\" \/>\n<meta property=\"og:description\" content=\"Want to create a twitter-like app using React Native? This blog is all you need to get started with the requirement instantly.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.dianapps.com\/blog\/building-a-twitter-clone-app-in-react-native\/\" \/>\n<meta property=\"og:site_name\" content=\"Learn About Digital Transformation &amp; Development | DianApps Blog\" \/>\n<meta property=\"article:published_time\" content=\"2023-02-12T07:44:45+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-02-17T06:05:33+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.dianapps.com\/blog\/wp-content\/uploads\/2023\/02\/Twitter-Clone-1.png\" \/>\n\t<meta property=\"og:image:width\" content=\"2048\" \/>\n\t<meta property=\"og:image:height\" content=\"1152\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Vikash Soni\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Vikash Soni\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"16 minutes\" \/>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Building a Twitter Clone App in React Native","description":"Want to create a twitter-like app using React Native? This blog is all you need to get started with the requirement instantly.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.dianapps.com\/blog\/building-a-twitter-clone-app-in-react-native\/","og_locale":"en_US","og_type":"article","og_title":"Building a Twitter Clone App in React Native","og_description":"Want to create a twitter-like app using React Native? This blog is all you need to get started with the requirement instantly.","og_url":"https:\/\/www.dianapps.com\/blog\/building-a-twitter-clone-app-in-react-native\/","og_site_name":"Learn About Digital Transformation &amp; Development | DianApps Blog","article_published_time":"2023-02-12T07:44:45+00:00","article_modified_time":"2023-02-17T06:05:33+00:00","og_image":[{"width":2048,"height":1152,"url":"https:\/\/www.dianapps.com\/blog\/wp-content\/uploads\/2023\/02\/Twitter-Clone-1.png","type":"image\/png"}],"author":"Vikash Soni","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Vikash Soni","Est. reading time":"16 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.dianapps.com\/blog\/building-a-twitter-clone-app-in-react-native\/","url":"https:\/\/www.dianapps.com\/blog\/building-a-twitter-clone-app-in-react-native\/","name":"Building a Twitter Clone App in React Native","isPartOf":{"@id":"https:\/\/www.dianapps.com\/blog\/#website"},"datePublished":"2023-02-12T07:44:45+00:00","dateModified":"2023-02-17T06:05:33+00:00","author":{"@id":"https:\/\/www.dianapps.com\/blog\/#\/schema\/person\/0126fafc83e42bece2acbfe92f7d0f4f"},"description":"Want to create a twitter-like app using React Native? This blog is all you need to get started with the requirement instantly.","breadcrumb":{"@id":"https:\/\/www.dianapps.com\/blog\/building-a-twitter-clone-app-in-react-native\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.dianapps.com\/blog\/building-a-twitter-clone-app-in-react-native\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.dianapps.com\/blog\/building-a-twitter-clone-app-in-react-native\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.dianapps.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Building a Twitter Clone App in React Native"}]},{"@type":"WebSite","@id":"https:\/\/www.dianapps.com\/blog\/#website","url":"https:\/\/www.dianapps.com\/blog\/","name":"Learn About Digital Transformation &amp; Development | DianApps Blog","description":"Dianapps","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.dianapps.com\/blog\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.dianapps.com\/blog\/#\/schema\/person\/0126fafc83e42bece2acbfe92f7d0f4f","name":"Vikash Soni","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.dianapps.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/dianapps.com\/blog\/wp-content\/uploads\/2022\/07\/cropped-vikash-96x96.png","contentUrl":"https:\/\/dianapps.com\/blog\/wp-content\/uploads\/2022\/07\/cropped-vikash-96x96.png","caption":"Vikash Soni"},"description":"Vikash Soni, the visionary CEO and Co-founder of DianApps. With his profound expertise in Android and iOS app development, he leads the team to deliver top-notch solutions to clients worldwide. Under his guidance, the company has achieved remarkable success, earning a reputation as a leading web and mobile app development company.","sameAs":["https:\/\/www.linkedin.com\/in\/vikash-soni-59726530\/"],"url":"https:\/\/www.dianapps.com\/blog\/author\/infodianapps-com\/"}]}},"_links":{"self":[{"href":"https:\/\/www.dianapps.com\/blog\/wp-json\/wp\/v2\/posts\/5593","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.dianapps.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.dianapps.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.dianapps.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dianapps.com\/blog\/wp-json\/wp\/v2\/comments?post=5593"}],"version-history":[{"count":7,"href":"https:\/\/www.dianapps.com\/blog\/wp-json\/wp\/v2\/posts\/5593\/revisions"}],"predecessor-version":[{"id":5607,"href":"https:\/\/www.dianapps.com\/blog\/wp-json\/wp\/v2\/posts\/5593\/revisions\/5607"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.dianapps.com\/blog\/wp-json\/wp\/v2\/media\/5653"}],"wp:attachment":[{"href":"https:\/\/www.dianapps.com\/blog\/wp-json\/wp\/v2\/media?parent=5593"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dianapps.com\/blog\/wp-json\/wp\/v2\/categories?post=5593"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dianapps.com\/blog\/wp-json\/wp\/v2\/tags?post=5593"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}