🔙 Quay lại trang tải sách pdf ebook Mastering React Native Ebooks Nhóm Zalo Mastering React Native Leverage frontend development skills to build impressive iOS and Android applications with React Native Eric Masiello Jacob Friedmann BIRMINGHAM - MUMBAI Mastering React Native Copyright © 2017 Packt Publishing All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews. Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold without warranty, either express or implied. Neither the author(s), nor Packt Publishing, and its dealers and distributors will be held liable for any damages caused or alleged to be caused directly or indirectly by this book. Packt Publishing has endeavored to provide trademark information about all of the companies and products mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy of this information. First published: January 2017 Production reference: 1060117 Published by Packt Publishing Ltd. Livery Place 35 Livery Street Birmingham B3 2PB, UK. ISBN 978-1-78588-578-5 www.packtpub.com Credits Authors Copy Editor Eric Masiello Jacob Friedmann Reviewers Patrick Puritscher Commissioning Editor Wilson Dsouza Acquisition Editor Denim Pinto Content Development Editor Divij Kotian Technical Editor Rutuja Vaze Safis Editing Project Coordinator Sheejal Shah Proofreader Safis Editing Indexer Rekha Nair Graphics Abhinash Sahu Production Coordinator Aparna Bhagat Disclaimer We are using the New York Times' API for illustrative purposes only. We do not recommend you publish your application to the app store using this API without first reading the Terms of Use (https://developer.nytimes.com/tou). For more information please consult the NYT's terms and conditions. About the Authors Eric Masiello is a lead software engineer for Vistaprint Digital. Formerly, Eric worked as a principal frontend engineer for the Advisory Board Company and built mobile apps for the Education Advisory Board. Eric has worked primarily as a frontend/UI developer for over 10 years and freelances as a website designer/developer at http://www.synbydesign.com. He has taught frontend topics at General Assembly in Washington, D.C. and was a technical reviewer for Mastering ReactJS, a video by Packt Publishing. You can follow him here: https://www.linkedin.com/in/ericmasiello https://twitter.com/ericmasiello http://synbydesign.com First and foremost, I must extend an enormous thank you to my beautiful, talented, and always-inspiring wife, Hyun. If not for her support, this book would honestly not exist. My deepest gratitude also goes out to my family: Mom, Dad, Brian, Juliana, Nicolas, Umma, and my sisters Hannah, Min, and Carroll. I’m truly blessed to have such a wonderful and supportive family. Shout out to all the inspiring people I’ve had the honor of working with over the years. I’ve learned so much from all of you. Thanks to Keith, Michael, Andrew, Scott, Shelley, Kelly, the inimitable Karthik, Jesse, Jaworski, Beth, Mat, Anbu, Ashwin, Kevin, Ann, all my PIC/RCS homies, the EAB dev/UI team, the entire ABC/EAB UX team, and finally my new Vistaprint Digital family. Thank you to all my close friends who have balanced me, challenged me, shared a drink, or just a laugh: Bryan, Alan, Chris, Kyril, Brandon, April, and the whole Expansion Broadcast + DC crew. Thank you to everyone at Packt for bringing me along on this amazing (and sleepless) journey. And finally, thanks to my coauthor Jacob for all the work he did in realizing this book and for agreeing to even write a book with someone he had known for all of two weeks. Jacob Friedmann is a developer living in Seattle, WA. He has been working as a developer professionally for 5 years and is currently a principal software engineer at AddThis, an Oracle company. At AddThis, he works on large front and backend applications. He also builds mobile applications using React Native, including Audicy (http://audicy.io), which will soon be launched on the App Store. He has taught several classes, including frontend web development and JavaScript development through General Assembly in Washington D.C. You can follow him here: https://www.linkedin.com/in/jacob-friedmann https://twitter.com/JacobDFriedmann Writing a book (my first!) is hard, and I don’t think I would have been able to do it without the support of my loving boyfriend, Matt. He weathered my frequent complaining in stride and kept me focused when I needed it most. For that, I am incredibly grateful. Huge thanks to all of my AddThis family who have always inspired me to keep learning and pushed me to do my best work. To all of my friends and family, who were patient with me when I became a recluse to finish this project, thank you. You are loved, and I promise not to do this again for a while! Finally, to Eric for pulling me along on this adventure. I definitely didn’t know what I was getting myself into when I agreed to this, but I can’t imagine having a more dedicated and capable partner. About the Reviewer Patrick Puritscher began developing websites at the age of 14 by teaching himself the necessary skills. Already using React.js, he started to develop with React Native, shortly after watching the initial presentation. He is also active in the community with his open source components and recently published an app for iOS, completely written with React Native. After graduating with his bachelor’s degree, Patrick worked as the lead developer for multiple internally used web apps and a website with several million visits each month. It is his personal ambition to create software for people that makes their life easier, rather than making it more difficult with poor UX. Patrick has just started with his master’s degree in Business Informatics. You can follow him on: https://twitter.com/whoispurii http://patrickpuritscher.com www.PacktPub.com For support files and downloads related to your book, please visit www.PacktPub.com. Did you know that Packt offers eBook versions of every book published, with PDF and ePub files available? You can upgrade to the eBook version at www.PacktPub.com and as a print book customer, you are entitled to a discount on the eBook copy. Get in touch with us at [email protected] for more details. At www.PacktPub.com, you can also read a collection of free technical articles, sign up for a range of free newsletters and receive exclusive discounts and offers on Packt books and eBooks. https://www.packtpub.com/mapt Get the most in-demand software skills with Mapt. Mapt gives you full access to all Packt books and video courses, as well as industry-leading tools to help you plan your personal development and advance your career. Why subscribe? Fully searchable across every book published by Packt Copy and paste, print, and bookmark content On demand and accessible via a web browser Customer Feedback Thank you for purchasing this Packt book. We take our commitment to improving our content and products to meet your needs seriously—that's why your feedback is so valuable. Whatever your feelings about your purchase, please consider leaving a review on this book's Amazon page. Not only will this help us, more importantly it will also help others in the community to make an informed decision about the resources that they invest in to learn. You can also review for us on a regular basis by joining our reviewers' club. If you're interested in joining, or would like to learn more about the benefits we offer, please contact us: [email protected]. Table of Contents Preface 1 Chapter 1: Building a Foundation in React 7 Library versus framework 8 Motivation for React 8 Getting started in React 9 Describing components in JSX 11 The component 13 Component composition 14 Props and PropTypes 15 Accepting props 15 PropTypes 16 Passing props 20 Default props 21 Props.children 24 Event handlers 25 State 27 The component lifecycle 32 The update cycle 34 Unmounting the component 36 Alternate component forms 37 React.createClass 37 Functional components 39 Summary 40 Chapter 2: Saying HelloWorld in React Native 41 Understanding the mobile app development ecosystem 42 Adobe PhoneGap 43 Ionic 43 NativeScript 43 React Native 45 Extending React Native 46 Introducing style and layout in React Native 46 Understanding all the React Native tools 47 Xcode 48 Google Chrome 48 Homebrew (also known as brew) 48 Node.js and npm 49 Watchman 49 Flow 49 React Native command-line interface (CLI) 50 Installing our tools 50 Installing Xcode 51 Installing Homebrew 51 Installing Node and npm 53 Installing Watchman and Flow 54 Installing the React Native CLI 54 Creating our first React Native app 56 React Native Packager 61 Understanding our HelloWorld app 62 Importing dependencies using ECMAScript 2015 63 Our HelloWorld component 64 HelloWorld style code 66 Registering the root component 66 Why import React? 67 Debugging a React Native app 68 Enabling the Chrome Debugger 68 Breakpoints 71 Summary 73 Chapter 3: Styling and Layout in React Native 74 Constructing and applying styles 74 Inline styles 75 Styles as objects in your React Native components 76 Stylesheet 78 Using Stylesheet.hairlineWidth 81 Applying component-specific style properties 83 Styling without inheritance 85 Understanding React Native's take on the box model and flexbox 86 Box model 87 Understanding Flexbox 91 Covering the other axis 97 Flex shrinking and growing 100 Setting flexBasis 100 Growing and shrinking flex items 100 Styling text with React Native 102 Text style properties 104 [ ii ] Encapsulating text styles in reusable components 106 Styling images 109 Background images 110 Inspecting and debugging styles 111 Using the React Native Inspector 111 Adding media query behavior to React Native 113 Using Dimensions 113 Using onLayout per View 114 Summary 116 Chapter 4: Starting our Project with React Native Components 117 Native components 118 Text 119 Props 122 View 124 Props 126 Image 128 Props 132 Static methods 133 Touchable 133 Props 136 ListView 137 DataSource 138 renderRow 139 Props 139 Modal 143 Props 144 WebView 150 Props 151 TabBarIOS 153 Props 154 TabBarIOS.Item 155 Props 155 TextInput 158 Props 159 Other input components 163 Native APIs 164 ActionSheetIOS 164 Alert 167 Vibration 169 StatusBar 169 Summary 170 [ iii ] Chapter 5: Flux and Redux 171 The Flux architecture 172 Motivation 172 Implementing Flux 174 Creating our view 175 Actions and action creators 179 Dispatcher 180 Stores 183 Rendering updated data 186 Getting started with Redux 190 Principles of Redux 190 Installing Redux 191 Implementing Redux 191 Refactoring the store 191 Reducer 191 Creating the store 194 Multiple reducers 195 Action creators 196 Subscribing to the store 197 React-Redux 199 Installing React-Redux 199 React context and providers 199 Container and presentational components 200 Middleware 204 Summary 206 Chapter 6: Integrating with the NYT API and Redux 207 Understanding the NYT API data 208 Wiring up our Redux data flow 211 Creating the Redux state tree 213 Wiring up Redux data to our app 216 Refactoring and reshaping 218 Refactoring the components 219 Reshaping the data 220 Introducing Reselect 222 Adding search 223 Wiring up the NYT API with asynchronous requests 227 Fixing iOS transport security 229 Adding pull to refresh and a loading spinner 231 Summary 234 Chapter 7: Navigation and Advanced APIs 235 Navigation landscape 236 [ iv ] NavigatorIOS 236 Navigator 237 NavigationExperimental 238 Choosing a navigator 238 Using Navigator 240 The Navigator component 242 Navigation bar 246 Advanced navigation with NavigationExperimental 251 Representing the navigation state 251 Managing the navigation state 253 The CardStack component 255 Navigation header 260 Tabbed navigation 262 Adding in the modal 268 Other advanced APIs 276 Offline messages with NetInfo 276 Opening the browser with linking 280 Saving bookmarks locally with AsyncStorage 283 Summary 291 Chapter 8: Animation and Gestures in React Native 292 Introducing LayoutAnimation and Animated 293 Building the basic Onboarding experience 293 Getting started 293 Adding LayoutAnimation 306 Adding a bit more animation 309 Understanding Animated 313 Refactoring our Onboarding experience 314 Adding Animated to our Onboarding experience 315 Interpolating Animated Values 318 Using PanResponder with the Animated API 322 Touching up PanResponder 325 Summary 326 Chapter 9: Refactoring for Android 327 Installing the necessary tools 328 Installing the Java Development Kit 328 Installing Android Studio 330 Configuring Android Studio 332 Configuring ANDROID_HOME and your PATH 334 [ v ] Verifying that the CPU/ABIs are installed 335 Starting the Android emulator 336 Adding Android support to RNNYT 337 Branching platform logic 339 Refactoring RNNYT for Android 341 Fixing Android vibration 343 Using DrawerLayoutAndroid 344 Customizing Android styling 347 Enabling LayoutAnimation 351 Summary 352 Chapter 10: Using and Writing Native Modules 353 Using native modules 354 Installing native modules 354 Using the library 355 Profile page 355 Adding the profile to the iOS home screen 358 Adding the profile to the Android home screen 362 Writing native modules 365 Native modules in iOS 366 Setting up the module 366 Exporting methods 372 Communicating with callbacks 378 Communicating with promises 381 Communicating with events 384 Exporting constants 387 Native modules in Android 388 Setting up the module 388 Exporting methods 394 Communicating with callbacks 395 Communicating with promises 396 Communicating with events 398 Exporting constants 399 Summary 402 Chapter 11: Preparing for Production 403 Testing 403 Unit testing 405 Component testing 408 Performance 411 Problematic ListView 412 Using Perf Monitor 412 Analyzing a Systrace 415 The React Perf Library 422 [ vi ] shouldComponentUpdate and PureRenderMixin 424 Minimizing the impact of state changes 425 The ListView data source 427 Additional optimizations 428 Unresponsive touch and slow navigation 430 Mitigating unresponsive touch 431 Smoothing out animations with InteractionManager 434 Performance summary 436 Running on physical devices 436 Debugging on an iOS device 436 Testing your app on an iOS device using Release 438 Debugging on Android devices 438 Generating a signed APK 439 Deploying our application 439 Remove debugging code 440 iOS 441 Creating provisioning profiles 442 Registering an application in iTunes Connect 443 Adding icons and updating the launch screen 444 Creating an archive 445 Beta testing and release 448 Android 448 Signing the application 448 Testing the release build 449 Generating the APK 450 Beta-test and release 450 Summary 450 Chapter 12: React Native Tools and Resources 451 Evaluating React Native Editors, Plugins, and IDEs 451 Atom and Nuclide 452 Taking React Native beyond iOS and Android 458 Introducing React Native Web 458 Configuring React Native Web 459 React Native plugin for Universal Windows Platform 462 Configuring the React Native plugin for UWP 462 React Native macOS 463 Configuring React Native macOS 464 Summary 465 References 465 Index 467 [ vii ] Preface React Native is a library for creating mobile applications using familiar web technologies without sacrificing performance or the look and feel typically associated with fully native applications. It is built on top of Facebook’s open source JavaScript library, React, and indeed, iOS and Android applications created using the library are primarily written in JavaScript. Because one does not need to learn new languages, ecosystems, and best practices for each platform they work on, React Native is pushing the boundaries of what is possible for React developers. In this book, we will look at the fundamental concepts of React and React Native, as well as the libraries and tools within the React Native ecosystem. We will also work towards the more practical goal of creating a complete React Native application. Finally, we’ll dig into useful and complex React Native concepts such as animation, navigation, native modules, testing and performance analysis. Upon turning over the last page of this book, you’ll be armed with the knowledge to create polished, sophisticated mobile applications using React Native. What this book covers Chapter 1, Building a Foundation in React, In order to work effectively in React Native, you must first understand React. This chapter explains the motivation behind React and teaches you how to think in React. Chapter 2, Saying Hello World in React Native, contains two primary topics. First, we’ll review how React Native works and compare it to other popular mobile development options. Then, we’ll switch gears and focus on configuring your computer to build your first React Native project for iOS. Chapter 3, Styling and Layout in React Native, React Native borrows many concepts from the web development world, including some of the best parts of Cascading Style Sheets (CSS). It also deliberately avoids some of CSS’s less desirable qualities. This chapter explains how to style React Native apps and how to use Flexbox to layout components. Chapter 4, Starting our Project with React Native Components, React Native includes many powerful components and APIs. This chapter demonstrates how to use many of these as we begin to build our news reader app, called Readly. Preface Chapter 5, Flux and Redux, ... The React community has largely eschewed the Model View Controller pattern in favor of a unidirectional data flow pattern called Flux. In this chapter, we’ll help you think in Flux and explain how to leverage a popular Flux implementation known as Redux. Chapter 6, Integrating with the NYT API and Redux, builds upon what we learned in this chapter. In order to bring our Readly app to life, we’ll implement Redux and Redux middleware as a means of managing our data and communicating with the New York Times API. Chapter 7, Navigation & Advanced APIs, Navigation in React Native has been a long journey resulting in an abundance of navigation options. But which should you choose? This chapter will make sense of these options. We’ll then apply experimental navigation components along with other advanced React Native APIs to our project. Chapter 8, Animation and Gestures in React Native, React Native offers two primary ways of creating fluid animations. This chapter will explain how to apply each of these along with touch gesture support to build out an on boarding experience for our Readly app. Chapter 9, Refactoring for Android, React Native makes cross platform development simple. However, configuring your computer to actually build for Android is a bit less than simple. This chapter will walk you through, step by step, how to install and configure all the tools necessary for Android development. We’ll then revisit our project, refactoring it to both work and feel like a first class Android app. Chapter 10, Using and Writing Native Modules, One of the most amazing parts of React Native is that it doesn’t limit you to the components and APIs that come packaged with the framework. If you want your app to do something else, you can either bridge custom native code to React Native or include other third-party libraries. This chapter adds additional capabilities to our project by exploring how to create custom native code written in Objective C for iOS and Java for Android. Chapter 11, Preparing for Production, Discovering the root cause of bug or performance problem can be a real chore. In this chapter we’ll introduce Jest, a testing framework along with other tools for uncovering pesky performance problems. Finally, we’ll show you how to bundle your apps so you can ship them to the iOS and Android stores. [ 2 ] Preface Chapter 12, React Native Tools & Resources, React Native is praised for its awesome developer experience and cross platform support. But can we take React Native even further? In this final chapter, we’ll show off some tools that can improve upon how you build React Native apps. Then we’ll explore a few React Native projects that allow us to extend platform support to the web, macOS, and even Windows. What you need for this book While we will add Android support to our project in later chapters, the majority of this book focuses on iOS development. In order to develop for iOS, you must have access to an Apple Mac computer capable of running Xcode 7 or later. Xcode is only necessary for building and testing React Native apps. You’re welcome to edit your code in any editor or IDE of your choosing. In addition to Xcode, React Native requires a few other tools. These include Homebrew, Node.js (6.5.0 or later), npm (3.10.3 or later), Watchman, the React Native CLI, and Google Chrome for debugging. We’ll explain what all these tools are and how to install them in Chapter 2, Saying Hello World in React Native. In Chapter 9, Refactoring for Android, we’ll update our project so it can run on both platforms. Android has its own set of software requirements including the Java Development Kit (JDK 1.8 or later) and Android Studio. Once again, we’ll walk you through how to install and configure these tools in Chapter 9, Refactoring for Android. Finally, in Chapter 12, React Native Tools & Resources, we’ll evaluate software that can aid your React Native workflow and allow you to build React Native apps for even more platforms. All of these installations are completely optional. However, it’s worth noting that the React Native plugin for Universal Windows Platform will require a computer or virtual machine running Windows 10 and Visual Studio 2015 Community. Who this book is for It’s expected the reader possess a strong understanding of JavaScript and is familiar with ECMAScript 2015 (ES2015 or ES6). Code samples in this book will heavily leverage ES2015 features such as classes, arrow functions, destructuring, and spreading. Familiarity with React, mobile development, HTML, and CSS will aid in your understanding but are not a requirement. [ 3 ] Preface Conventions In this book, you will find a number of text styles that distinguish between different kinds of information. Here are some examples of these styles and an explanation of their meaning. Code words in text, database table names, folder names, filenames, file extensions, pathnames, dummy URLs, user input, and Twitter handles are shown as follows: "We can include other contexts through the use of the include directive." A block of code is set as follows: [default] exten => s,1,Dial(Zap/1|30) exten => s,2,Voicemail(u100) exten => s,102,Voicemail(b100) exten => i,1,Voicemail(s0) When we wish to draw your attention to a particular part of a code block, the relevant lines or items are set in bold: [default] exten => s,1,Dial(Zap/1|30) exten => s,2,Voicemail(u100) exten => s,102,Voicemail(b100) exten => i,1,Voicemail(s0) Any command-line input or output is written as follows: cp /usr/src/asterisk-addons/configs/cdr_mysql.conf.sample /etc/asterisk/cdr_mysql.conf New terms and important words are shown in bold. Words that you see on the screen, for example, in menus or dialog boxes, appear in the text like this: "Clicking the Next button moves you to the next screen." Warnings or important notes appear in a box like this. Tips and tricks appear like this. [ 4 ] Preface Reader feedback Feedback from our readers is always welcome. Let us know what you think about this book-what you liked or disliked. Reader feedback is important for us as it helps us develop titles that you will really get the most out of. To send us general feedback, simply e mail [email protected], and mention the book's title in the subject of your message. If there is a topic that you have expertise in and you are interested in either writing or contributing to a book, see our author guide at www.packtpub.com/authors. Customer support Now that you are the proud owner of a Packt book, we have a number of things to help you to get the most from your purchase. Downloading the example code You can download the example code files for this book from your account at http://www.p acktpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.c om/supportand register to have the files e-mailed directly to you. You can download the code files by following these steps: 1. Log in or register to our website using your e-mail address and password. 2. Hover the mouse pointer on the SUPPORT tab at the top. 3. Click on Code Downloads & Errata. 4. Enter the name of the book in the Search box. 5. Select the book for which you're looking to download the code files. 6. Choose from the drop-down menu where you purchased this book from. 7. Click on Code Download. Once the file is downloaded, please make sure that you unzip or extract the folder using the latest version of: WinRAR / 7-Zip for Windows Zipeg / iZip / UnRarX for Mac 7-Zip / PeaZip for Linux [ 5 ] Preface The code bundle for the book is also hosted on GitHub at https://github.com/PacktPublishing/Mastering-React-Native. We also have other code bundles from our rich catalog of books and videos available at https://github.com/Packt Publishing/. Check them out! Errata Although we have taken every care to ensure the accuracy of our content, mistakes do happen. If you find a mistake in one of our books-maybe a mistake in the text or the code we would be grateful if you could report this to us. By doing so, you can save other readers from frustration and help us improve subsequent versions of this book. If you find any errata, please report them by visiting http://www.packtpub.com/submit-errata, selecting your book, clicking on the Errata Submission Form link, and entering the details of your errata. Once your errata are verified, your submission will be accepted and the errata will be uploaded to our website or added to any list of existing errata under the Errata section of that title. To view the previously submitted errata, go to https://www.packtpub.com/books/conten t/supportand enter the name of the book in the search field. The required information will appear under the Errata section. Piracy Piracy of copyrighted material on the Internet is an ongoing problem across all media. At Packt, we take the protection of our copyright and licenses very seriously. If you come across any illegal copies of our works in any form on the Internet, please provide us with the location address or website name immediately so that we can pursue a remedy. Please contact us at [email protected] with a link to the suspected pirated material. We appreciate your help in protecting our authors and our ability to bring you valuable content. Questions If you have a problem with any aspect of this book, you can contact us at [email protected], and we will do our best to address the problem. [ 6 ] 1 Building a Foundation in React There is a common trope within the frontend web development community that boils down to new day, new framework. It is a comment on the velocity at which this profession is changing and evolving. The rapid pace can be exhausting, but it is also exciting because of what it represents. The domain of frontend developers seems to be ever expanding–from simple web pages to web applications, mobile applications, and beyond–and with that, the number of smart people contributing ideas and code to the collective knowledge bank is also expanding. With all of that said, any sane person must pick and choose which developments to tune into. When React.js emerged on to the open source scene in May 2013 from the inner sanctum of Facebook, it would have been easy to brush this library off as just another frontend library. That, however, would have been a mistake. It could be said that React was the most significant and influential open source development in frontend technology in recent memory. Its growth beyond the web and its application in the realm of mobile development through React Native is both a testament to its popularity and a boon to its potential utility. React Native is a library for creating native mobile applications using familiar web technologies that is built on top of React. What this means is that in order to understand React Native, we must first explore React. In this chapter, we'll examine the fundamentals of React. First, we'll talk briefly about the circumstances that led to React being created. We'll also cover these React concepts: JSX, a JavaScript/HTML hybrid that we use to describe React components React components Component composition Component properties, or props Handling events Component state Building a Foundation in React The React component lifecycle Alternate component forms A note to the reader: this chapter focuses on React for the web, the original purpose of the library. This provides important context for the remainder of the book. If you already know React for the web, then it is probably safe to skip this chapter and proceed to Chapter 2, Saying Hello World in React Native. Library versus framework When people describe React, they often eschew the description of framework–a description often used for something such as Backbone or Angular–in favor of library. The reason for this more lightweight description is that React is not a complete solution for application development. It is often relegated to only a view-layer solution, and that characterization is mostly correct. React has some mechanisms for maintaining internal state, but it has no opinion about or solutions for data flow and management, server communication, routing, or other common frontend application concerns. React, therefore, is often coupled with some other library or libraries to create a fully fleshed out application. The most common pairing is with an application architecture that is also the brainchild of the wizards at Facebook called Flux. Flux is not a library in and of itself; it is a set of design patterns that have been implemented by many different libraries, which will be discussed in more depth in Chapter 5, Flux and Redux. Motivation for React React and the community, libraries, and patterns that surround it are very much a reaction (pun intended) to some of the most frustrating and prevalent issues that plague JavaScript applications as they grow in size and complexity. JavaScript was not designed for creating large applications; it was designed, famously, in just 10 days as a scripting language to add a modicum of interactivity to lifeless web pages. Chief among these concerns is the unpredictability that comes with shared mutable state. Historically, passing around JavaScript objects that represent the application's state to different views and controllers has been common practice. The ease with which those objects can be mutated by a rogue view, wisdom notwithstanding, can lead to hard-to diagnose bugs, especially as applications and teams grow. [ 8 ] Building a Foundation in React The foundational building block in a React application is the component, which is a declarative description of some visual feature on the page, such as a form or a menu. The declarative nature of components promotes predictability: given some set of external inputs (properties), the output is well defined and deterministic. React also aims to combat one of the hurdles to writing efficient applications: the Document Object Model (DOM) is notoriously slow. If changes to the DOM are relatively infrequent, this may not be a problem, but in a complex application the time it takes to alter and redraw the DOM can add up. This is especially true for applications that take a declarative approach as React does, which necessitates re-rendering whenever the application's state changes. The solution proposed by the React framework is to keep a representation of the DOM in memory, called a virtual DOM, and make all alterations there. Once the alterations have been made in memory, React can apply the minimum number of changes necessary to reconcile the real DOM with the virtual DOM. This also can allow quickly successive changes to be batched for greater efficiency. Taking this approach can lead to great gains in performance that can be noticed by end users. In addition to solving some of the common problems faced when creating JavaScript applications, React components are modular and emphasize composition over inheritance, which makes code immensely reusable and testable. Additionally, a React component often has rendering logic, markup declaration, and even styles in the same file, which promotes the portability of code and the ability to write shared libraries of components. Perhaps the most compelling reason to use React and React Native is the astounding amount of community adoption that has taken place in the last two years. People are excited about this technology, and rightly so; it is a novel approach to developing frontend applications that is, by most accounts, accelerating the development time on teams that choose to adopt it. With React Native, the idealistic promise of learn once, write anywhere is becoming more and more viable. Getting started in React To begin creating an interface in React, the first thing we need to do is break down the interface into conceptual components. We start with a large component, for instance, a news feed. We then say our large component is made up of, or composed of, other smaller components. In the case of our news feed, these smaller components might be individual news items. Each news item, in turn, might be composed of several even smaller components, such as images, a description, and a byline. [ 9 ] Building a Foundation in React This process should continue until the smallest components are bite-sized, reusable visual units that can no longer be easily broken down into smaller pieces. Doing this exercise sets us up well for writing our first code in React. Here is what this process might look like for our hypothetical news reader application. First, identify and give a name to the largest component we can find, in this case, a NewsFeed: Now, draw boxes around the next largest set of components, the NewsItem components: [ 10 ] Building a Foundation in React Next, we can zoom in on a single NewsItem and identify the components that it is made of. Here, we can see that there is an Image, a Title, a Description and a Byline: We've now laid the groundwork to start creating a React application. We have identified six components and their relationships: the NewsFeed, which is composed of NewsItem components, which in turn are composed of Image, Title, Description, and Byline components. Describing components in JSX In recent years, there have been many developments in JavaScript as a language itself. For instance, the new ECMAScript 2015 (ES2015–sometimes called ES6) specification, which defines the next version of JavaScript, is becoming increasingly solidified. If a developer wishes to write in ES2015–and many do–they need to use a program to convert the newer syntax into one that is compatible with the majority of browsers. Additionally, there are a number of JavaScript-like syntaxes, such as CoffeeScript and TypeScript, that ultimately have to be converted to browser-compatible JavaScript in order to function. With all of these developments and alternate syntaxes, many developers have become accustomed to transforming code into browser-compatible JavaScript instead of writing it directly. When Facebook created React, they capitalized on this and created a syntax similar to HTML that could be used to describe components. It's called JavaScript XML (JSX), and it is a declarative markup language that is written in tandem with JavaScript to define a component's layout. Using JSX is not an absolute requirement for writing React, but without it, React becomes verbose and cumbersome. Furthermore, since most developers will be using tools such as Babel already to convert their ES2015 code into JavaScript, writing in JSX does not add much burden because most of those tools come with support for JSX built in. [ 11 ] Building a Foundation in React JSX looks almost exactly like HTML:

