Categories
Current Events Tampa Bay Uncategorized

Xamarin Dev Days in Tampa Bay happens tomorrow – Saturday, November 19th!

xamarin

Xamarin, the development tool that lets you use C# to write code for Android, iOS, Mac OS, Windows, and the cloud, is hosting a number of Xamarin Dev Days events all over the world, and the Tampa Bay event takes place tomorrow, Saturday November 19th at 9:00 a.m..

The Tampa Bay event is hosted by the Tampa Bay Mobile App Developers meetup at the Tampa Microsoft office in the Westshore area. Xamarin Dev Days events are hands-on sessions, with the mornings dedicated to learning about Xamarin and the afternoon set for diving into coding.

Are you in the Tampa Bay area and want to join in? Register at the Tampa Bay Xamarin Dev Days site!

Agenda

Here’s what will take place, and when:

 Time  What’s happening
9:00 a.m. – 9:30 a.m. Registration and breakfast, which SMARTRAC and SMART COSMOS (the company and platform I represent) are providing!
9:30 a.m. – 10:10 a.m. “Intro to Xamarin” presentation
10:20 a.m. – 11:00 a.m. “Cross-platform Xamarin” presentation
11:10 a.m. – 11:50 a.m. “Cloud Xamarin” presentation
12:00 p.m. – 1:00 p.m. Lunch (they’ll provide it; it will most likely be pizza)
1:00 p.m. – 4:00 p.m. Hands-on lab

Your hosts will be:

What you should bring

mac-and-windows-laptops

You’ll need a computer running either Mac OS or Windows on which to do Xamarin development. You should set up Xamarin prior to showing up, because setup takes time and bandwidth, which will likely be in short supply at the event. Follow these steps:

Breakfast is on SMART COSMOS!

smart-cosmos-horizontal

If you’re going to show up to spent 8 hours of your Saturday in an office — especially in the Tampa Bay Area, where November means sunny skies and 80°F/27°C temperatures — the least we can do is feed you. SMART COSMOS will help by providing breakfast!

SMART COSMOS is the IoT platform made by SMARTRAC, the company where I hold the title of developer evangelist. It orchestrates data for the internet of things, and combined with SMARTRAC’s RFID technology, it’s being used to help clothing manufacturers and retailers manage their wares, improve the way healthcare providers track patients from the moment they check into the hospital to well after they check out, and on mechanical devices to ensure that the right parts are plugged into the right places.

New to C#, or has it been a while? Download this free book.

c-sharp-programming-yellow-book

If you’re new to the C# programming language (I’ve quipped that it’s “like Java, but good”) or if it’s been a while (as is the case for me), I recommend getting your paws on Rob Miles’ C# Programming Yellow Book, a free ebook that he’s been publishing and updating for years. It’s based on the first year programming course at the University of Hull, and it’s been the free ebook I’ve been sending C# students to for years.

Categories
Current Events Florida Tampa Bay

A walk through my “Just enough React to get you into trouble” presentation at Tampa Code Camp 2016

just enough react title slide

I had the opening presentation in the “Miscellaneous and Open Source” track of Tampa Code Camp 2016, which took place on July 16th. My presentation was titled Just enough React to get you into trouble, and was designed to be an introduction to building user interfaces using React.

In 50 minutes, I introduced React to the audience mostly by live-coding a simple React application in a JSFiddle playground. For those of you who missed it (or saw it and wanted to review it), this article walks you through my presentation. Enjoy!

Playing around with React in a JSFiddle playground

I spent most of my presentation live-coding some a simple React application in JSFiddle, a “playground” that lets you quickly try out web development ideas in your browser and save them for later use. A saved “playground” is called a fiddle, and you can fork other people’s public fiddles for your own experimentation.

JSFiddle has four key areas — HTML, CSS, JavaScript, and output, as shown below:

jsfiddle diagram

Click the screenshot to see it at full size.

JSFiddle lets you enter the HTML, CSS, and JavaScript into the corresponding areas and then see the result in the output area by clicking on the Run button located near the upper left-hand corner of the page. It even lets you import a number of JavaScript and CSS libraries.

In this exercise, we’ll work using a base fiddle that imports the libraries necessary for a React application, and we’ll do all of our coding in the JavaScript area.

Let’s start with a simple React fiddle

Let’s start by navigating to the fiddle that I set up as the starting point for the presentation. I forked it from the React base fiddle, and if you set up your own JSFiddle account, you should fork it for yourself.

The fiddle features one of the simplest React applications that you can write: “Hello, world” for React. Here’s the JavaScript:

class Hello extends React.Component {

  render() {
    return <h1>Hello, world!</h1>
  }

}


ReactDOM.render(
  <Hello />,
  document.getElementById('app')
)

And here’s a screenshot showing the output:

hello world

Let’s take a closer look at what’s going on in the JavaScript code…

1. First, we create a React component named Hello.

React is all about creating user interfaces by assembling modular, composable components. For this first example, we want to create a component named Hello, which is made up of a single <h1> heading. We do this by creating a class named Hello, which subclasses React’s React.Component class:

class Hello extends React.Component {

  render() {
    return <h1>Hello, world!</h1>
  }

}

Our Hello class has a single method, render. React component classes can implement many methods, but must implement a method called render, which returns a value that shows how the component should be drawn onscreen. The value returned by render depends on the kind of React app we’re working on:

  • In a web application, the render method returns a single HTML element. This single HTML element is allowed to contain other HTML elements.
  • In a native mobile application, the render method returns a single view. This single view is represented in a dialect of XML whose elements represent native mobile UI elements. This view is allowed to contain other views.

