React Native Fundamentals 

 

WELCOME FRIENDS!

Welcome

Gant

Laborde

  • Chief Technology Strategist

@GantLaborde

Connect

community.infinite.red

Morning

7:30 - 8:00am

8:00 - 8:30am

8:45 - 9:45am

9:45 - 10:45am

10:45 - 11:00am

Welcome

React Philosophy - ES6 - JSX

Hello World Basics - props & state - animation

Play with components

8:30 - 8:45am

BREAK

Styles intro -💪Flex Yo Self exercises

🍽  LUNCH  🍽

11:00am-12:15pm 

Afternoon

12:15 - 12:30pm

1:15 - 1:45pm

Panel

2:15 - 2:30pm

Packing List - Step 2

1:45 - 2:15pm

BREAK

2:30 - 3:00pm

Packing List - Step 3

3:00 -3:30pm

Packing List - Step 4

3:30 - 4:00pm

State Management

4:00 - 4:30pm

Wrap up - Questions - Show-and-Tell

Navigation

12:30 - 1:15pm

Packing List App intro & Step 1

Let Us Meet You

  1. What is your name?

  2. Where are you now?

  3. Programming background?

  4. What do you enjoy?

Frank

von Hoven

  • Software Engineer

  • Editor-in-Chief:
    React Native Newsletter

newsletter.com

React Native Philosophy

The React Story

What is React?

  • UI as a function of state
  • React virtual DOM, React Fiber
  • By Facebook

What is React Native?

 

  • Based on ReactJS
  • Multiple Platforms
  • "Learn once, write anywhere"

Software Goals

  • Reusable
  • Predictable
  • Testable
  • Scalable

Who Uses React Native?

Declarative

  • Flexible
  • Predictable
  • Easier to debug

Declarative Code

$("#btn").click(function() {
  $(this).toggleClass("highlight")
  $(this).text() === 'Add Highlight'
    ? $(this).text('Remove Highlight')
    : $(this).text('Add Highlight')
})
<Btn
  onToggleHighlight={this.handleToggleHighlight}
  highlight={this.state.highlight}>
    {this.state.buttonText}
</Btn>

Composability

  • Small reusable components
  • Combine components into screens
  • Screen into Apps

What is ES6 + JSX?

ES6

ES6

New variable types

let
const
var

X

99% of the time

ES6

Arrow functions:      ( ) => { }

ES5

ES6

binds function to

var sayName = 
function() { }
const sayCity = 
() => { }
() => { }
this
this.sayName.bind(this)
this.sayCity()

ES6

const getName = (name) => {
  return name
}

Functions - explicit vs implicit

var getName = function(name) {
  return name
}

ES5

ES6

const getName = (name) => name

EXPLICIT

IMPLICIT - only with

const getName = (name) => 
  name
return

Implicit === No { } required

ES6

ES6

const sayName = (name) => console.log(name)

Arrow Function Parameters

const sayName = name => console.log(name)
const addTwo = (a, b) => console.log(a + b)

1 Parameter

( )  are optional

2+ Parameters

( )  are required

ES6

Spread operator 

console.log(person)










 

Spread an object

...
const employment = {
  company: 'Infinite Red',
  job: 'Software Engineer'
}
const basicInfo = {
  firstName: 'Frank',
  lastName: 'von Hoven'
}
const person = {
  ...basicInfo,
  ...employment,
  food: 'Tacos',
  movies: 'Comedy'
}
console.log(person)

{
  firstName: 'Frank',
  lastName: 'von Hoven',
  company: 'Infinite Red',
  job: 'Software Engineer',
  food: 'Tacos',
  movies: 'Comedy'
}
 
const person = {
  ...basicInfo,
  ...employment,
  

}
const person = {
  ...basicInfo,



}
const person = {
  ...basicInfo,
  ...employment,
  food: 'Tacos',

}

ES6

Object { destructuring }

const { name, hair } = person

console.log(name, hair)

ES6

const person = { name: 'James', hair: 'Brown', height: "6'1" }
// "James", "Brown"

JSX

JSX

  • JSX adds XML-like syntax to JavaScript.
  • Can use React Native without JSX.

JSX

This:

Compiles to:

<Text color="blue">Click Me</Text>
React.createElement(Text, {color: 'blue'}, 'Click Me')

 JSX    vs.    HTML

<View>
  <Text>Hello World</Text>
</View>
<button onClick="myFunction()">
<div>
  <p>Hello World</p>
</div>
<View>

</View>
<div>

</div>
<input type="text">
<TextInput />
<TouchableOpacity onPress={myFunction()} />

Embedding Expressions into JSX

const person = { name: ‘Chris’, age: 22 }
<View>
  <Text>Hello { person.name }</Text>
</View>
// "Hello Chris"

JSX Children

