Fig. 12 A Guide for Developers

React.js From Scratch: Part 5 — Hello World+

Here are two short examples to get you started, and plenty of resources to keep you going.

Here’s the final part of my React starter series. If you missed any previous chapters, make sure to view Part 1 , Part 2, Part 3, and Part 4.

Ok. Let’s do this.


Last time, we got your development environment set up. This time, we will be building two basic React examples: “Hello, World!” and an event example that introduces a few heavier concepts central to React.js as a whole.

Hello, World!

This is as basic as it gets, but it took us quite a while to get here. We can start from where we left off in Part 4, or you can download the source code from the repo. If you already have the code downloaded, make sure you pull the latest version down to make sure I didn’t leave you with some funky bugs.

Once you have the project open in your favorite text editor, run gulp from the command line (from within the project directory) to bundle everything, spin up the server, and to watch for code changes.

Let’s spend some time in the scripts.js file. The file should be blank. If it isn’t, delete everything inside it and save.

Note: In some React projects, you may notice the .jsx extension in use instead of .js. Both are valid filetypes, but you need to make sure to configure your development environment to look for changes to those filetypes for bundling.

Ok. So. The first thing we need to do to before writing any React code is include the dependencies. Your package.json file includes the React and ReactDOM modules, so now we can just include the two modules into our script file to utilize them.

// script.js
var React = require('react');
var ReactDOM = require('react-dom');

Excellent. Now for your first lines of React code. Ready?

// script.js
var React = require('react');
var ReactDOM = require('react-dom');

// Holy crap, React!
ReactDOM.render(
  <h1>Hello, world!</h1>,
  document.getElementById('hello')
);

Save it.

But, what the heck is that stuff we just wrote? What is ReactDOM versus React?

Actually, ReactDOM is all the DOM manipulation methods separate from the React core code. They used to be combined into one library, but after version 0.14, they were separated. React.js isn’t just for web apps, you see.

Facebook also built React Native which allows developers to create native applications for iOS and Android with React components. It doesn’t make much sense to include browser DOM rendering methods with a library that doesn’t actually utilize them.

The React core takes care of all the actual application lifecycle stuff—it’s the innards.

The ReactDOM library includes the method render() as seen above. render() takes two arguments: the item being rendered, and (as an optional argument) where it should be rendered to. The item being rendered (as a return value) is a <h1>Hello, world!</h1> block, and it will be rendered in place of some element with an id of hello.

Note: If render() has a return value that is longer than one line, make sure to include it inside parenthesis.

Open the index.html file. Around line 8 you should see <div id="hello"></div>. This is where the React component will be rendered. BrowserSync should automatically refresh the page after any code has changed. At this point, “Hello, world!” should appear on the screen.

That’s it! You wrote code that renders a “Hello, world!” <h1> node. Now let’s change the code up a bit and structure it more like a traditional React component. This code will have the exact same output.

var HelloWorld = React.createClass({
  render: function() {
    return <h1>Hello, world!</h1>
  }
});

ReactDOM.render(<HelloWorld />, document.getElementById('hello'));

Nothing should be different in the browser, but what we have done is create a component with the createClass() method packaged with the React library. It has its own render() method that returns a single element (which can have children). This component can then be passed to the ReactDOM.render() method as a custom html element, <HelloWorld />. Neat, eh?

What are Props?

You might have seen or heard the word “props” in relation to React. Props (or properties) are a term for values that can be passed to and consumed by components. Props are considered read only and a component will not be changing the values after they are received.

For example:

var HelloWorld = React.createClass({
  render: function() {
    return <h1>{this.props.message}</h1>
  }
});

ReactDOM.render(<HelloWorld message="Hello, world!" />, document.getElementById('hello'));

We added a dynamic message to our HelloWorld component by passing the message through a custom attribute. Props are a simple, but super helpful concept for any React project.

State and Events

We’re going to create a simple form with a text field and a submit button. The submission of the form should update some text on the page. To build this, we will need to understand the concepts of state and events.

Let’s start building a TextForm component. This code can be written directly under the previous example.

// script.js
var TextForm = React.createClass({

});

ReactDOM.render(<TextForm />, document.getElementById('form'));

We also need to update the html so the component has a place to render.

<!-- index.html -->

<!-- added directly below the 'hello' div -->
<div id="form"></div>

For now, let’s build a simple form inside the render() function for our TextForm component.

// script.js
var TextForm = React.createClass({
  render: function() {
    return (
      <form className="react-form">
        <input
          type="text"
          placeholder="Type something..."
        />
        <input type="submit" value="Submit" />
        <p>Awaiting input...</p>
      </form>
    );
  }
});

Perfect. We have a simple form with a text field and a submit button. The first thing we should work with is React events. There is a good amount of events that React supports, but we’re going to focus on a simple click event. Let’s add a click hander function and wire it up to the submit button. We’re also going to prevent the form from submitting (i.e. refreshing the page).

Another important thing to note is the use of the className attribute. This is the same as a normal class attribute on an HTML element. However, the word “class” is reserved in JavaScript and cannot be used in this context. If you want to add custom classes to your components (perhaps for styling), className is how you do it.

You can create event listeners by adding them as an attribute to any element. In this case, the <input> element is going to be linked to a handleClick() function through an onClick event.

// script.js
var TextForm = React.createClass({

  // here's a click handler function
  handleClick: function(event) {
    event.preventDefault();
    alert('clicked!');
  },

  render: function() {
    return (
      <form className="react-form">
        <input
          type="text"
          placeholder="Type something..."
        />
        // add the onClick event inline
        <input type="submit" onClick={this.handleClick} value="Submit" />
        <p>Awaiting input...</p>
      </form>
    );
  }
});