(For now, we’ll stick to React web applications. I’ll look at React native applications in a later article.)

Here’s the value returned by the render method:

<h1>Hello, world!</h1>

You’ve probably noticed that it’s not in quotes as you might have expected. That’s because render‘s return value isn’t a string that contains HTML.

Instead, its return value is JSX, a dialect of XML whose name is short for “JavaScript XML”. It looks like HTML, and it’s meant to — it’s a shorthand for the value that the render method actually returns, which is a React element — a JavaScript object. This fiddle — and many React applications — includes a extension that preprocesses JSX into JavaScript that generates a React element.

Here’s what render really returns, once the JSX has been processed into JavaScript:

React.createElement("h1", null, "Hello, world!")

In fact, you can have render directly return a React element. Try changing the render method so that it looks like this, then click the Run button to run the app:

render() {
  return React.createElement("h1", null, "Hello, world -- the hard way!")
}

The output should look like this:

hello world the hard way

Click the screenshot to see it at full size.

Generally, React developers prefer to work with JSX. It’s preprocessed, so using it doesn’t affect your application’s efficiency, and it’s much easier to read, especially as you work on more complex React projects.

2. Then we render the Hello component onto the page.

Here’s the line that renders the Hello component onto the page:

ReactDOM.render(
  <Hello />,
  document.getElementById('app')
)

The ReactDOM.render method takes two arguments:

  1. A React element to render. In this case, the react element is the output of Hello‘s render method, which we request by using the JSX tag <Hello />.
  2. The DOM node where the React element will be rendered. In this case, we specify that it should be rendered in the node whose id is app. If you look in the HTML area of the fiddle, you’ll see it at the very end:
<div id="app">
    <!-- 
    This element's contents will be filled by our React code's output.
    -->
</div>

This is one of the two things you should take away from this tutorial: At its core, building user interfaces in React is about defining components and then rendering them onto the screen. Everything else builds on this basic principle.

Let’s continue. If you changed the render method in Hello to use JavaScript instead of JSX, change it back. The code in the JavaScript area of the page should look like this:

class Hello extends React.Component {

  render() {
    return <h1>Hello, world!</h1>
  }

}


ReactDOM.render(
  <Hello />,
  document.getElementById('app')
)

Pass information to a component with a prop

Suppose we want our application to be a little more flexible in who it says “Hello” to. Let’s change the component so that it can be passed a name parameter, and then says “Hello,” followed by that name.

Update the code in the JavaScript area so that it looks like this:

class Hello extends React.Component {

  render() {
    const name = this.props.name
    return <h1>Hello, {name}!</h1>
  }

}


ReactDOM.render(
  <Hello name="Kate" />,
  document.getElementById('app')
)

Let’s first look at the ReactDOM.render line. Note that we’ve added an attribute to the Hello element:

<Hello name="Kate" />

The use of XML attributes in React elements allows us to pass values to the corresponding components. In the Hello element, we’re using an attribute called name to pass the string “Kate” to our Hello component.

Within the Hello component’s render method, we access that value by using the component’s props (short for properties) object and assign its value to a variable…

const name = this.props.name

…and then we use that variable within the JSX returned by the render method. Note that the variable is delimited by { }:

return <h1>Hello, {name}!</h1>

When you click on the Run button in JSFiddle, here’s what you should see:

hello kate 1

Click the screenshot to see it at full size.

For components, props are read-only — they can take in props and use their values, but they can’t change them. They’re meant to be used to set up components.

Using multiple props and rendering more stuff

Let’s change our app so that it says “Hello, Kate!” followed by a greeting:

class Hello extends React.Component {

  render() {
    const name = this.props.name
    const greeting = this.props.greeting
    return <h1>Hello, {name}!</h1>
           <p>{greeting}, {name}.</p>
  }

}


ReactDOM.render(
  <Hello name="Kate" greeting="Welcome to Tampa Code Camp" />,
  document.getElementById('app')
)

If you click the Run button right now, the output area will contain…nothing:

hello kate 1

Click the screenshot to see it at full size.

In many cases, when the output area is blank when you don’t expect it to be, it means that there’s an error in your code. In this case, it’s the fact that the render method is supposed to return only one HTML element, but our returns two:

<h1>Hello, {name}!</h1>
<p>{greeting}, {name}.</p>

While render is supposed to return a single HTML element, that single element is allowed to contain other elements. The fix is to take our two elements and enclose them in a <div> like so:

<div>
  <h1>Hello, {name}!</h1>
  <p>{greeting}, {name}.</p>
</div>

Here’s what your code should look like now…

class Hello extends React.Component {

  render() {
    const name = this.props.name
    const greeting = this.props.greeting
    return (<div>
      <h1>Hello, {name}!</h1>
      <p>{greeting}, {name}.</p>
    </div>)
  }

}


ReactDOM.render(
  <Hello name="Kate" greeting="Welcome to Tampa Code Camp" />,
  document.getElementById('app')
)

…and here’s what things should look like when you hit the Run button:

hello kate 2

Click the screenshot to see it at full size.

Introducing default props

In addition to passing values to React components using props, we can also create default values through the use of default props. Change the code in the JavaScript area of the fiddle so that it looks like this:

class Hello extends React.Component {
  
  render() {
    const name = this.props.name
    const greeting = this.props.greeting
    return (<div>
      <h1>Hello, {name}!</h1>
      <p>{greeting}, {name}.</p>
    </div>)
  }

}

Hello.defaultProps = {
  name: "stranger",
  greeting: "Please press the button"
}


ReactDOM.render(
  <Hello />,
  document.getElementById('app')
)