<View>
  <Text>Hello!</Text>
  <Text>Good to see you here.</Text>
</View>

JSX

  • HTML/XML-like structure in the same file as our JS code

 

  • JSX is transformed into actual JS code (via Babel)

 

  • tl;dr  →  JSX === Syntactic sugar

15 Minute Break?

☕️ Break ☕️

Please return at 9:15am

Next Up: Hello World 🌎

Hello World 🌎

Hello World

  • React Native Core Components
  • Get app running
  • Examine structure
  • Create functional component
  • Pass props

Preview

React Native Core Components

  • View
  • ScrollView
  • Text
  • TextInput
  • Image
  • TouchableOpacity

React Native vs HTML

HTML React Native
<div> <View>
<p> <Text>
<input /> <TextInput />
<button> <TouchableOpacity />

Basic React Native Components

import React from 'react'
import { View, Text } from 'react-native'

class MyComponent extends React.Component {
 render() {
    return (
      <View>
        <Text>Hello World</Text>
      </View>
    )
  }
}

// example usage

<MyComponent />

React

class

code
$ react-native init HelloWorld
✨  Done in 4.01s.
To run your app on iOS:
   cd /Users/aj/Projects/HelloWorld
   react-native run-ios
   - or -
   Open ios/HelloWorld.xcodeproj in Xcode
   Hit the Run button
To run your app on Android:
   cd /Users/aj/Projects/HelloWorld
   Have an Android emulator running (quickest way to get started), or a device connected
   react-native run-android




$ cd HelloWorld

$ react-native run-ios
App.js

Hello World

  • Get app running

 

  • Examine structure

 

  • Create functional component

 

  • Pass props

Re-cap

Intro to Lifecycles and Animation

Intro to Lifecycles and Animation

MOTIVATION

Lifecycle Basics

 

Let's CODE!

ANIMATION TIME!!!

Intro to Lifecycles and Animation

  • onLayout

 

  • Basics of Animated

 

  • Fade/Pulse/Spin

 

  • useNativeDriver!

Re-cap

Styling + Flexbox

Styling

Styles can be created one of three ways:

  • inline
  • object  
  • StyleSheet

Styling

inline styles


export App = () => {
  return (
    <View 
      style={{ 
        width: 300, 
        hight: 150, 
        backgroundColor: "green"
      }}
    >
      <Text style={{ color: "red" }}>Hello</Text>
    </View>
  )
}

Styling

style object

const styles = {
  text: {
    color: "red"
  }
}

export App = () => {
  return <Text style={styles.text}>Hello World</Text>
}

Styling

StyleSheet
// ... imports ⬆︎

export class App extends Component {
  render () {
    return (
      <View style={styles.container}>
        <Text style={styles.text}>Hello World</Text>
      </View>
    )
  }
}

const styles = StyleSheet.create({
  container: {
    width: 300,
    height: 130
  },
  text: {
    color: "red"
  }
})

Styling

Array of styles

// ... imports ⬆︎

export class App extends Component {
  render () {
    return <Text style={[ styles.text, styles.bigText ]}>Hello</Text>
  }
}

const styles = StyleSheet.create({
  text: {
    color: 'red'
  },
  bigText: {
    fontSize: 30
  }
})

Styling

Combining inline styles with StyleSheet

// ... imports ⬆︎

export class App extends Component {
  render () {
    return (
      <Text style={[ styles.text, styles.bigText ]}>
        Hello
      </Text>
    )
  }
}

const styles = StyleSheet.create({
  text: {
    color: 'red'
  },
  bigText: {
    fontSize: 30
  }
})
// ... imports ⬆︎

export class App extends Component {
  render () {
    return (
      <Text style={[ styles.text, styles.bigText, {} ]}>
        Hello
      </Text>
    )
  }
}

const styles = StyleSheet.create({
  text: {
    color: 'red'
  },
  bigText: {
    fontSize: 30
  }
})
// ... imports ⬆︎

export class App extends Component {
  render () {
    return (
      <Text style={[ styles.text, styles.bigText, { margin: 5 } ]}>
        Hello
      </Text>
    )
  }
}

const styles = StyleSheet.create({
  text: {
    color: 'red'
  },
  bigText: {
    fontSize: 30
  }
})

Styling

Dynamic styling

// ... imports ⬆︎

export class App extends Component {
  state = { warning: true }

  render() {
    const fontColor = this.state.warning ? 'red' : 'black'
    return (
      <View>
        <Text style={{ color: fontColor }}>Hello World</Text>
      </View>
    )
  }
}

Styling

  • Styles usually match CSS
  • Prop names are camelCased
backgroundColor
background-color

vs

Styling

  • width / height - number
  • top / left / bottom / right  - number
  • padding - number
  • margin - number
  • borderWidth - number
  • borderColor - color

Non-flex styles

<View/>

