DEV Community

Corbin Callais
Corbin Callais

Posted on

Rundown of React

Introduction

Building a webpage typically takes 3 different languages:

  • HTML, a markup language to give your page structure
  • CSS, a styling language to give your page...style
  • JS, a programming language to give your page functionality

Typically, when you want to do something to the DOM, it's a very long-winded process, and doing that for your entire webpage will take up far more code than the majority of people feel like writing.

The snippet below is a very simple example of grabbing a div tag, and editing its inner text to say something else.

// Grab the item
const testNode = document.getElementById('test');
// Change its text
testNode.innerHTML = 'This is some new text for the tag!';
// What about a child?
const childNode = testNode.childNodes[0];
childNode.innerHTML = "I'm the child of the item above!";

Granted, this is a small example. But when you scale up to a full-fledged webpage, it can get out of hand very quickly.

Usually, jQuery can handle shorthanding the functions to do more in the same amount of space.

// Same thing as above, but in jQuery
$('#test').text('This is some new text for the tag!');
// Grabbing the p tag elements in #text
$('#text > p').text("I'm the child of the item above!");

But that doesn't entirely fix issues with what we primarily use JavaScript for in webpages, and that is dynamic rendering and interaction. Of course, you can use jQuery to do it too, but it's much less intuitive than looking at raw HTML.

And that is where ReactJS1 comes in.

ReactJS

ReactJS, or just React, is, as said in their hyperlink, "A JavaScript library for building user interfaces". React is quite a different beast from JavaScript, literally. It uses an entirely different extension called .jsx. Though, don't let that scare you, it's still just JavaScript, with a little bit of HTML thrown in there.

To get started in React, all you have to do is create an arrow function variable, and have your return statement return some HTML, wrapped in parentheses. This will create what they call a component.

// Define your function
const App = () => {
  // Return HTML. Keep in mind you can only return one "master" node at a time,
  // meaning it will error out if you try to, say, add a second div after the first
  // one closes.
  return (
    <div>
      <p>Hi there!</p>
    </div>
  );
};

See, looks really easy, doesn't it? Now, React doesn't actually add it to the DOM for you, you have to dictate where it gets added first. We do this using ReactDOM.render(), which takes two arguments: your component call, and where to place it. This can be done in standard JS, and is convention to do so.

KEEP IN MIND: when you call your component, instead of doing Component(), you do <Component />. It has to do with generic typing2, primarily seen in Typescript, to keep the code unopinionated as they advertize.

<!-- app.html -->
<!DOCTYPE html>
<head></head>
<body>
  <div id="app"></div>
</body>
// App.jsx
const App = () => {
  return (
    <div>
      <p>Hi there!</p>
    </div>
  );
};
// index.js
ReactDOM.render(<App />, document.getElementById('app'));

And with this, you'll get a basic div that says Hi there!, right in the DOM. Now, this is a basic example, but we can get fairly insane with it, React doesn't care.

And you can also call other components within the component. Let's take the same example, but only the JSX.

const ShoppingList = () => {
  return (
    <div>
      <p>Grocery List:</p>
      <ul>
        <ListItemOne />
        <ListItemTwo />
      </ul>
    </div>
  );
},
ListItemOne = () => {
  return (
    <li>Kale</li>
  )
},
ListItemTwo = () => {
  return (
    <li>Cucumbers</li>
  )
};

This will print out as if you just put the <li>'s directly in ShoppingList. Funny how that works.

But seeing static examples probably will bring up the question of dynamics again. React's got that covered.

"props" and Templating

props, shot for properties, is the parameter in React that determines what can be passed down from parent to child, typically information and/or functions that we want specific parts of our webpage to have.

We pass in props when we call our React components, in the whitespace between the end of the name and the forward slash to end the call. This allows any and all items passed in to act like an object--you assign it a keyname when you pass it in, and that keyname will be in the props object, with the value you pass in. But you can't just use variable names by themselves, because of how JSX works. That's where templating comes in.

Templating is very similar to how string interpolation, using ${}, works, but you can do it with every datatype. And not just when passing down data; you can template anywhere within your JSX return statement.

// ShoppingList.jsx
const ShoppingList = (props) => {
  // You don't need to do this, but it's more convenient to destructure*, as React is
  // built primarily for ES6.
  // items is an array.
  const { items } = props;

  return (
    <div>
      {/* A good example of templating, you can comment in JSX returns like this! */}
      <ul>
      {/* And also map. */}
      {items.map((item, i) => {
        // When you map things in JSX, it will tell you to make sure each iterate has
        // a unique 'key' property. 'key' is a unique keyname and shouldn't be any 
        // other data's name.
        <ListItem key={i} item={item} />
      })}
      </ul>
    </div>
  );
},
ListItem = (props) => {
  const { item } = props;
  // Don't worry about the aforementioned key, React adds it for you.
  return (
    {/* And of course templating works for raw data. */}
    <li>{item}</li>
  );
}
  • Destructuring3