Note that the <Hello> tag in the ReactDOM.render call doesn’t contain any attributes. This means that we’re not passing any props to it, which in turn means that our Hello component will use the default props defined in this line of code:

Hello.defaultProps = {
  name: "stranger",
  greeting: "Please press the button"
}

If you run the application, you’ll see that the Hello component uses the default props, addressing the user as “stranger” and using the greeting “Please press the button”:

hello stranger

Click the screenshot to see it at full size.

However, if we change the <Hello> tag in the ReactDOM.render call so that it has name and greeting attributes, as shown in the code below…

class Hello extends React.Component {
  
  render() {
    const name = this.props.name
    const greeting = this.props.greeting
    return (<div>
      <h1>Hello, {name}!</h1>
      <p>{greeting}, {name}.</p>
    </div>)
  }

}

Hello.defaultProps = {
  name: "stranger",
  greeting: "Please tell me your name"
}


ReactDOM.render(
  <Hello name="Kate" greeting="Welcome to Tampa Code Camp" />,
  document.getElementById('app')
)

…when you run the application, the Hello component uses the given props, addressing the user as “Kate” and using the greeting “Welcome to Tampa Code Camp”:

hello kate 3-2

Click the screenshot to see it at full size.

Adding state and interactivity

As I mentioned earlier, as far as components are concerned, props are read-only. They can only be set by attributes in the tags that invoke them and in the statement that sets their default values. With only read-only data like props, components themselves would also be read-only. What we need is data that components can change in response to user input or events, and that’s what state is for.

State is represented by the state object, which every React component has. Like the props object, it’s a “dictionary” that components can use to store values. However, there are two key differences between state and props:

  1. Unlike with the props object, the state object is read-write. Components can change the values within the state object by using the setState method.
  2. Any change to a component’s state object causes its render method to be called.

That second difference is key; in fact, it’s why the library is called “React”. The name is a nod to reactive programming, which is often defined as being “oriented around data flows and the propagation of change” (in fact, Wikipedia uses his definition). A greatly simplified way to describe it as “programming code that responds to changes in data”.

And now, here’s the second of the two things you should take away from this tutorial: Making changes to React components is all about changing their state. Or, if you’re into snappy rhyming mantras or hip-hop, remember it this way: Change the state to make it update.

Modify the code in the JavaScript area so that it looks like this. Don’t worry about any of the unfamiliar stuff; I’ll walk you through it in a moment:

class Hello extends React.Component {

  constructor(props) {
    super(props)
    this.onSubmit = this.onSubmit.bind(this)
    this.state = {
      name: this.props.name,
      greeting: this.props.greeting
    }
  }
  
  render() {
    const name = this.state.name
    const greeting = this.state.greeting
    return (<div>
      <h1>Hello, {name}!</h1>
      <p>{greeting}, {name}.</p>
      
      <form onSubmit={this.onSubmit}>
        <button>Update!</button>
      </form>
    </div>)
  }
  
  onSubmit(event) {
    event.preventDefault()
    this.setState({
      name: "button-presser",
      greeting: "Thanks for pressing the button"
    })
  }

}

Hello.defaultProps = {
  name: "stranger",
  greeting: "Please press the button"
}


ReactDOM.render(
  <Hello />,
  document.getElementById('app')
)

When you press the Run button, you should be greeted with “Hello, stranger!”, an invitation to press a button, and a button, as shown below…

hello stranger 2

Click the screenshot to see it at full size.

…and when you press that button, the name you’re referred to and the message below it change:

hello stranger 3

Click the screenshot to see it at full size.

Let’s take a closer look at the code. We’ll start with the render method, which is often a good place to start analyzing React components:

render() {
  const name = this.state.name
  const greeting = this.state.greeting
  return (<div>
    <h1>Hello, {name}!</h1>
    <p>{greeting}, {name}.</p>
      
    <form onSubmit={this.onSubmit}>
      <button>Update!</button>
    </form>
  </div>)
}

The main difference between this render method and the previous one is the addition of this form code:

<form onSubmit={this.onSubmit}>
  <button>Update!</button>
</form>

The onSubmit attribute of the <form> tag is set to {this.onSubmit}, which means that when the form is submitted — which in turn that means that the user has clicked the button — the class’ onSubmit method is called. Let’s look at onSubmit now:

onSubmit(event) {
  event.preventDefault()
  this.setState({
    name: "button-presser",
    greeting: "Thanks for pressing the button"
  })
}

Two things are happening in this method:

  1. First, the event.preventDefault method is called. This stops the page from reloading, which is the default behavior when a form is submitted (it also explains the name of the method).
  2. Then, the setState method is called, which changes the properties of the state object so that:
    • name‘s value is changed to “button-presser”, and
    • greeting‘s value is changed to “Thanks for pressing the button”.

And since we’ve changed state, the render method gets called, which in turn causes it to display the new state values.

Finally, let’s take a look at the constructor:

constructor(props) {
  super(props)
  this.onSubmit = this.onSubmit.bind(this)
  this.state = {
    name: this.props.name,
    greeting: this.props.greeting
  }
}

Here’s what’s happening in this method:

  1. The props argument that constructor takes contains the properties that were passed to Hello via the <Hello> tag’s attributes. As with constructors in many other programming languages, we pass this argument to the component’s superclass with super(props).
  2. The onSubmit attribute of our form specifies that the this.onSubmit method should be called when the form is submitted. The problem is that within the JSX, the this in this.onSubmit is undefined. We solve this problem by binding the onSubmit method to this specific instance of the Hello class, so that the this in this.onSubmit points to this instance (if you’re skeptical, comment out the line this.onSubmit = this.onSubmit.bind(this) and try running the app). You’ll need to do this sort of binding for every method that you call from JSX.
  3. And finally, we update the state object, which in turn causes the render method to get called, redrawing the component with the new values.