FlexBox

Flexbox is designed to provide a consistent layout on different screen sizes.

You will normally use a combination of:

  • flexDirection
  • alignItems
  • justifyContent

to achieve the right layout.

coding
exercise

training.infinite.red

Styling

  • Inline
  • Object
  • StyleSheet
  • FlexBox

Re-cap

Play with Components

🍽 Lunch 🍽

Please return at 12:15pm

Next Up: Packing List App

Panel

Packing List App

Packing List App

https://github.com/infinitered/packing-list

Lesson 1

  • Able to write to and read from local state
  • Introduce TextInput component

Preview

  • Introduce local state

Basic React Native Concepts - state

import React from 'react'
import { Text } from 'react-native'

class App extends React.Component {
  state = { name: 'Chris' }

// lifecycle methods

  render() {
    return (
     <Text>{this.state.name}</Text>
    )
  }
}

class

<App />
  • Contains local state  
  • Lifecycle methods
  • State is data
  • Private
  • Fully controlled by component

Basic React Native Concepts

import React from 'react'
import { Text } from 'react-native'

class App extends React.Component {
  state = { name: 'Chris' }

  render() {
    return(
      <Text>{this.state.name}</Text>
    )
  }
}

Creating state

State using property initializers to declare state

Basic React Native Concepts

import React from 'react'
import { Text } from 'react-native'

class App extends React.Component {
  constructor() {
    super()
    this.state = {
      name: 'Chris',
    }
  }

  render() {
    return(
      <Text>{this.state.name}</Text>
    )
  }
}

Creating state

Using constructor to declare state

Basic React Native Concepts

import React from 'react'
import { View, Text } from 'react-native'

class App extends React.Component {
  state = { name: 'Chris' }

  updateName = () => {
    this.setState({ name: 'Amanda' })
  }

  render() {
    return(
      <View>
        <Text onPress={this.updateName}>
          {this.state.name}
        </Text>
      </View>
    )
  }
}

Updating state with

  • Component needs to be re-rendered with the updated state
setState
  •  Enqueues changes to the component state

Basic React Native Concepts

class App extends React.Component {  
  state = { value: 0 }

  increment = () => {
    this.setState((state, props) => ({value: state.value + 1}))
  }

  render() {
    return <Text onPress={this.increment}>{this.state.value}</Text>
  }
}
  • Receives an optional callback
setState
  • Update state based on prev state
class App extends React.Component {  
  state = { value: 0 }

  increment = () => {
    this.setState((state, props) => ({value: state.value + 1}))
  }

  render() {
    return <Text onPress={this.increment}>{this.state.value}</Text>
  }
}
code

Lesson 1

Re-cap

  • Able to write to and read from local state
  • Introduce TextInput component
  • Introduce local state

Lesson 2

  • Introduce "items" array into local state

Preview

  • Able to push inputted item into the items array
  • Introduce TouchableOpacity
code

map()

  • Creates a new array
  • With the results of calling a provided function
  • On every element in the calling array.

map()

[1, 2, 3]

Array     →

[1, 2, 3].map()

.map()   →

[1, 2, 3].map((item) => item)

.map()   →

[1, 2, 3].map((item, index) => item + index)

.map()   →

[1, 2, 3]

returns →

[1, 3, 5]

returns →

map()

{ items: ["Socks", "Shoes", "Jeans"] }
items.map((item) => ?)

Shoes

Socks

Jeans

items.map((item) => <Text>{item}</Text>)

Lesson 2

Re-cap

  • Introduce "items" array into local state
  • Able to push inputted item into the items array
  • Introduce TouchableOpacity

Lesson 3

Preview

  • Create Button Component
  • Create ListInput Component
  • Clear items

Current App

 coding exercise

Lesson 3

Re-cap

  • Create Button Component
  • Create ListInput Component
  • Clear items

Lesson 4

  • Intro to FlatList
  • Add ability to "check" an item

Preview

code

FlatList

FlatList

  • Inherits from ScrollView
  • Renders an array of items

FlatList

render() {


  


    
  return (
    <View>
      <FlatList
        data={data}


      />
    </View>
  )
}

Requires 3 props:

  • data
  • renderItem
  • keyExtractor