Hello World!

It differs from HTML5 only slightly. HTML and JSX have a common ancestor language called XML (Extensible Markup Language). HTML has since diverged in some ways from strict XML that JSX has not. For instance, in the case of a tag such as the image tag (that is, ) HTML and JSX differ. The tag is called self-closing in that there is no standalone closing tag like we might see with a
or a

. For a self-closing tag in HTML, a forward slash before the end is optional: HTML: In JSX (and XML, for that matter), this forward slash is required: JSX: There are other differences between JSX and HTML that arise from JSX being written in the context of JavaScript. The first is that class is a keyword in JavaScript, whereas that word is used as an attribute of HTML elements to allow elements to be targeted by CSS for styling. So, when we would use class in HTML, we instead have to use className in JSX: HTML:

JSX:
A consolation prize for this small inconvenience is we get the benefit of being able to interleave JavaScript into places in our markup where we typically wouldn't in normal HTML. For instance, defining inline styles can use a JavaScript object, rather than cramming all properties into a string. HTML:
JSX:
Notice here that there are two sets of curly braces on the style attribute's value. The outer set of curly braces is used to show that the code contained is JavaScript. The inner set is a JavaScript object literal containing the CSS style property names and their respective values. Not only can attribute values be written in JavaScript, but so too can the content contained between JSX tags. This way, we can use dynamic properties to render text content: HTML: Hello World JSX: {'Hello' + 'World!'} [ 12 ] Building a Foundation in React As we'll see in coming section, there are more tags available to us than we would see in normal HTML. In fact, our application-defined components themselves can be added into JSX markup: Hello React! Understanding JSX is paramount to starting to create React components; however, JSX makes up only a part of a complete component. The component In React, we build applications using composable, modular components. These components represent parts of our visual interface and are rendered as such. In their most simple form, they are simply a description of how to render. We create a component by using ES2015 class syntax: import React, { Component } from 'react'; class Title extends Component { render() { return (

Hello World!

); } } Since the only requirement is that a render() method is defined, this is now a valid and complete (albeit not especially useful) React component. In a typical React application project, a component will be self-contained within a file. Files that contain JSX, such as a component file, sometimes have a .jsx extension in web projects; however, this practice is less common in React Native projects. This extension helps tools such as Babel know how to transform them into browser-compatible JavaScript. The entire contents of the file that defines and exports the Title component, Title.jsx, might look like this: import React, { Component } from 'react'; export default class Title extends Component { [ 13 ] Building a Foundation in React render() { return (

Hello World!

); } } This simple component by itself is not very compelling. So far, everything we've seen in this component could easily be created using only HTML. Rest assured, React provides several ways of making this component more interesting and useful. Component composition As was mentioned earlier in this chapter, React favors composition over inheritance. What does this mean? In essence, it means to build complex or derivative components, instead of using something akin to object-oriented inheritance, we use composition to build up complexity from simple building blocks. Our Title component is pretty simple, but we can build up a more complex NewsItem component from the Title component and other simple components: import React, { Component } from 'react'; class NewsItem extends Component { render() { return (
<Byline /> <Description /> </div> ); } } The JSX returned by the render method of a component is that component's declarative definition. When that JSX includes other components, such as the <Image />, <Title />, <Byline />, and <Description /> elements we see in the preceding code, it is said to be composed of those components. [ 14 ] Building a Foundation in React Composition has other uses besides making increasingly more complex components from smaller, simpler building blocks. Composition can also be used to make derivative components, a task that in an object-oriented programming world we might use inheritance to achieve. For instance, imagine we want to make a component that is a WarningTitle. This component might share many properties with a Title component, but also add bright red border around it in order to draw a user's attention: import React, { Component } from 'react'; class WarningTitle extends Component { render() { return ( <div style={{ border: '1px solid red' }}> <Title /> </div> ); } } Using the previous definition, we would then say that WarningTitle is composed of Title because the latter is returned in the render() method of the former. Props and PropTypes The components that we've seen so far are completely static in that they take no external input and always render exactly the same. This isn't especially interesting because the same outcome can be achieved by writing plain old HTML. However, React provides a mechanism for making components dynamic by using properties, or props. Accepting props Props are passed into a component in order to modify their base definition. Let's take another look at our Title component: import React, { Component } from 'react'; export default class Title extends Component { render() { return ( [ 15 ] Building a Foundation in React <h1> Hello World! </h1> ); } } While the title of a single article might be Hello World!, this component needs to be more dynamic if it is to be reused within all of our NewsItem components. For this, we'll use a React input property, or prop, called titleText. React component methods have a this context that gives access to properties that have been passed in: import React, { Component } from 'react'; export default class Title extends Component { render() { return ( <h1> {this.props.titleText} </h1> ); } } Once again, remember that curly brackets in JSX denotes JavaScript code. Here, we are accessing the component's titleText prop in order to render it within the component's markup: <h1> {this.props.titleText} </h1> PropTypes This by itself is sufficient code to start accepting a titleText property. However, as a best practice, we should include in our component's definition a description of what properties it is equipped to accept. While this may seem like over-engineering and unnecessary in small projects maintained by a single developer, as the project and team grows, explicit definition of properties is key in an untyped language such as JavaScript. [ 16 ] Building a Foundation in React Defining PropTypes in a component is how we formally tell other developers what properties a component accepts and what value types those properties should be. PropTypes are the same across instances of a component and are thus statically attached to the class: import React, { Component, PropTypes } from 'react'; export default class Title extends Component { render() { return ( <h1> {this.props.titleText} </h1> ); } } Title.propTypes = { titleText: PropTypes.string }; Adding PropTypes to a component does not change anything functionally, but it will cause annoying warning messages to be logged to the JavaScript console when they are disobeyed (only when React is in development mode, mind you). To use PropTypes, we'll need to add it to the React import: import React, { Component, PropTypes } from 'react'; The PropTypes module comes with functions for validating different value types, such as string, number, and func. Here, what we are communicating is that this component takes one optional property called titleText, and that property should be of type string: Title.propTypes = { titleText: PropTypes.string }; We could also make this a required property: Title.propTypes: { titleText: PropTypes.string.isRequired } [ 17 ] Building a Foundation in React In addition to having string type props, we can also have other simple types, such as booleans and numbers: Title.propTypes = { titleText: PropTypes.string.isRequired, highlighted: PropTypes.bool, fontSize: PropTypes.number }; Props can not only be used to define the text content, but can also be used to define attributes of an element, for instance, inline style: import React, { Component, PropTypes } from 'react'; export default class Title extends Component { render() { return ( <h1 style={{ backgroundColor: this.props.highlighted ? 'yellow' : 'white', fontSize: `${this.props.fontSize}px` }} > {this.props.titleText} </h1> ); } } Title.propTypes = { titleText: PropTypes.string.isRequired, highlighted: PropTypes.bool, fontSize: PropTypes.number }; One thing to note with the preceding example is that CSS properties that have a dash in them when written in traditional CSS use camel case in React inline style. This is because keys in JavaScript objects cannot contain dashes. React PropType specifications can also be used to validate more complex properties. For instance, we could have a property that is either a string or a number using the oneOfType function, which is as follows: fontSize: PropTypes.oneOfType([ PropTypes.string, [ 18 ] Building a Foundation in React PropTypes.number ]) Likewise, we can specify a set of specific values that a property is allowed to take by using the oneOf method: size: PropTypes.oneOf([ 'small', 'medium', 'large' ]) We can of course specify more complex data types, such as arrays and objects, but we can also be more specific and describe the types of values in an array property or the shape that an object property takes: propTypes: { //Array that can contain anything simpleArray: PropTypes.array, //Object that can contain anything simpleObject: PropTypes.object, //Array that contains only Number values arrayOfNumbers: PropTypes.arrayOf(PropTypes.number), //Object that takes a specific "shape" complexObject: PropTypes.shape({ id: PropTypes.number, name: PropTypes.string }) } Now our Title component is getting interesting. It has gone from something that can be easily recreated using just HTML to something more like a HTML template–still declaratively defined, but dynamic in that it can take external properties. Alternatively, PropTypes can be added to a React component as a static property using the static keyword: import React, { Component, PropTypes } from 'react'; export default class Title extends Component { static propTypes = { titleText: PropTypes.string.isRequired, highlighted: PropTypes.bool, [ 19 ] Building a Foundation in React fontSize: PropTypes.number } render() { return ( <h1 style={{ backgroundColor: this.props.highlighted ? 'yellow' : 'white', fontSize: `${this.props.fontSize}px` }} > {this.props.titleText} </h1> ); } } This syntax is cleaner, but is not officially part of the ECMAScript specification at this point. While most transpiler programs will recognize this syntax, we'll avoid it in this book for that reason. Passing props With a component defined that accepts props, the next step is for props to be passed into this component. In the case of our Title component, the NewsItem component can pass properties into the contained Title component. It does this using the attribute syntax of XML: import React, { Component } from 'react'; import Title from './Title'; export default class NewsItem extends Component { render() { return ( <div className="news-item"> <Image /> <Title titleText="Hello World!" highlighted={true} fontSize={18} /> <Byline /> <Description /> [ 20 ] Building a Foundation in React </div> ); } } Strings are the only value types that can be passed in as a prop directly: titleText="Hello World!" For other JavaScript data types, such as numbers, Booleans, and arrays, we must surround the values in curly braces so that they are interpreted correctly as JavaScript: fontSize={18} For Boolean props, we can shorten their input to where the property name's presence is interpreted as true and its absence is interpreted as false, much like in HTML: <div className="news-item"> <Image /> <Title titleText="Hello World!" highlighted fontSize={18} /> <Byline /> <Description /> </div> Default props In a previous section, we specified, using PropTypes, that the titleText property of the Title component is required, but the other two properties are optional. This raises an interesting question: what will the value of those properties be if they are not specified? Well, without any intervention from the component developer, those properties will appropriately have the value undefined when no value is passed in. This could be problematic in some situations. For our fontSize property, a value of undefined could lead to some unpredictable and potentially error-prone code because it is expecting a number. Luckily for us, React has a mechanism for specifying default values for optional properties that have not been passed in explicitly. This mechanism is a method on the component called defaultProps and we can use it in Title, statically, like this: import React, { Component, PropTypes } from 'react'; [ 21 ] Building a Foundation in React export default class Title extends Component { render() { return ( <h1 style={{ backgroundColor: this.props.highlighted ? 'yellow' : 'white', fontSize: `${this.props.fontSize}px` }} > {this.props.titleText} </h1> ); } } Title.propTypes = { titleText: PropTypes.string.isRequired, highlighted: PropTypes.bool, fontSize: PropTypes.number }; Title.defaultProps = { highlighted: false, fontSize: 18 }; defaultProps must be a JavaScript object where keys are property names and the values are the default values to use in the case that no values were passed in for that particular property. We can now define a Title component that isn't highlighted and has the default font size of 18 pixels by simply writing the following: <Title titleText="Hello World!" /> In context, our NewsItem component is now simplified to this: import React, { Component } from 'react'; import Title from './Title'; export default class NewsItem extends Component { render() { return ( <div className="news-item"> <Image /> [ 22 ] Building a Foundation in React <Title titleText="Hello World!" highlighted /> <Byline /> <Description /> </div> ); } } Sometimes, a component will receive its props from several levels above. For instance, maybe NewsFeed specifies the title of an individual NewsItem, rather than having NewsItem provide it statically itself, as we have done in the previous examples. Parameterizing this property allows the NewsItem component to be more generic and reusable: import React, { Component, PropTypes } from 'react'; import Title from './Title'; export default class NewsItem extends Component { render() { return ( <div className="news-item"> <Image /> <Title titleText={this.props.titleText} highlighted /> <Byline /> <Description /> </div> ); } } NewsItem.propTypes = { titleText: PropTypes.string.isRequired }; Here, we have shown how the NewsItem component can accept a property, and in turn, pass it down to the Title component. [ 23 ] Building a Foundation in React Props.children Every component has an optional special property that is called children. Normal properties, as we have seen, are passed in using something similar to the HTML attribute syntax: <Title titleText="Hello World" /> You can also pass in text or other component elements by placing them in between an opening and closing tag. We can refactor our Title component to accept children instead of the titleText prop: <meta charset="UTF-8"><title> Hello World Now, the render() method of our Title component becomes this: render() { return (

{this.props.children}

); } Note that we could now also pass in other React elements into the Title as property by also placing them in between the opening and closing tags: Hello World! <img src="icon.png" /> [ 24 ] Building a Foundation in React When validating the children prop, we can use a special PropTypes called node, which means anything that can be rendered by React: Title.propTypes = { children: PropTypes.node.isRequired, highlighted: PropTypes.bool, fontSize: PropTypes.number }; Event handlers In JavaScript development, we often think of our application as reacting to user events on the page. For instance, we may listen for a submit button on the page to be clicked, and when it is, validate a form. Functions that respond to these user events are sometimes dubbed event handlers or event listeners. In a simple JavaScript application, we register these event handlers by querying the DOM for some element and adding an event listener function to run when the event of interest occurs. Here is how we might do this: document.querySelector('form').addEventListener('click', validateForm); function validateForm() { alert('The form is valid!'); } In the early days of JavaScript, we probably would have used HTML event attributes in order to respond to user events on some element. The equivalent code for this inline approach to event handling might look something like this:
...
In React, the way we do event handling is more like the inline JavaScript of yesteryear. Elements in React can optionally take event handler properties in order to respond to user inputs. A React element is the portion of a component that is returned from the render function. In other words, it is a description of what we want rendered on the screen, generally written in JSX. Our form from the previous example written in JSX would only have a couple of subtle differences:
[ 25 ] Building a Foundation in React To show an example of event handling in context, let's return to our NewsItem example. Let's imagine that we want our application to respond to a user clicking on the news item. We can do this by creating an event listener function in the component and adding it to the outer element in JSX: import React, { Component, PropTypes } from 'react'; import Title from './Title'; export default class NewsItem extends Component { onClick() { alert(`You've clicked on ${this.props.titleText}`); } render() { return (
{this.props.titleText}
); } } NewsItem.propTypes = { titleText: PropTypes.string.isRequired }; Take note that we are binding the render method's this context to the onClick method when adding it as a click handler: onClick={this.onClick.bind(this)} [ 26 ] Building a Foundation in React We need to do this in order to ensure this has the same meaning in the onClick method as it does in other component methods. This way, we can still access props and call other component methods. However, the better way to bind the this context to the event handler method is to do so within the component's constructor: constructor(props) { super(props); this.onClick = this.onClick.bind(this); } Then there is no need to re-bind the event handler in the JSX, which can be simplified:
This method is preferred not only because it reduces the amount of typing, but also because React internally optimizes to make it more efficient. Event listeners in React, much as they do without React, receive an optional argument that is an object representing the user event. We can access this event object in order to suppress default behavior, for instance, in a form submission, by using event.preventDefault(). We can also use the event object to, for example, see what document element was targeted by the action or, in the case of a key press event, see which specific key was pressed by the user. To get access to the event, we just need to add it as a parameter to our event listener method: onClick(event) { console.log('User event', event); alert(`You've clicked on${this.props.titleText}`); } State Occasionally, a component will need to keep track of some internal state in addition to the external, read-only, properties that are passed into it. State is necessarily internal to the component and, generally, exclusively tied to some visual display option (for instance, is the component visually expanded or collapsed). [ 27 ] Building a Foundation in React Much in the same way that a component instance can access external properties via this.props, a component instance can access its internal state using this.state. Using internal state, we could optionally show parts of NewsItem only when that item is in an expanded state: render() { let body = null; if (this.state.expanded) { body = (
); } return (
{this.props.titleText} {body}
); } We can see now that the body variable will only be defined if the internal state is expanded. Another thing we can see here is that a
element has been added around the description and byline. The reason we do this is because JSX elements must have a single root node in order to return them or store them in a variable. Alternatively, we could have stored each element in its own variable: render() { let byline = null; let description = null; if (this.state.expanded) { byline = ; description = ; } [ 28 ] Building a Foundation in React return (
{this.props.titleText} {byline} {description}
); } While this code is completely valid, we can make it even better by splitting out conditional rendering into a separate method: renderBody() { if (this.state.expanded) { return (
); } return null; } Then, we can use this helper method within our main render() method in order to make things a bit clearer: render() { return (
{this.props.titleText} {this.renderBody()} [ 29 ] Building a Foundation in React
); } We've now seen how to use internal state to render things conditionally, but we have not yet seen how that state is defined or how it is modified. In React, we can specify the initial values of internal state by assigning them in the constructor of the component. The component's initial state, much like its default properties, should be a JavaScript object: constructor(props) { super(props); this.state = { expanded: false }; this.onClick = this.onClick.bind(this); } This method describes the initial state of a component, but it does not provide us with any means to update that state. In order to update the state of a component, we can use a React component's setState method to assign, or reassign, any internal state value. Typically, updating state happens as a response to some user input or user event. In the last section, we learned how to define methods that respond to these user events, such as clicks, and how to attach these event listeners to the appropriate React element. Let's modify our onClick event handler to change the expanded state of our component instead of simply alerting: onClick() { this.setState({ expanded: !this.state.expanded }); } When we use setState in this way, React will notice that the internal state has changed, and this will trigger a new rendering using the new internal state. For this reason, we should never manipulate the state of a component directly: //Do not do this this.state.expanded = false; [ 30 ] Building a Foundation in React If we change the internal state directly, React's rendering engine will not become aware of it and the component we see on our page will differ from the one in JavaScript. The same goes for props; they are external and should only be changed as a result of new values being passed in through JSX: //Also don't do this this.props.titleText = 'Hello World!'; Now that we've demonstrated how to use internal state to display something conditionally, how to initialize state by setting it in the constructor method, and how to modify internal state in response to some user event using setState, let's look at all of this in context in our NewsItem component: import React, { Component, PropTypes } from 'react'; import Title from './Title'; export default class NewsItem extends Component { constructor(props) { super(props); this.state = { expanded: false }; this.onClick = this.onClick.bind(this); } onClick() { this.setState({ expanded: !this.state.expanded }); } renderBody() { if (this.state.expanded) { return (
); } return null; } render() { [ 31 ] Building a Foundation in React return (
{this.props.titleText} {this.renderBody()}
); } } NewsItem.propTypes = { titleText: PropTypes.string.isRequired }; Now we have a component for our news item that starts out collapsed (not expanded) and not showing the description or byline, but when the user clicks on the news item, it expands to show the two previously hidden elements. The component lifecycle Every React component that is rendered into the DOM goes through a series of steps before and after rendering. As React component developers, we can hook into these steps, called the component lifecycle, in order to perform tasks or check conditions specific to some stage in that lifecycle: [ 32 ] Building a Foundation in React Mounting the component Before a component is mounted, which means placed into the DOM for the first time, React will look at that component's class to see if it has a method called componentWillMount defined. Should this method exist, React will invoke it. This method is a good place to do things such as set up timers needed by the component or request data the component needs from the server: componentWillMount() { //Decrement an internal state counter every second setInterval(() => { this.setState({ secondsLeft: this.state.secondsLeft - 1; }); }, 1000); } [ 33 ] Building a Foundation in React The next step in the component's lifecycle is the first render. The render() method we've seen before. React calls this method and then, the first time, converts the JSX element output to HTML elements and places them in the DOM. In other words, it mounts the component. Once mounting is complete, the next step in the lifecycle, an optional method called componentDidMount, is called. This is often an integration point for non-React libraries. With that said, a word of warning: it is generally not a good idea to use libraries that manipulate the DOM alongside React. Remember that React works by keeping a virtual representation of the DOM in memory in order to calculate change sets and apply them. When other libraries are modifying the DOM, it can quickly become out of sync with what React expects. This could, and more often than not, will, lead to errors when React tries to reconcile changes: componentDidMount() { //Integrate with an external library here } From here, the component is stable and its lifecycle dormant until one of two things happens. The first thing that could happen is the component's parent could pass it new props. The second is some event or interval triggers a change in internal state. These two actions, of course, necessitate a re-render. Before a re-render happens, there are a few other lifecycle methods that will be called. The update cycle The first method called during a property update cycle is componentWillReceiveProps. Here, we not only know that the component is about to receive a new set of properties, but we also can see what those properties are and how they compare to the old ones: componentWillReceiveProps(nextProps) { //an object of new props console.log(nextProps); //The current (old) props console.log(this.props); } This lifecycle method is a good place to update state that is somehow derived from props because it is the only update lifecycle method that is not called for both prop and state changes. [ 34 ] Building a Foundation in React This brings us to the next lifecycle method that is called when either props or state are updated: shouldComponentUpdate. This method is unique among lifecycle methods in that it is the only one that expects a return value. As you may be able to guess, the return value expected is a Boolean. If the method returns true, the lifecycle continues as we expect it. However, if shouldComponentUpdate returns false, the lifecycle is short-circuited here and a re-render does not occur. Within this method, we can see not only the new properties, but also the new state that will be rendered: shouldComponentUpdate(nextProps, nextState) { if (this.props.uid !== nextProps.uid) { return true; } return false; } If a component does not define this method, it is always assumed to be true. React, though, gives you the ability to override this behavior. This can become important in large applications with many components and many layers of component nesting. Using shouldComponentUpdate, we can fine-tune when a component re-renders in order to enhance the performance of our application. This is important because, while React is good at optimizing renders, rendering is still computationally expensive and excessive rendering can slow down an application to the point where a user can feel stuttering. If shouldComponentUpdate returns true (or is not defined by the component), the next step in the lifecycle is componentWillUpdate, which is the last step before re-rendering. Here, like in shouldComponentUpdate, we have access to both the new properties and the new state: componentWillUpdate(nextProps, nextState) { //Prepare for render! } At this point, React will call render on the component again, getting its new JSX representation. It will compare this new JSX to the old JSX in the virtual DOM and create a change set to apply to the real DOM. Once this process is complete, we arrive at the next step of the lifecycle, which is componentDidUpdate. This method is very similar to componentWillUpdate, except that it receives the previous properties and state as arguments: componentDidUpdate(prevProps, prevState) { //Here are the old props console.log(prevProps); //And here are the current (new) props [ 35 ] Building a Foundation in React console.log(this.props); } Now, we've completed the update lifecycle. At this point, once again the component remains dormant until another change in properties or state occurs. This process continues over and over again until the component is removed, or unmounted, from the DOM. Unmounting the component Just before a component is removed from the DOM, the final stage of the component's lifecycle will be completed. Here, React calls the optional componentWillUnmount method, which receives no arguments. This method is a good place to clean up anything that the component created over the course of its life. For instance, if the component started an interval upon mounting, here would be a good place to stop that interval. In our componentWillMount example, we showed starting a countdown interval that fired every second after the component mounted. If we store that interval's ID in state, we can then stop the interval when the component is being unmounted: componentWillMount() { //Save the interval in state this.setState({ tickInterval: setInterval(() => { this.setState({ secondsLeft: this.state.secondsLeft - 1; }); }, 1000); }); } componentWillUnmount() { //Stop the countdown before unmounting clearInterval(this.state.tickInterval); } While we've gone through and demonstrated how each lifecycle method might be used within a component, it is important to point out that we would very rarely need to use every component lifecycle method in a single component. Remember that each one is optional and need not be defined by the component unless some feature of its functionality necessitates it. In fact, our NewsItem component does not need any of these lifecycle methods to do exactly what we want. [ 36 ] Building a Foundation in React Alternate component forms In React, there are three ways to define a component. The way we've seen so far uses ES2015 classes to define a component and its methods. This is currently the most common method for defining React components and, in fact, the one you'll encounter most often in documentation and in this book. React.createClass Before ES2015 and its class syntax became popular and brought into React, the way to define a component was by using the React.createClass function. This function takes as an argument a JavaScript object that describes the component and its methods. This conceptually is very similar to the way we have seen so far, but has some syntactic differences. To demonstrate, let's take a look at what our NewsItem component looks like using this method: React.createClass({ propTypes: { titleText: PropTypes.string.isRequired }, getInitialState() { return { expanded: false } }, onClick() { this.setState({ expanded: !this.state.expanded }); }, renderBody() { if (this.state.expanded) return (
; ); } return null; [ 37 ] Building a Foundation in React }, render() { return (
{this.props.titleText} {this.renderBody()}
); } }); Other than the obvious syntactic differences, there are a few subtle differences in how we define and use components with React.createClass that we should draw our attention to. The first is instead of simply assigning the state in the class constructor, we define a getInitialState method in the component, which returns the initial component state as an object: getInitialState() { return { expanded: false } } The next thing we might notice is that, previously, event handler functions were bound to the component's this context either in the constructor or within the event attribute assignment. When using the React.createClass syntax, we have no longer need to explicitly bind the context:
[ 38 ] Building a Foundation in React We may have also noticed that rather than defining the propTypes statically on the class, we instead do it within the component object: propTypes: { titleText: PropTypes.string.isRequired } This component does not need default properties, but if it did, we would also define those inside the component object. We do this by defining a method similar to getInitialState called getDefaultProps that also returns an object: getDefaultProps() { return { someProp: 'some value' } }; Functional components For simple components that maintain no internal state, we can define them simply as functions that take props as input and return JSX elements as output. These components are not only succinct, but may in the future be more performant than components defined in other ways. For these reasons, it is recommended that we use functional components wherever possible. Because of its simplicity and lack of internal state, our Title component from an earlier section is a good candidate for being a functional component. Here is what that component would look like with this alternate syntax: const Title = (props) => (

{props.children}

); [ 39 ] Building a Foundation in React Taking advantage of ES2015 arrow function syntax, our large traditionally defined component has been simplified to a single function. In addition to not having internal state, functional components don't have lifecycle methods. They can, however, have defaultProps and propTypes that can be specified in the same manner as class components: Title.propTypes = { titleText: PropTypes.string.isRequired }; Summary The React library has created a new way to develop user interfaces for web applications through creating declarative and composable components in the new, but familiar, JSX syntax. Since its introduction, it has grown immensely in popularity. At Facebook's F8 developer conference in 2016, it was estimated that upwards of 250,000 developers were using React in some way. This enthusiasm led the community to look for new places to use their favorite library, and in early 2015, React Native was born. In this chapter, we covered the fundamentals of React, from conception to implementation. We learned how to take a user interface and structure it as components, the building blocks of React applications. Starting with simple components, such as a static title, we then built up to more complex components by adding props, event handlers, state, and lifecycle methods. Finally, we looked at some alternate ways of representing React components and discussed when each was appropriate. In the next chapter, we will take this knowledge of React into the realm of native mobile applications by building a Hello World application in React Native. [ 40 ] 2 Saying HelloWorld in React Native Now that we've introduced you to the basics of programming in React, it's time to dig into some of the underlying tools and technologies that make React Native work. This will provide valuable context as you progress through the remainder of this book. We'll also touch on some of the more popular mobile development alternatives to React Native. This will help you understand where React Native fits into the broader mobile development ecosystem and better inform your decision-making as to which technology best suites your mobile requirements. Once we've completed setting context, we'll switch gears and focus on configuring your computer for running and debugging your very first React Native application using the iOS Simulator. Since our immediate goal is to get you up and running quickly, we'll only focus on configuring your environment for iOS. Chapter 9, Refactoring for Android, is entirely dedicated to configuring your computer for Android development and refactoring your app to run across both platforms. We will also save much of the React Native API specifics for Chapter 4, Starting our Project with React Native Components and APIs. In this chapter, we'll cover the following topics: A review of a few popular mobile development options catered toward JavaScript developers A review of the various software and tools we'll use to build React Native applications Installing and configuring all the software needed to build our first React Native app Walk through basic strategies for debugging in React Native Saying HelloWorld in React Native Understanding the mobile app development ecosystem When it comes to building mobile applications, the two most popular approaches have been, first, building a native application for each target platform (iOS, Android, and so on), and second, writing a hybrid application by using web technologies (HTML, CSS, JavaScript) and wrapping the app inside of a container WebView using a tool such as Adobe PhoneGap. Each option has its pros and cons. Native applications often feel faster and more responsive. They have built-in support for complex touch gestures and they look and feel consistent with their platform. As a post from the Facebook blog states, the reason we build native apps on these proprietary platforms is that right now, we can create better-feeling experiences that are more consistent with the rest of the platform than we can on the web. (Source: https://co de.facebook.com/posts/1014532261909640/react-native-bringing-modern-web-techn iques-to-mobile/) However, this comes at a cost. For one, the native technology stacks are completely different from one another. Developing a native application for iOS typically involves authoring your code in Objective-C or Swift. Android applications are often written in Java. Additionally, the environment you write your code in is different. Xcode is the de facto choice for iOS development, and Android development is typically done with tools such as Eclipse or Android Studio. Juggling lots of tools and languages shouldn't be anything new to seasoned frontend developers. However, couple these differences with differing best practices, approaches to networking, and a limited number of sharable assets across platforms and you've got quite a bit of work ahead of you just to get a cross-platform app off the ground. Hybrid applications are a very popular alternative, particularly for those with frontend development experience. Hybrid apps are easier to scale because you only have to author one codebase that can be deployed to multiple platforms. For a large swath of applications, the hybrid approach makes sense, particularly if you or your team's skill set mostly aligns with that of your traditional frontend developer: HTML, CSS, and JavaScript. However, achieving the same level of responsiveness and gesture support as a native app can prove deeply challenging. In this section, I'll provide an overview of a few mobile development frameworks. This is not intended to be comprehensive list. Other options, such as Titanium (https://www.appc elerator.com/), Fuse (https://www.fusetools.com), and others may also be worth exploring. [ 42 ] Saying HelloWorld in React Native Adobe PhoneGap Adobe PhoneGap is a very popular solution to hybrid development. It's built off the open source Apache Cordova library and provides a Command Line Interface (CLI) for packaging your web application built with HTML, CSS, and JavaScript inside of a native container that can be installed and deployed to native app stores. The native container is a WebView that removes any browser window decoration and runs your web application in full screen. PhoneGap allows you to access different native APIs, such as the device's camera, GPS, and accelerometer. Additionally, Cordova has a rich ecosystem of plugins that provide a bridge to all sorts of phone features that can be interfaced directly within your JavaScript code. Ionic Ionic is another hugely popular hybrid application framework. It comprises two major pieces: Ionic Framework (http://ionicframework.com/) and the Ionic CLI (http://ionic framework.com/docs/cli/). Ionic Framework is a mobile framework that includes common UI widgets appropriate for mobile interfaces such as action sheets, mobile navigation, infinitely scrolling lists, and popovers. These components are built on top of Google's Angular JS (https://angularjs.org/) framework using Angular directives. If you're familiar with Angular, working with Ionic should be really straightforward. The Ionic CLI is a tool for managing a lot of the tedious parts of mobile app development, such as scaffolding, building, and deploying to phones. Ionic CLI also provides multiple templates for beginning your project based on common UI patterns. Similar to PhoneGap, Ionic is built on top of Cordova. This means you'll be able to leverage the same Cordova plugins in your Ionic applications. Currently, Ionic is built using Angular 1.x. As of this writing, Ionic 2 is available for preview and will pair with the newly released Angular 2 framework. NativeScript Telerik's open source NativeScript lets you build native apps for iOS and Android (they also plan to add support for Windows Universal apps soon) with an approach similar to React Native. Unlike the Cordova options, there is no WebView rendering HTML and CSS. NativeScript relies on JavaScript running on the device with JavaScriptCore on iOS and V8 for Android. [ 43 ] Saying HelloWorld in React Native Your JavaScript code communicates through NativeScript to the underlying platform rendering real native views. NativeScript uses XML markup for declarative UIs that can even be customized per platform either using separate XML files (that is, myView.ios.xml and myView.android.xml) or using platform-specific tags within a view. As the NativeScript site states, “NativeScript has a lot of cool features, such as two-way data binding between JavaScript objects and native UI components, and a CSS implementation for native apps.” (Source: http://developer.telerik .com/featured/nativescript-works/). One important differentiator between NativeScript and alternative offerings is its ability to directly access all native platform APIs through JavaScript. The Telerik site provides several good examples of what this might look like in an application: var alert = new UIAlertView(); alert.message = "Hello world!"; alert.addButtonWithTitle("OK"); alert.show(); (Source: http://developer.telerik.com/featured/nativescript-works/) In the preceding sample, UIAlertView is a native class in Objective-C. NativeScript allows you to access these native APIs without needing to touch Objective-C or Java. The NativeScript runtime injects into the global namespace of the platform's JavaScript virtual machine all the meta information of the iOS or Android API. This allows you to successfully execute something like the following in an Android environment: var time = new android.text.format.Time(); (Source: http://developer.telerik.com/featured/nativescript-works/) NativeScript allows you to style your application using a subset of the CSS language. You can place your CSS inline, in page-specific CSS files, or in application-wide CSS files. You can also layout your views using the predefined layouts–AbsoluteLayout, DockLayout, GridLayout, StackLayout, and WrapLayout. These web-like paradigms make NativeScript a very enticing option for frontend developers looking to develop native applications. [ 44 ] Saying HelloWorld in React Native React Native React Native is an open source project released by Facebook in March 2015. The goal of React Native is to allow developers to write high-quality native applications for iOS and Android using familiar web technologies. It uses the same declarative approach to constructing user interfaces as React for the web. React Native also aims to reduce many native development inefficiencies. Rather than deal with the slow process of write > compile > deploy > debug, which can cripple development on larger native apps, React Native allows you to simply refresh the app after making a change without the slow compile and deploy steps, just like on the Web! This makes for a much improved developer experience. And, unlike normal native development, React Native allows you to share far more code across platforms. However, Facebook points out that React Native is not intended to be a write once, run anywhere solution. They acknowledge that each platform has its own look, feel, and capabilities. Instead, React Native allows you to leverage common technologies to build across multiple platforms. They call this learn once, write anywhere. React Native apps are authored very similarly to React for the Web. You write your business logic in JavaScript and compose your views using JSX. Similar to NativeScript, React Native does not rely on WebViews. React Native runs an embedded instance of JavaScriptCore that communicates through the React Native bridge to platform-specific native components that look and feel as they should on the platform. React Native also exposes underlying platform APIs, allowing you to access the device's camera, GPS, and the like all in JavaScript. However, unlike NativeScript, React Native has you compose your application just like React–by creating a nested component tree structure. React Native maintains its high performance by executing layout calculations and JavaScript on separate threads, leaving the main thread focused on rendering native views, handling gestures responses, and smooth animations. React components are themselves pure, side-effect-free representations of the application state. UI updates are prompted by changes to a component's props or state. React then goes through its usual update lifecycle and asynchronously batches up the minimal updates necessary to send over the React Native bridge. The bridge is how JavaScript then communicates to the native side and how the native side messages back to JavaScript. However, you can think of the bridge as an implementation detail that can be largely ignored in your day-to-day development. For the most part, you can focus on writing your code in JavaScript using the React Native APIs and let React Native take care of the ugly parts. [ 45 ] Saying HelloWorld in React Native React Native comes bundled with support for many APIs you're used to seeing on the Web. This include, among others, networking APIs for fetch, XMLHttpRequest, and WebSockets along with geolocation and requestAnimationFrame. React Native has built-in support for ECMAScript 2015 and parts of ECMAScript 2016. The React Native Packager (more on this later) runs Babel, a tool for transpiling ES2015 and ES2016 into ECMAScript 5. This is necessary as many older JavaScript runtimes only support parts of ES2015 at this point. But thanks to Babel, this means you can leverage many of the new JavaScript language features in your React Native apps. If you're unfamiliar with Babel, you can experiment with it in the Babel REPL available on their website at https://babeljs.io/repl/. Extending React Native Being a JavaScript framework, you're automatically able to leverage a vast number of JavaScript libraries such as Moment.js and Lodash. But every now and then you'll need to do something that requires native code that isn't available in the React Native API. Through React Native's Native Modules, you can extend the capabilities of React Native allowing you to access platform APIs, reuse existing native code, or perhaps offload an expensive task to the native side. A rich ecosystem of React Native plugins already exists, adding support for things like Google's Material Design, barcode scanners, and an assortment of user interface components. As a testament to how far React Native can be extended, during Facebook's 2016 F8 conference, a React Native plugin for the Microsoft Windows Universal Platform was announced. This opens up React Native development to both Windows and Xbox. We'll touch more on this in Chapter 12, React Native Tools and Resources. We'll also review how you can build your own Native Module in Chapter 10, Using and Writing Native Modules. Introducing style and layout in React Native Before we wrap up our introduction to React Native, we must discuss style. Similar to NativeScript, React Native borrows many ideas of styling for the Web. However, unlike NativeScript, you don't author CSS selectors in a CSS file. Instead, you write JavaScript objects that align with many familiar CSS properties. For example, in CSS, you might write the following: .container { width: 400px; height: 400px; [ 46 ] Saying HelloWorld in React Native background-color: #222222; } .box { border-width: 2px; border-color: #cc0000; } However, in React Native, you would write the following in JavaScript: const styles = StyleSheet.create({ container: { width: 400, height: 400, backgroundColor: '#222222' }, box: { borderWidth: 2, borderColor: '#cc0000' } }); Note that instead of writing properties such as border-color, you instead write the camel cased borderColor. This approach actually follows the same conventions used when updating DOM style properties for the Web. Because these are JavaScript objects, you'll need to add quotes around strings. Also, you must omit units such as px for numeric values. There are several reasons why the React Native team chose not to implement CSS as it exists on the Web. CSS at scale is hard. It's not impossible. But it is hard. There are many approaches for scaling large CSS libraries for the Web, such as OOCSS, BEM, and SMACSS. Each has its own take but none can escape one of CSS's biggest hurdles: everything is entirely global. CSS was never intended to be isolated from the global namespace. For many developers, this seems counterintuitive since global variables are usually a bad practice. Even tools such as Bootstrap and Zurb's Foundation rely heavily global SCSS variables. Writing CSS in JavaScript allows you to isolate styles from the global name space. There's one other major piece to React Native's approach to layout. React Native uses flexbox as the default layout system. If you're familiar with flexbox for the web, it operates very similarly. We'll go much deeper on style and layout in Chapter 3, Styling and Layout in React Native. For now, let's get our environments configured to build our first React Native application. [ 47 ] Saying HelloWorld in React Native Understanding all the React Native tools Like most modern development, there are a few tools required to build a React Native application. Luckily, React Native is pretty easy to configure relative to many frameworks out there. We'll get into installing all these tools shortly. First, let's review what all the tools are how they fit into the bigger picture of developing a React Native app. Xcode In order to build an iOS application, you'll need Apple's Xcode IDE. React Native runs on iOS 7 and above. This means that you'll need Xcode version 7.0 or higher. (We'll be using Xcode 8 in this book.) Whether you love, hate, or are altogether indifferent about Xcode, we won't actually be spending much time in it. Initially, we'll just use Xcode to launch our app in the iOS Simulator. Also, because we'll mostly be testing our app in the iOS Simulator, you don't need to worry about enrolling in the Apple iOS Developer Program. However, if and when you wish to ship an app to the App Store, you will need to register. Gustavo Ambrozio has a wonderful series on how to configure everything required for submitting to the Apple App Store; for more information, refer to https://www.raywenderlich.com/8003/how-to-submit-your-app-to-apple-fro m-no-account-to-app-store-part-1. Google Chrome Wait, Chrome? I thought we were making native mobile apps? Don't worry. We are. If you've been developing web apps for some time, chances are you've had some time to play with Chrome's amazing DevTools. Thankfully, the Facebook team feels the same way. You can actually debug your React Native apps running on the iOS Simulator or your native device in Google Chrome. It's pretty amazing and is from my experience one the biggest selling points when showing off React Native to other developers. Homebrew (also known as brew) Homebrew is a package manager for macOS (formerly known as Mac OS X). We won't be interfacing with this tool much at all in this book. It'll simply be used for installing some of the other tools we'll need to get our environments up and running. Once everything is configured, you can almost forget it exists. If you're curious, though, you can find out more about Homebrew on its website, http://brew.sh/. [ 48 ] Saying HelloWorld in React Native Node.js and npm Node.js is a server-side JavaScript runtime environment. React Native ships with some tools that are written for Node.js. Additionally, we will use Node's package manager, npm, to install the React Native command-line tool along with other libraries in later chapters. It's very likely you've encountered Node and npm in the past. Almost all modern frontend tooling, such as Gulp, Babel, or Webpack, run on top of Node. Watchman Watchman is an open source tool created by Facebook (https://facebook.github.io/wat chman/). React Native's packager uses Watchman to recursively watch for changes to our source code files across one or more directory trees. Once it detects a change, it automatically rebuilds the JavaScript bundle. This allows us to sidestep one of the slowest and most painful parts of native development. Much like several of our other tools, once Watchman is installed, you won't have to worry about it. The React Native Package Manager handles running Watchman for us. Flow Unlike the other tools mentioned, Flow is entirely optional. Flow is yet another open source tool created by the Facebook team (http://flowtype.org/). It's used to add type annotations to our JavaScript code. JavaScript, as you likely already know, is a dynamically typed language. This means you never need to declare a variable as an int or a string. You just declare a variable and set a value. The type is implicitly set based on the value you assigned. This makes JavaScript an incredibly powerful and dynamic language. But as the saying goes, with great power comes great responsibility. That said, many JavaScript developers are embracing type annotation tools such as Flow as a way to guard against potential errors in their code. Once you've annotated your code with types, you can run flow from the terminal to verify everything is as expected. [ 49 ] Saying HelloWorld in React Native Following is a simple example from the Flow website: // @flow function foo(x) { return x * 10; } foo('Hello, world!'); The previously code will execute without error but it isn't likely going to return a result that's particularly useful. Passing a string to foo will result in NaN (Not a Number). So here's how we might try to guard against this using Flow: // @flow function foo(x: number): number { return x * 10; } foo('Hello world'); Note the number type annotations that were added to both the function's parameters and the function's return value. Now, running flow will produce an error alerting you that the argument 'Hello world' is incompatible with the expected type. Flow can be configured for a project by creating a .flowconfig file in the root directory of your project. The React Native CLI actually provides you an initial configuration when it creates your project. React Native command-line interface (CLI) The React Native CLI is a small Node app that offers a simple init command used to create new React Native applications. There really isn't much to it. As we'll see shortly, once you run the CLI, it will create a standard React Native app with all the necessary files and dependencies needed to build an app for iOS and Android. Installing our tools At this point, we have covered what each of the tools in our tool chain is responsible for doing. So with that out of the way, let's begin installing each of them. [ 50 ] Saying HelloWorld in React Native Installing Xcode The first thing you'll need to do is ensure you have version 7 or later of Xcode installed. However, I recommend you install Xcode 8 as that's what we'll be using throughout this book. If you already have Xcode installed, verify the version by launching the program and then clicking on Xcode | About Xcode. You should see an image similar to the following screenshot: If you don't have Xcode installed, you'll need to download it from the Apple App Store. To do this, launch the App Store application and search for Xcode using the search bar in the top right corner of the window. Once you find it, click on the Get button and then Install App. You may need to enter your Apple credentials before downloading. The Xcode installer is pretty large, so while we wait on that, you can start downloading the next set of tools. Installing Homebrew The next series of tools must be installed through the terminal. You can use the macOS Terminal app or another terminal of your choosing. You can search for Terminal (or any other application) by using Command + Space on your keyboard. Then type Terminal and launch it. [ 51 ] Saying HelloWorld in React Native Once the terminal is open, visit http://brew.sh in your web browser. Copy and paste the Install Homebrew command into your terminal and press Enter. You'll need to have administrator privileges in order to install Homebrew and most other tools. You may have to press Return a second time for the terminal to ask for your password. Type in your account password, press Return, and wait for Homebrew to finish installing: Once it's done installing, your terminal window should look like the following: [ 52 ] Saying HelloWorld in React Native Installing Node and npm Next on our list are Node and npm. As the React Native docs recommend, you can install this through brew: brew install node Node comes with npm, so you don't have to worry about installing that separately. I recommend installing the latest version of Node and npm, version 6 and 3, respectively, at the time of writing. Once you've installed Node, you can run npm -v and node -v from the terminal. If you see version numbers, you're good to go: [ 53 ] Saying HelloWorld in React Native Installing Watchman and Flow Next up are Watchman and Flow. Again, Flow is entirely optional. If you wish to experiment with it, you're welcomed to install it. It won't hurt anything. If you'd rather skip it for now, that's totally fine as well. From the terminal, run brew install watchman: And if you wish, run brew install flow. Installing the React Native CLI Okay! We're almost done with installing everything. There's just one more it we need: the React Native CLI. Again, from the terminal, run npm install -g react-native-cli. Using npm, this will globally (-g) install the React Native CLI that you'll use to scaffold your React Native applications. However, don't be surprised if you see an error that looks like the following: [ 54 ] Saying HelloWorld in React Native This is pretty common permission error. One way to get around this is by prefacing the command with sudo, which will required you type your password. However, we can fix our permissions pretty easily so that sudo is unnecessary. Here are the steps: 1. Type in npm config get prefix. 2. If you see /usr/local, then simply run sudo chown -R $(whoami) $(npm config get prefix)/{lib/node_modules,bin,share}. 3. You'll be prompted for your user password. Enter it and press Return, and your permissions should be set. 4. If after running npm config get prefix you get a different response, check out https://docs.npmjs.com/getting-started/fixing-npm-permissions. There are more detailed instructions and different options for how to fix npm permissions. [ 55 ] Saying HelloWorld in React Native Once you have your permissions buttoned up, rerun npm install -g react-native cli. Once it's done, you should see something like the following: Finally, you're all set. Now let's create an app! Creating our first React Native app If you're fairly well versed in navigating the terminal, go ahead and cd into whichever directory you plan to place your code. We'll be putting this project on our desktop. You can always move it later if wish.Enter the following into the terminal: cd ~/Desktop Then type the following: react-native init HelloWorld. [ 56 ] Saying HelloWorld in React Native This uses the React Native CLI we installed earlier to create a directory called HelloWorld. It then downloads all the necessary dependencies needed to create our first React Native app. Downloading these assets should only take a few minutes if you're on a reasonably fast Internet connection. Once it's done installing, you should see something like the following in your terminal: Now back in your terminal, run the following: cd HelloWord Then type the following: open . [ 57 ] Saying HelloWorld in React Native This will open up a new Finder window in your HelloWorld directory, as shown in the following screenshot: [ 58 ] Saying HelloWorld in React Native Open the ios folder and then open HelloWorld.xcodeproject in Xcode, as shown in the following screenshot: Once Xcode has completed indexing your project, you should see the message HelloWorld: Ready at the top center of the window. Click the build and run play button in the top left. This will launch your HelloWorld application in the selected simulator. In the preceding screenshot, the default simulator is the iPhone 7 Plus. If you'd like to change it to a different device, select a different simulator from the dropdown. Then click build and run. You may be prompted with a message asking if you wish to Enable Developer Mode on this Mac. Click on Enable and the app will continue building. [ 59 ] Saying HelloWorld in React Native It's possible that the simulator device may look humongous on your screen, particularly if you picked one of the recent iPhones. To adjust this to something more reasonable, make sure the iOS Simulator is in the foreground. From the menu, select Window | Scale | 33%. Feel free to pick a different scale option that best suits your computer screen. Refer to the following screenshot: Assuming everything ran successfully, you should see the default React Native app, as shown in the following screenshot: [ 60 ] Saying HelloWorld in React Native Going forward, you actually don't even need to open Xcode to run React Native apps. Instead, run the following command from the root directory of your project: react-native run-ios This will launch the app directly in iOS simulator without needing to open Xcode. React Native Packager You may have noticed a separate terminal window spawn when running your HelloWorld app. This is the React Native Packager. It's a program similar to Browserify and Webpack, which are responsible for resolving dependencies, transpiling, and bundling the JavaScript, JSX, and other assets to be run on the device or simulator. [ 61 ] Saying HelloWorld in React Native Understanding our HelloWorld app This is great. We've got the app running in our simulator. Sure, it required a little bit of work to install the necessary tools, but the good news is that the only thing we'll need to do from this point forward is run the react-native init AppName command whenever we wish to create a new app. All our tools are installed and we're ready to start developing. But before we get into the meat and potatoes of React Native, let's quickly take a look at what exactly the React Native CLI provided us. Open up package.json in your text editor of choice. I'm using Atom (https://atom.io/) as shown in the following screenshot: I want to call your attention to dependencies section. Here, you should only see two items listed: react and react-native. At the time of writing, React Native is at stable version 0.35.0. Given the pace of updates to React Native, yours is likely newer. That's fine. Just keep your version in mind when seeking out help with React Native questions. The last file I want to call your attention to is index.ios.j from the following screenshot: [ 62 ] Saying HelloWorld in React Native There are four major parts to this file. Let's walk through them one by one. Importing dependencies using ECMAScript 2015 It's worth calling this out since we'll be doing this a lot. At the top of this file, you'll see two ES2015 import statement. The syntax follows the pattern import something from 'somewhere';. Using the first import as an example, we are telling the React Native Packager that we require the React object from the React package found in the node_modules directory. When our application runs, the React Native Packager will resolve this dependency automatically, making the React object available in this file. You'll need to do this in every file you create that creates a React component. [ 63 ]