A little more interactivity

Let’s add a text field to our application, and change the code so that we first run, it looks like this:

interactive 1

If you leave the text field blank and click the Enter button or hit the Return key, the output area should change to display this:

interactive 2

If you type the name “Zaphod” into the text field and click the Enter button or hit the Return key, the output area should change to display this:

interactive 3

Here’s the code that does this:

class Hello extends React.Component {

  constructor(props) {
    super(props)
    this.onSubmit = this.onSubmit.bind(this)
    this.state = {
      name: this.props.name,
      greeting: this.props.greeting
    }
  }
  
  render() {
    const name = this.state.name
    const greeting = this.state.greeting
    return (<div>
      <h1>Hello, {name}!</h1>
      <p>{greeting}, {name}.</p>
      
      <form onSubmit={this.onSubmit}>
        <input ref="nameTextField" type="text" placeholder="Enter your name here." />
        <button>Enter</button>
      </form>
    </div>)
  }
  
  onSubmit(event) {
    event.preventDefault()
    const nameTextField = this.refs.nameTextField
    const newName = nameTextField.value.trim()
    nameTextField.value = ""
    
    if (newName.length > 0) {
      this.setState({
        name: newName,
        greeting: "Pleased to meet you"
      })
    }
    else {
    	this.setState({
      	name: "stranger",
        greeting: "Seriously, please enter your name"
      })
    }
  }

}

Hello.defaultProps = {
  name: "stranger",
  greeting: "Please tell me your name"
}


ReactDOM.render(
  <Hello />,
  document.getElementById('app')
)

Let’s take a closer look at the code. We’ll start with the render method:

render() {
  const name = this.state.name
  const greeting = this.state.greeting
  return (<div>
    <h1>Hello, {name}!</h1>
    <p>{greeting}, {name}.</p>
      
    <form onSubmit={this.onSubmit}>
      <input ref="nameTextField" type="text" placeholder="Enter your name here." />
      <button>Enter</button>
    </form>
  </div>)
}

The only difference between this version of the render method and the previous one is the addition of a single line containing an <input> tag:

<input ref="nameTextField" type="text" placeholder="Enter your name here." />

It looks like a standard <input> tag, but it has a strange attribute called ref. That’s short for reference, and it a way for other code to access this tag. Think of it as being similar to HTML’s id attribute, but for React. We access refs that we define in JSX via the refs object, which is similar in structure to the props and state objects.

The onSubmit method isn’t all too different, either:

onSubmit(event) {
  event.preventDefault()
  const nameTextField = this.refs.nameTextField
  const newName = nameTextField.value.trim()
  nameTextField.value = ""
  
  if (newName.length > 0) {
    this.setState({
      name: newName,
      greeting: "Pleased to meet you"
    })
  }
  else {
    this.setState({
      name: "stranger",
      greeting: "Seriously, please enter your name"
    })
  }
}

Some notes:

  1. We’ve created a new constant, nameTextField, which holds a reference to the element whose ref is nameTextField — the text field into which the user enters his/her name.
  2. We fill another constant, newName, with the contents of nameTextField, trimmed of leading and trailing white space.
  3. We clear the text field.
  4. If the user entered something into the text field, newName‘s length will be greater than 0, and we change the state so that the newly-entered name becomes the value for the state key name and “Pleased to meet you” becomes the value for the state key greeting.
  5. If the user entered nothing into the text field (or entered nothing but white space into it), newName‘s length will be 0, and we change the state so that the value for the state key name is “stranger”, and “Seriously, please enter your name” becomes the value for the state key greeting.

Componentizing

So far, we’ve created a single component, Hello, for our application. For a simple tutorial app, this approach — sometimes called the Big Ball of Mud — is a workable one. You wouldn’t want to use it for an app of any appreciable size, as it becomes hard to code, manage, and maintain. Ideally, a React UI is supposed to be made up of small components that collectively form a larger whole.

Let’s break up our simple app into components as shown in the diagram below:

components

Note that in the diagram, the UI is broken into three components:

  1. Greeting: This displays the name and greeting.
  2. NameForm: This displays the form, which contains our text field and button.
  3. Hello: This contains both the Greeting and NameForm components.

Greeting and NameForm present UI components, and are thus called presentation components. Their job is to present user interface elements that are visible to the user.

Hello is used as a container for other components, and is hence called a container component. Its has a couple of jobs:

  • To act as a container for other components, Greeting and NameForm in this case, and
  • To contain the user interface state and logic for itself and its child components (again, Greeting and NameForm).

Let’s start by coding the Greeting component, one of the presentation components:

class Greeting extends React.Component {

  render() {
    const name = this.props.name
    const greeting = this.props.greeting
    return (<div>
      <h1>Hello, {name}!</h1>
      <p>{greeting}, {name}.</p>
    </div>)
  }

}

It’s a pretty simple component: it expects two props — name and greeting — and displays them appropriately. Nothing new here.

Note that Greeter doesn’t make use of any state; it simply accepts two props and displays them. It doesn’t do any “thinking”. You’ll see this approach in a lot of React code, where presentation components don’t have much logic them and a primarily concerned with the display and input of information.

Think of this as the mantra for presentation components:

youre not paid to think

Let’s now code the NameForm component, the other presentation component:

class NameForm extends React.Component {
  constructor() {
    super()
    this.onSubmit = this.onSubmit.bind(this)
  }