render() {
  




  
  return (
    <View>
      <FlatList
        


      />
    </View>
  )
}
render() {
  const data = [{ name: "Chris" }, { name: "Amanda" }]

  renderItem = ({ item }) => {
    return <Text>{item.name}</Text>
  }
    
  return (
    <View>
      <FlatList
        data={data}
        renderItem={this.renderItem}
        keyExtractor={item => item.name}
      />
    </View>
  )
}
render() {
  const data = [{ name: "Chris" }, { name: "Amanda" }]

  


    
  return (
    <View>
      <FlatList
        data={data}


      />
    </View>
  )
}
render() {
  const data = [{ name: "Chris" }, { name: "Amanda" }]




    
  return (
    <View>
      <FlatList
        data={data}
        renderItem={this.renderItem}

      />
    </View>
  )
}
render() {
  const data = [{ name: "Chris" }, { name: "Amanda" }]

  renderItem = ({ item }) => {

  }
    
  return (
    <View>
      <FlatList
        data={data}
        renderItem={this.renderItem}

      />
    </View>
  )
}
render() {
  const data = [{ name: "Chris" }, { name: "Amanda" }]

  renderItem = ({ item }) => {
    return <Text>{item.name}</Text>
  }
    
  return (
    <View>
      <FlatList
        data={data}
        renderItem={this.renderItem}

      />
    </View>
  )
}
able to check an item

coding

exercise

Hints

  • items: string[]
    • ["Socks", "Shoes"]
  • items: object[]
    • [{ name: "Socks, ?: ??? }, { name: "Shoes", ?: ??? }]

Lesson 4

  • Intro to FlatList
  • Add ability to "check" an item

Re-cap

☕️ Break ☕️

Please return at 2:30pm

Lesson 5

Preview

  • State management
  • Unstated

React State Museum

github.com/GantMan/ReactStateMuseum

https://unstated.io

Important Componets

  • <Container />
  • <Provider />
  • <Subscribe />

<Container />

  • Place to store state
  • Contains logic to update state
  • Looks similar to componet state
// Example

class CounterContainer extends Container {
  state = { count: 0 };

  increment = () => {
    this.setState({ count: this.state.count + 1 });
  };

  decrement = () => {
    this.setState({ count: this.state.count - 1 });
  };
}
code

$ yarn add unstated

-- or --

$ npm install --save unstated

Add <Container />

  • Create a Container
  • Move state
  • Move state manipulating functions
import { Container } from "unstated"

export class RootStore extends Container {
  state = { inputValue: null, items: [] }

  handleInput = value => {
    this.setState({
      ...this.state,
      inputValue: value
    })
  }

  handleAddPress = () => {
    const { inputValue, items } = this.state
    if (inputValue) {
      const newItems = [...items, { name: inputValue, checked: false }]
      this.setState({ items: newItems, inputValue: "" })
    }
  }

  handleClearPress = () => this.setState({ items: [], inputValue: "" })

  checkItem = selectedItem => {
    const selectedName = selectedItem.name
    const newItems = this.state.items.map(item => {
      const { name, checked } = item
      return name === selectedName ? { name: name, checked: !checked } : item
    })
    this.setState({ items: newItems })
  }
}

<Subscribe />

  • Allows component rerender
  • Call methods from <Container />

<Provider />

  • Wraps the app's root component
  • Used once to wrap multiple screens
class CounterContainer extends Container<CounterState> {
  state = {
    count: 0
  };

  increment() {
    this.setState({ count: this.state.count + 1 });
  }

  decrement() {
    this.setState({ count: this.state.count - 1 });
  }
}

function Counter() {
  return (
    <Provider>
      <Subscribe to={[CounterContainer]}>
        {counter => (
          <div>
            <button onClick={() => counter.decrement()}>-</button>
            <span>{counter.state.count}</span>
            <button onClick={() => counter.increment()}>+</button>
          </div>
        )}
      </Subscribe>
    </Provider>
  );
}
import { Container, Subscribe, Provider } from "unstated"

  // Replace this.state w/ container.state
  // Replace items and inputValue with container.state.items or container.state.inputValue
  render() {
    return (
      <Provider>
        <Subscribe to={[RootContainer]}>
          {container => (
            <View style={styles.container}>
              <View style={styles.topContainer}>
                <ListInput
                  value={container.state.inputValue}
                  onChangeText={value => container.setState({ inputValue: value })}
                  onAddItem={container.handleAddPress}
                  onClearItems={container.handleClearPress}
                />
              </View>
              <View style={styles.bottomContainer}>
                <FlatList
                  data={container.state.items}
                  extraData={{ data: container.state.items && container.state.items.length }}
                  keyExtractor={item => item}
                  renderItem={({ item, index }) => this.listItems(item, index, container)}
                  contentContainerStyle={styles.listContainer}
                  style={styles.list}
                  numColumns={3}
                />
              </View>
            </View>
          )}
        </Subscribe>
      </Provider>
    )
  }

Lesson 5

Preview

  • State management
  • Unstated

Lesson 6

  • React Navigation

Preview

code

Lesson 6

  • React Navigation

Re-cap

Playground

Packing List App

Questions?

Wrapping Up

Reactotron

Solidarity

Ignite

Fin

Thank you all!

December 11 Online: Intro to React Native

By Infinite Red

December 11 Online: Intro to React Native

React Native Workshop Connect.Tech 2018.

  • 2,000