Save and check it out! You should see an alert after clicking the submit button.

handleClick() is not a reserved function name. I made it up. When you add custom functions (such as event handlers), you can name them whatever you want, as long as they aren’t in use by the React API.

React components have lifecycles. They depend on several optional functions (render() is the only required function) for data and view management at different points in an application’s life. For example, if you wanted to have default data values set before anything renders, use the getInitialState() function. If you want to control data before the component is going to update, do it inside the componentWillUpdate() function. There are many more functions to chose from.

Speaking of getInitialState(), now’s a great time to talk about state.

What is State?

Each component has a state. State is a data object scoped to a component which stores values that can be displayed or manipulated. This means that parts of the component can pass data around as well as update it. We’re going to use the getInitialState() function to set default data that we will change with use elsewhere in the form.

// script.js
var TextForm = React.createClass({

  // Let's set some default values
  getInitialState: function() {
    return {
      value: '',
      output: 'Awaiting input...'
    };
  },

  handleClick: function(event) {
    event.preventDefault();
    alert('clicked!');
  },
  render: function() {
    return (
      <form className="react-form">
        <input
          type="text"
          placeholder="Type something..."
        />
        <input type="submit" onClick={this.handleClick} value="Submit" />

        // we can refer to the state here instead of hardcoding the value into the markup
        <p>{this.state.output}</p>
      </form>
    );
  }
});

We added an object containing an output value of “Awaiting input…”. We then took that object and used it in between the <p> tag. On save, the screen shouldn’t look any different. We are doing this because we want that output value to be dynamic. The goal is to grab the value from the input, then assign it to the <p> tag. We’re just laying the groundwork.

The value value will be used in a couple minutes. I’m just initializing it to a blank string for now.

Updating the State

The only thing left to do is to grab a value from the input field after a click of the submit button. Let’s update the handleClick() function to change the state of the component. Also, we will need to grab a hold of the value of the input field as the user types (so we don’t miss anything). Here’s what the component should look like now. There’s a lot more code, but I’ll break it down for you.

 1 // script.js
 2 
 3 var TextForm = React.createClass({
 4   getInitialState: function() {
 5     return {
 6       value: '',
 7       output: 'Awaiting input...'
 8     };
 9   },
10 
11   // on field change, update the component state
12   handleChange: function(event) {
13     // getting the value directly from the input field
14     // this mimics traditional JS events
15     this.setState( {value: event.target.value} );
16   },
17 
18   // on form submit, update the component state
19   // sets this.state.output to this.state.value
20   handleClick: function(event) {
21     event.preventDefault();
22     this.setState( {output: this.state.value} );
23   },
24 
25   // render the form
26   render: function() {
27     return (
28       <form className="react-form">
29         <input
30           type="text"
31           placeholder="Type something..."
32           value={this.state.value} // set the value of the input to the state value
33           onChange={this.handleChange} // fire handleChange() on input change
34         />
35         <input type="submit" onClick={this.handleClick} value="Submit" />
36         <p>{this.state.output}</p>
37       </form>
38     );
39   }
40 });
41 
42 ReactDOM.render(<TextForm/>, document.getElementById('form'));

Wow. Okay. What changed?

On line 12 of the code block above, we added a custom function called handleChange(). Looking on line 33, you can see we are firing the function through the use of the onChange event. Whenever the input field is updated by typing in it, handleChange() will run. Inside, we are calling a function called this.setState() and setting the value from the incoming event itself ({event.target.value}). So, the field value is now stored in the state object for the component. this.setState() is the simple way to update state data in a component.

Also, we are using the handleClick() function to grab the value from the input field and update the state. Next is where React shines.

React components can tell when data has changed somewhere—it’s always listening. Wherever you are outputting some value of the state, the output will automatically update. Note the paragraph markup in the form:

<p>{this.state.output}</p>

Whenever the state changes (by user interaction or otherwise) the text will automatically update to reflect this. Go ahead. Use the form. Editing the field and submitting will update the paragraph output. It’s black magic, I say.

So there… you did it! You have a working basic component that handles state changes through events! Nice work. I built the same project, which is available if you grab the latest from the repo. Switch to the hello-world branch to play around.

Debugging with React Developer Tools

Remember the React Developer Tools from last time? Here’s where you can put them to good use. With the Chrome Developer Tools open, click the React tab. You will see the React application structure as well as a pane to view the props and other values of each element. Just like the standard Developer Tools, you can edit the values and watch the application update. In this case, you should see both the <HelloWorld> and <TextForm> components in the structure pane.

React Developer Tools

These tools are only available for Chrome.

If you would like to change the default browser to Chrome, add the browser name to the BrowserSync init block in your Gulpfile.

browserSync.init({
  server: "./",
  browser: "google chrome" // <- here
});

Where to now?

We have reached the end of our React from Scratch journey. We have covered a bunch of topics from ES2015, to JSX, to task runners, and finally basic React components.

There are a billion more things that I didn’t cover (as React is a huge beast), so we need to point you to the next arena. In the “Further Reading” section, I have listed a couple of awesome React resources for you. Thank you so much for reading this series—it’s been a blast to write, research, and learn.

More advanced React tutorials (shorter ones, I swear) will be coming soon. SOOOOOON. I mean, we need to actually build something a bit more complex, right? Also, what about that whole Webpack thing?

Also, if you have more resources, please send them my way! I crave additional learning.


Further Reading

Written by Andy Rossi Published on March 24, 2016