  render() {
    return (<div>
      <form onSubmit={this.onSubmit}>
        <input ref="nameTextField" type="text" placeholder="Enter your name here." />
        <button>Enter</button>
      </form>
    </div>)
  }
  
  onSubmit(event) {
    event.preventDefault()
    const nameTextField = this.refs.nameTextField
    const newName = nameTextField.value.trim()
    nameTextField.value = ""
    
    if (newName.length > 0) {
      this.props.onNewName(newName)
    }
    else {
      this.props.onNoName()
    }
  }

}

The only really different part is the if statement in the onSubmit method:

if (newName.length > 0) {
  this.props.onNewName(newName)
}
else {
  this.props.onNoName()
}

In the previous version of our onSubmit method, both branches made changes to the state object. This time it’s different:

  • If the user entered something into the text field (i.e. newName‘s length is greater than 0), it calls a method called onNewName, which is stored in the props object. It passes newName as an argument to onNewName.
  • If the user entered nothing or just white space into the text field (i.e. newName‘s length is 0), it calls a method called onNoName, which is also stored in the props object.

Note that both onNewName and onNoName are stored in NameForm‘s props. This means that NameForm has very little built-in logic for dealing with user input, but instead receives this logic from an outside source through its props. As with Greeter, NameForm doesn’t make use of state. Once again, this is an approach you’ll see in a lot of React code — presentation components doing as little “thinking” as possible.

Both Greeter and NameForm receive their props from their container component, Hello. Let’s look at its code:

class Hello extends React.Component {

  constructor(props) {
    super(props)
    this.state = {
      name: this.props.name,
      greeting: this.props.greeting
    }
    this.handleNewName = this.handleNewName.bind(this)
    this.handleNoName = this.handleNoName.bind(this)
  }
  
  render() {
    return (<div>
      <Greeting name={this.state.name} greeting={this.state.greeting} />
      <NameForm onNewName={this.handleNewName} onNoName={this.handleNoName} />
    </div>)
  }

  handleNewName(newName) {
    this.setState({
      name: newName,
      greeting: "Pleased to meet you"
    })
  }
  
  handleNoName() {
    this.setState({
      name: "stranger",
      greeting: "Seriously, please enter your name"
    })
  }

}

Hello.defaultProps = {
  name: "stranger",
  greeting: "Please tell me your name"
}

Let’s look at its render method first:

render() {
  return (<div>
    <Greeting name={this.state.name} greeting={this.state.greeting} />
    <NameForm onNewName={this.handleNewName} onNoName={this.handleNoName} />
  </div>)
}

Note that the <div> it returns has two component tags and nothing else:

  1. Greeting: We pass the current name and greeting to it via the attributes, which it receives as props.
  2. NameForm: We pass it two methods — handleNewName and handleNoName — via attributes, which it receives as props.

Let’s take a look at handleNewName and handleNoName:

handleNewName(newName) {
  this.setState({
    name: newName,
    greeting: "Pleased to meet you"
  })
}

handleNoName() {
  this.setState({
    name: "stranger",
    greeting: "Seriously, please enter your name"
  })
}

Note that:

  1. handleNewName does just one thing: change the state so that the value for name is set to the contents of newName, and the value for greeting is set to “Please to meet you”. Changing the state of the Hello component causes its render method to be called, which in turn causes the Greeting and NameForm components to be redrawn, which causes them to call their render methods as well.
  2. handleNoName also does just one thing: change the state so that the value for name is set to “stranger”, and the value for greeting is set to “Seriously, please enter your name”. Changing the state of the Hello component causes its render method to be called, which in turn causes the Greeting and NameForm components to be redrawn, which causes them to call their render methods as well.
  3. handleNewName and handleNoName are passed as props to NameForm, which uses their logic to perform tasks based on what the user enters or doesn’t enter into NameForm‘s text field. It appears that while Hello doesn’t present any user interface of its own, it does a lot of the “thinking”.
  4. Note that Hello‘s methods, handleNewName and handleNoName, are passed to NameForm as props with the names onNewName and onNoName. This is a naming convention used in React:
    • When defining a function that will be passed to a child component, prefix the function name with handle. A name beginning with handle implies that we’re defining a response to a specific event.
    • When passing a function to a child component as a prop, prefix the prop name with on. A name beginning with on implies that we’re calling on a defined response to a specific event.

Let’s take a closer look at the constructor:

constructor(props) {
  super(props)
  this.state = {
    name: this.props.name,
    greeting: this.props.greeting
  }
  this.handleNewName = this.handleNewName.bind(this)
  this.handleNoName = this.handleNoName.bind(this)
}

The constructor sets up the app’s initial state based on the default props. It also binds the handleNewName and handleNoName methods to the current instance, so that they can be called when they’re passed as props to the NameForm component.

Speaking of default props, here’s the function that sets Hello‘s default props:

Hello.defaultProps = {
  name: "stranger",
  greeting: "Please tell me your name"
}

That’s the complete definition for the Hello component.

We’ve just reviewed all the code in the app piece by piece. Here’s the complete code:

class Greeting extends React.Component {

  render() {
    const name = this.props.name
    const greeting = this.props.greeting
    return (<div>
      <h1>Hello, {name}!</h1>
      <p>{greeting}, {name}.</p>
    </div>)
  }

}


class NameForm extends React.Component {
  constructor() {
    super()
    this.onSubmit = this.onSubmit.bind(this)
  }

  render() {
    return (<div>
      <form onSubmit={this.onSubmit}>
        <input ref="nameTextField" type="text" placeholder="Enter your name here." />
        <button>Enter</button>
      </form>
    </div>)
  }
  