// index.js
const items = ['Kale', 'Cucumbers', 'Cheese'];
ReactDOM.render(<ShoppingList items={items} />, document.getElementById('app'));

And now we'll have a list that contains three bulleted items: Kale, Cucumbers, and Cheese.

Okay, but this is still not very dynamic. There aren't even any click handlers! Well, that's where Statefulness comes in.

Stateless and Stateful

What we've been doing up to this point were "stateless" components, components that aren't expected to be changing throughout the lifetime of the DOM. But what happens if we want, say, to be able to add items to our list as we make our rounds? Enter, stateful components.

Stateful components can explain themselves pretty well; they have an innate this.state property. Yes, this is here too. Because to create these components, we use ES6 pseudoclassical instantiation. We can use non-ES6, but that will involve using a separate file entirely, called 'create-react-class'.

When we create a stateful component, make sure to always extend from React.Component. This will give you all of the methods and such to help you create it.

This next example will get a fair bit more complicated, but I have comments all the way.

class ShoppingList extends React.Component {
  // Make our constructor, and have it call the super (React.Component)
  constructor(props) {
    super(props);
    // From here, define the state. State is always an object, keep that in mind.
    // props is also this.props in here, so keep that in mind too.
    this.state = {
      items: this.props.items
    };
  }
  // In the methods we define a render method. This is what React calls when the state
  // changes, or creating it for the first time.
  render() {
    const { items } = this.state;
    return (
      <div>
        {/* An input value and a button to add stuff. This shouldn't be in Shopping
            List, but this is just because it's lone enough already. */}

        {/* Click handlers should go in protector functions for the same reason 
            setTimeout calls need them; immediate calling can seriously mess up your 
            code. */}

        <input id="input" type="text" placeholder="Add an item..."/>
        <button type="button" onClick={() => this.addItem()}>Add</button>
        <ul>
        {items.map((item, i) => {
          <ListItem key={i} item={item} />
        })}
        </ul>
      </div>
    );
  }
  // Now we need a click handler for the button. We'll use a little bit of jQuery here,
  // so we can grab the value in the input.
  addItem() {
    // Here we want to reassign the value of state entirely, using a convenient
    // function called setState. Does exactly what you think it does.
    const item = $('#input').val(),
          listCopy = this.state.items.slice();

    // Unshift so it appears at the top.
    listCopy.unshift(item);
    this.setState({
      items: listCopy
    });

    // Quality of life optimization, clear the input field when done.
    $('#input').val('');
  }
}

// ListItem can do stateless, the item itself doesn't need to change.
const ListItem = (props) => {
  return (
    <li>{props.item}</li>
  );
}

Okay, that was a lot to take in. Let's break it down.

  1. We start with our usual: define a ShoppingList, and ListItem, and fill them out with the basic necessities, i.e., the rendering function with relevant data.
  2. We then add in two extra items to ShoppingList, an input and a button. We set the onClick (camelCased for React to be able to understand it) to ShoppingList's method of addItem, which takes the input's value and reinstates the state with that new item.
  3. Behind the scenes, React then does its magic and rerenders the component, and all sub-components, to the DOM again, removing the last one, as that's outdated.

Compiling

Since React uses a separate extension, we can't just plug in the code and call it a day. We have to pre-compile the JSX into plain JS, and to do that, we have a separate file entirely, called Babel4. Babel, when installed, will take your JSX code and convert it into plain JS that a browser can understand. Just make sure the base HTML file you run off of takes the compiled versions, not the JSX.

Alternatively, you could just type out the entire thing in plain JS, without the need for a compiler, but that removes all of the syntactic sugar that is in-line HTML, and can seriously nest deep, depending on what you're making.

Conclusion

ReactJS is a JS library that makes creating a webpage far simpler than what it is without it. It seamlessly mixes HTML into JavaScript, which makes it far more readable in terms of its structure. You can handily pass in data to dynamically render it to the DOM, and you can even have stateful components that can change within the lifespan of the DOM.

Superscript References

  1. ReactJS's homepage: https://reactjs.org/
  2. Typescript Generic Typing: https://www.typescriptlang.org/docs/handbook/generics.html
  3. Destructuring is a different beast than the topic at hand, but the basic idea is pulling keys from an object into their own separate variables, to avoid redundant typing.
  4. Babel compiler: https://babeljs.io/

Top comments (0)