"Structural Basics of ReactJS," or "PLEASE NO, NOT ANOTHER REACTJS PRIMER"
Published: 2020-07-13 13:44:25

Yes, it's true. This is another ReactJS primer. But maybe, just maybe, this will be the one that makes it sink in for you. (It was for me, after all.)

**Components**

Components are the building blocks in ReactJS. At the most basic level, they take in data and return a React element, or, the thing that should appear on the screen. What's convenient is the data the function takes in is always called the same thing: `props`. Here's a very basic example:

```javascript
const Greet = props => {
  return <h1>Hello from {props.location}</h1>;
}
```

Alternately, an ES6 class can accomplish the same thing:

```javascript
class Greet extends React.Component {
  render() {
    return <h1>Hello from {this.props.location}</h1>;
  }
}
```
Notice the use of capitalization for the component name `Greet`. The reason for this convention is to distinguish it from a typical DOM tag, such as the `<h1>` above. These must be distinguished because a component can also be referred to as an element:

```javascript
const Greet = (props) => {
  return <h1>Hello from {props.location}</h1>;
}

const element = <Greet location="New Orleans" />;

ReactDOM.render(
  element,
  document.getElementById('root')
)
```

In the example above, element `Greet` has a property `location`, which is passed to the component `Greet` through the `props` object, the one and only vehicle for data in any relationship of this nature in React. The `Greet` component formulates the data it receives through `props` into an html-y element, which ReactDOM renders to the DOM. (The html-y business is thanks to JSX, JavaScript XML, a syntax extension to JavaScript. It's helpful, but required.) This example renders to the page "Hello from New Orleans."

Components can also be referred to by other components, allowing for further abstracting away of the structure:

```javascript
const Greet = props => {
  return <h1>Hello from {props.location}</h1>;
}

const App = () => {
  return (
    <div>
      <Greet location="Mid-city, New Orleans" />
      <Greet location="Uptown, New Orleans" />
      <Greet location="French Quarter, New Orleans" />
    </div>
  );
}

ReactDOM.render(
  <App />,
  document.getElementById('root')
);
```

In the example above, component `App`—a common moniker for the highest level component containing all other components—returns three instances of component `Greet`, each with a different value. Notice in component `App` the use of parentheses, another common pattern in ReactJS. The parentheses "collect" all the components to be returned so JavaScript will return multiple lines.

**State**

So far, all the examples we've looked at have been stateless. This means they have not had to keep track of any data changes or re-render. Let's practice that now by refactoring `Greet` to initialize state:

```javascript
class Greet extends React.Component {  
    constructor(props){  
        super(props);  
        this.state = {  
            location: "the West Bank"  
        };  
        this.updateLocation = this.updateLocation.bind(this);   
   }

   updateLocation() {  
        this.setState({  
            location: "the East Bank"  
        });  
    }

    render() {  
        return <h1>Hello from {this.state.location}</h1>;  
    }  
}
```
Component `Greet` is now a class with a constructor (notice the call to `super` like any proper subclass!) which sets state using keyword `this`. Likewise, the method, `updateLocation`, is bound with keyword `this` within the constructor. Inside the method itself is the crucial part that often goes wrong. Here, the `setState` react method must be used, *not* the logical presumption of `this.state.location = "new location"`. Finally, the return element is moved inside of the `render` method, and instead of using `props.location`, uses `this.state.location`. (Side note: notice the use of curly braces around `this.state.location`. These allow the contained code to be interpreted as javascript instead of React, another commonly used tool.) 

Finally, let's add a button to click to update the location:

```javascript
render() {  
  return (  
     <div>  
       <h1>Hello from {this.state.location}</h1>  
       <button onClick={this.updateLocation}>Change location</button>  
     </div>     
  )  
}
```

And now to tie it together:
```javascript
class Greet extends React.Component {   
    constructor(props){  
        super(props);  
        this.state = {  
            location: "the West Bank"  
        };  
        this.updateLocation = this.updateLocation.bind(this);   
   }

   updateLocation() {  
        this.setState({  
            location: "the East Bank"  
        });  
    }

  render() {
    return (
      <div>
        <h1>Hello from {this.state.location}</h1>
        <button onClick={this.updateLocation}>Change location</button>
      </div>
    )
  }
}

const App = () => {
  return (
    <div>
      <Greet />
    </div>
  );
}

ReactDOM.render(
  <App />,
  document.getElementById('root')
);
```

A summary:
1. Component `Greet`'s `location` property resides in its `state`, which can be changed when the button element calls the `updateLocation` method. (Props are still passed down here from `App` but are no longer used since the `location` property now lives in `state`.)
2. The current value of `location` is rendered with the text in the `<h1>` element. 
3. Component `App` renders component `Greet`.
4. `ReactDOM` renders `App` to the page. 

Hopefully, breaking this into small components (see what I did there) helps to "see" the patterns and where the dots connect. To be fair, it's never this easy to picture in reality. References are obscured by being located across numerous files and keeping track of them can become dizzying. *But* the more these structures become second nature, the faster you'll be comfortable diving into a full scale program. Keep at it!