  onSubmit(event) {
    event.preventDefault()
    const nameTextField = this.refs.nameTextField
    const newName = nameTextField.value.trim()
    nameTextField.value = ""
    
    if (newName.length > 0) {
      this.props.onNewName(newName)
    }
    else {
    	this.props.onNoName()
    }
  }

}


class Hello extends React.Component {

  constructor(props) {
    super(props)
    this.state = {
    	name: this.props.name,
      greeting: this.props.greeting
    }
    this.handleNewName = this.handleNewName.bind(this)
    this.handleNoName = this.handleNoName.bind(this)
  }
  
  render() {
    return (<div>
      <Greeting name={this.state.name} greeting={this.state.greeting} />
      <NameForm onNewName={this.handleNewName} onNoName={this.handleNoName} />
    </div>)
  }

  handleNewName(newName) {
    this.setState({
      name: newName,
      greeting: "Pleased to meet you"
    })
  }
  
  handleNoName() {
    this.setState({
      name: "stranger",
      greeting: "Seriously, please enter your name"
    })
  }

}

Hello.defaultProps = {
  name: "stranger",
  greeting: "Please tell me your name"
}


ReactDOM.render(
  <Hello />,
  document.getElementById('app')
)

Looking at the entire application, note that the Hello component, as the container component, doesn’t display any UI of its own; it simply displays its child components. However, it also contains all the “smarts”, maintaining the state of the application and passing its child presentation components any information they need:

  • Hello passes data to the Greeting component, namely the name and greeting it should use, and
  • Hello passes instructions to the NameForm component, namely what it should do if the user entered a name (handleNewName) and what it should do if the user left the name text field blank or filled with white space (handleNoName).

In the meantime, the Greeting and NameForm components present their parts of the UI and do what they’re told as specified by the props passed to them.

You’ve probably noticed that this arrangement ensures that the flow of information in this application is one-way, starting at the top and going down…

flow of information

…with the top-level reactDOM.render method calling on the Hello component to render itself, and the Hello component providing data and instructions to the Greeting and NameForm components and calling on them to render themselves. The information doesn’t flow the other way — The Greeting and NameForm components don’t send any information to the Hello component, and the Hello component doesn’t send any information to the code>reactDOM.render statement. This one-way flow of information simplifies development and is a basic principle of React.

Next steps

next steps

You’ve probably suspected that this is just the beginning. You’re right — there’s only so much you can cover in a 50-minute presentation, and React is already a large topic, and it’s continuing to grow. Here are some resources you might find handy:

  • The official React site: Sooner or later, you’ll have to go to the mothership, and that’s what this site is — the official source of the React code, and home of the official documentation.
  • The React base fiddle: If you want to play around with React code in a fiddle (an online playground), this is a good place to start.
  • build with react: This site describes itself as “a periodical of tutorials and advanced articles for the react.js library”.
  • LearnCode.academy’s React.js tutorial:  If you learn better from video tutorials, you should find this one helpful. This is the first in a series of tutorials.
  • Questions tagged “reactjs” in Stack Overflow: If you have a programming problem, chances are that many other people have (or have had) the same problem, and it may have already been solved. That’s what good ol’ Stack Overflow is for!
  • The ReactJS Tampa Bay Meetup: If you’re local to the Tampa area, there’s a React meetup that meets twice monthly! They alternate between “lecture” and “lab” formats every two weeks, the group is friendly, and you’ll learn a lot.
Categories
Current Events Tampa Bay Uncategorized

While I was away (or: Getting married and getting my 2011 MacBook fixed)

Things have been quiet lately here on Global Nerdy. I have a couple of good excuses. Here’s the first one:

Photo: Anitra Pavka and Joey deVilla at their wedding.

Anitra and me, shortly after getting married. Click the photo to see more.

On Saturday, March 7th, the lovely lady for whom I moved from Toronto to Tampa and I got married. We had our ceremony on St. Pete Beach followed by a brunch reception on the penthouse ballroom of the Grand Plaza Hotel, a stunning room that looks like it would’ve made a great hideout for Sean Connery-era Bond villain. As you might expect, this big life event took priority over a great many things, including blogging.

Photo: Joey deVilla's MacBook Pro (early 2011 15-inch model), as seen from his vantage point in an Air Canada window seat. In the background, a movie plays on the seat-back in-flight entertainment system.

“El Guapo”, my trusty early 2011 15″ MacBook Pro, circa 2012.

My other excuse is technological: “El Guapo”, my trusty early 2011 15″ MacBook Pro, was beginning to show some glitchy behavior just before my wedding. (Maybe it had some reservations about leaving the bachelor computing lifestyle.) At first, it started running hotter than usual, and its fans would often be going full bore. Then came the random restarts. Finally, it would fail to boot up. It would start up fine…

Photo: MacBook Pro screen, showing the OS X Yosemite progress bar a little past the halfway mark.

Photo taken from the Stack Exchange Forum Ask Different. Click to see the source.

…but after the progress bar filled up — a process that seemed to take a little longer than usual — it would display a blank gray screen like the one shown below:

Photo: MacBook Pro showing a bank gray screen.

Photo taken from the Stack Exchange Forum Ask Different. Click to see the source.

At this point, the computer would either hang there or spontaneously reboot, which would lead back to the blank gray screen.

The first resort: Resetting the NVRAM, a.k.a. the PRAM

Long-time Mac users know that when a Mac starts exhibiting wonky behavior, resetting the PRAM — that’s short for Parameter RAM — often does the trick. Those same long-time Mac users are also the ones who still call it PRAM; Apple’s moved on from that old name and now calls it NVRAM, which stands for Non-Volatile RAM. No matter what you call it, NVRAM/PRAM is a small store of persistent, writable memory that contains a number of system settings and configurations, including:

  • Which disk is your startup disk
  • Networking and port configurations
  • User input settings such as autokey delay and rate, mouse speed, the blink rate of the “text insert point” cursor, how quickly you have to double-click for it to register as a double-click, and so on…
  • All manner of memory settings, including virtual memory, disk cache, and RAM disk

When your Mac starts acting strangely, it’s often the case that the configuration data inside your NVRAM somehow got corrupted. Luckily, there’s a simple but not-very-obvious way to reset your NVRAM, and it’s all based on a combination of keys that you need to press simultaneously when your Mac boots up. This trick goes back to the days when it was still called PRAM, which explains the keys you have to press:

Headline: The key combo for resetting the PRAM on your Mac when you power up / Photo: Mac keyboard with "command", "option", "P", and "R" keys highlighted.

The steps are simple:

  1. Shut down your Mac. Don’t just log out or put it to sleep, shut it all the way down.
  2. Press the power button to turn your Mac on. Get ready to pounce on the keyboard.
  3. Hold down these keys simultaneously: command, option, P, and R. Make sure that you’re holding down this combination of keys before the gray screen appears. You have to be quick.
  4. Your Mac will reboot. Wait for the startup sound, then let go of the keys and let the machine boot as usual.

While this trick has served me well in the past, it didn’t work in this case. It was time for the next trick: resetting the SMC.

The second resort: Resetting the SMC

The SMC — short for System Management Controller — doesn’t have as long a history as the PRAM, as it was introduced with Intel-based Macs (prior to that. Macs were based on Motorola CPUs). The SMC controls a number of interesting hardware goodies, including indicator lights, the display and keyboard backlights, the cooling fans, power, and more.

The steps for resetting the SMC vary depending on the model of Mac. For my particular machine (once again, it’s an early 2011 15″ MacBook Pro), here are the steps:

  1. Shut down your Mac. Don’t just log out or put it to sleep, shut it all the way down.
  2. Unplug the power cord and all peripherals.
  3. Press and hold the power button for 5 seconds.
  4. Release the power button.
  5. Reconnect the power cord.
  6. Press the power button and let the machine boot as usual.

I’m told this trick fixes a lot of hardware weirdness, but not for me. It was time to take it to the shop, but before I could do that, I wanted to back up some files.

Target disk mode: turning your Mac into a drive that other Macs can use

Target disk mode allows a Mac to function as a drive that other Macs can access. My plan was to hook up the following to my wife’s perfectly-functioning Mac:

  • My Mac, with a Thunderbolt cable, and
  • An external hard drive, with a USB cable.

My plan: to boot my Mac into target disk mode, after which I would copy the files I wanted from my Mac to the external hard drive. I crossed my fingers and booted my Mac into target disk mode using the magic key:

Headline: To boot your Mac in target disk mode, hold the T key while booting up / Photo: Mac keyboard with the "T" key highlighted.

Luckily for me, my Mac was working just well enough to boot into target disk mode. You’ll know when a Mac is in this mode by what it shows on its display: a screensaver-like display of a Thunderbolt or FireWire icon that pops up on random locations on the screen. I used a Thunderbolt cable to connect my Mac to my wife’s (it feels a little odd typing wife rather than girlfriend), and the setup looked something like this:

Headline: Wife's Mac - Normal Mode --- My Mac - Target Disk Mode / Image: Two MacBooks connected via ThunderBolt cable, with one Mac showing a window on its screen and the other Mac showing the Thunderbolt icon on its screen.

With my files backed up so that I could work on them with my backup machine, a Windows/Ubuntu box, it was time to take it to the shop.

Good news, bad news, and a NetBoot at the shop

Photo: The storefront of the PeachMac at Citrus Park Mall in Tampa.

The closest authorized Apple dealer and repair shop to me in the PeachMac at Citrus Park Mall. A number of people I know from the Suncoast iOS Meetup group consider it their go-to store for Macs and Macessories, and they’ve generally done right by me as well. I took my machine to the service desk, where they plugged an ethernet cable into it and performed a netboot in order to run their diagnostics application:

Headline: To boot your Mac from the network, hold the N key while booting up / Photo: Mac keyboard with the "N" key highlighted.

Everything except the graphics card checked out fine. “Yeah, I figured that was the problem — it’s been happening with a lot of 2011 MacBooks.”

“What’s been happening with a lot of 2011 MacBooks?” I asked.

The AMD graphics cards on that line of MacBooks, especially the early 2011 models, have been crapping out. In the beginning, Apple just said that you should zap your PRAM, reset the SMC, or even reinstall the OS. That works — for a little while. Then the graphics card just dies again, and your machine’s hanging in mid-boot with nothing but a gray screen. The real fix is a replacement motherboard.”

“And how much is that going to cost?” I was already wondering if I’d have to drop some cash for a new machine. I was hoping to put off that kind of purchase until next year.

“You’re in luck. Apple’s not calling it a recall, but they’ve got a ‘Repair Extension Program’, and you’ll get a brand new mobo for free…but in your case, there’s a hitch.”

Now what? I thought.

“It’s the replacement battery you put in. In order to qualify for this repair, your machine can’t have any non-standard parts in it. We can’t fix it as it is right now, but if you were to go home and put the original battery back in and bring it back here, we wouldn’t know about it, nudge nudge wink wink.”

Banner: Is your MacBook eligible for a free motherboard replacement? Click here to enter its serial number into Apple's Service and Support Coverage page.

I had a new problem: I’d already recycled the old battery, as it barely held a charge and was just taking up space in my home office as an inert, useless block.

Replacing the battery

Screen capture: eBay page for an Apple A1382 laptop battery

Click the screen shot to visit the eBay page.

eBay to the rescue! I found a dealer selling A1382 batteries — the kind that early 2011 15″ MacBook Pros take — for much cheaper than even the replacement battery I bought through OWC. I didn’t need this battery to be any good; I just needed it to be a genuine Apple one in order to qualify for the free repair.

The battery on the 2011-era MacBooks is technically replaceable, but Apple make it a little difficult by holding it in place with tri-lobe screws, which look like Philips screws, but with one less “wing”:

Photo: Two tri-lobe screws.

Your local hardware store doesn’t typically stock tri-lobe screwdrivers, but they can be ordered online, and the non-Apple replacement battery I got from OWC comes with all the screwdrivers you need to install it. Luckily for me, I’d decided to keep them, which made this operation possible:

Back in action

With a standard Apple battery back in its belly, I brought my MacBook back to PeachMac. They ran the diagnostics again, and this time, the support guy — not the same guy I talked to during my earlier visit — pointed out that I should discharge my battery from time to time. “Don’t leave it plugged in all the time,” he said, not knowing that I’d had the battery for all of one day.

“We’ll call you when we’ve finished swapping out the motherboard,” he said. “It’s pretty quick to do. The slow part is getting it shipped to us.”

With my main machine in the shop, I pressed my backup machine — a Lenovo T430, the quintessential TPS Reports writing machine — into active duty. It has an annoying habit of dropping wifi connections, even with the latest drivers installed.

Photo: Joey deVilla's MacBook Pro, complete with 'Nyan Cat' sticker on the palm rest.

“El Guapo”, my trusty early 2011 15″ MacBook Pro, at the time of this writing (April 2, 2015).

They got the job done in a couple of business days. The new motherboard looks newer, as the markings on the chips don’t look as faded by the heat of regular operation, but the real sign is that it takes a little extra force to insert cables into the USB and Thunderbolt jacks; it feels like breaking in a new pair of shoes. The PeachMac guys even replaced a couple of the rubber feet that had gone missing from the bottom of the machine over the years, as well as one of the screws I lost while upgrading my RAM a little while back, all free of charge.

With my preferred machine back in action, I’ll be able to get back to writing iOS apps, as well as iOS development tutorials here on Global Nerdy. Keep watching this space!

Categories
Current Events Tampa Bay Uncategorized

Scenes from Tampa Bay Startup Week’s kickoff party

tampa bay startup week

Photo by David Betz.

tampa bay startup week buttonMonday marked the beginning of Tampa Bay Startup Week, a five-day-long series of events meant to bring creatives, techies, entrepreneurs, and anyone who’s a combination of any of those together to meet, plot, and party. There’s a small but interesting tech scene here in the Tampa Bay area, and a number of factors including the subtropical climate, low cost of living, and the influx of people to the area — you might call it a brain gain — could help it grow dramatically over the next few years.

joey and anitra at startup week tampa bay kickoff

Me and Anitra, working the room. Photo by Laicos.

The week’s kickoff party took place at the Chase Basecamp, a rented venue on 7th Avenue, the main street of Ybor City (pronounced “EE-bor”), Tampa’s nightlife and party neighborhood. The Basecamp (located at the corner of 7th Avenue and 20th Street), serves as the central meeting place for Startup Week participants, as well as a venue for many of the scheduled events.

tbstartupweek kickoff 1

Photo by Laicos.

While chatting up the people from local mobile development shop Sourcetoad, I was introduced to the friendly-looking gentleman below, who went up to me and said “I just have to tell you, I love that accordion!”

bob buckhorn 1

Photo by Laicos.

As he walked away, Anitra told me that I just shook hands with Bob Buckhorn, mayor of Tampa. I’m a relatively recent transplant from Toronto, so I’ve never seen a photo of him, and I’m too used to picturing the mayor as either a sweaty, drug- and booze-addled, embarrassing mess, or too attached to highfalutin’ extravaganzas that are full of sound and fury but ultimately signifying nothing to care about a small grassroots effort like this one. I’m also not used to a mayor with his approval rating.

bob buckhorn 3

Photo by Yours Truly.

He gave a short speech to the crowd, in which he encouraged everyone to meet other people of like minds and ambitions, do what we do, “be a little crazy”, disrupt things, and start businesses. He talked about the brain drain that existed until recently, when people would leave Tampa in search of their fortunes. The situation has been turned around, what with Florida being one of the most moved-to states in the U.S. (as of this writing, it’s the third most populous state, after California and Texas), the population growth in the Tampa Bay/Jacksonville corridor and “Orlampa”, and Penske rental truck data that suggests that the Tampa Bay/Sarasota area is in the top 10 most moved-to locales. He asked the group to keep working to make Tampa a better place to be, if only to make sure that his daughters don’t move away to Atlanta, Austin, or anyplace else.

The money quote that got the audience to really put their hands together:

“I want Tampa Bay to be the economic engine of the southeast.”

It’s bold. It’s ambitious. I like it.

After all the speechifying, he then did what any good mayor would do: take control of the decks and drop a fat beat.

bob buckhorn 2

Photo by Laicos.

Anitra and I spent the rest of the evening either catching up with or getting to know the people in attendance, including:

tampa bay startup week banner

Here’s what’s happening with Tampa Bay Startup Week today and tomorrow. These events are free — just visit the Tampa Bay Startup Week site and sign up!

Today (Tuesday, February 3):

Tomorrow (Wednesday, February 4):

This article also appears in my personal blog, The Adventures of Accordion Guy in the 21st Century.