
Many of the tutorials I see on [React](https://facebook.github.io/react/) try to (web)pack in a lot. Yes; there is a lot of tooling that _can_ go around React, however, I didn't fully grasp how amazing React is until I was shown a very simple example of the way the actual, functioning code is written. This tutorial focuses on percisely that; just jumping in and writing some code.
## The Setup - [CodePen](https://codepen.io)
[CodePen](https://codepen.io) is one of the great tools out there for testing out code. It offers a lot of options for defining how your code will run; the biggest of which is being able to add resources (libraries) very easily.
* On a new "pen", go to `Settings` and then `JavaScript`.
* For `JavaScript Preprocessor` select `Babel` - this will allow us to write using ES6. React can be written in older specs, however, most tutorials and code snippets you find will be using ES6.
* In the `Add External JavaScript` section add the following:
* `//cdnjs.cloudflare.com/ajax/libs/react/0.13.0/react.min.js` - The React Library
* Click `Save & Close`
The pen is now setup to allow us to write in ES6, utilizing the React framework.
## Writing Some Code
> Code-first, explain later.
This seems to be a great way to learn, so let's jump in!
### Give Your App a Home
This first one is easy; in the `HTML` editor drop this:
```html
<div id="app"></app>
```
We need a place for our app to load. We'll use this as that place, as you'll see in the next section. MOVING ON!
### Render Something
In the `JavaScript` editor, enter the following:
```javascript
class MyComponent extends React.Component {
render() {
return (
<h1>
Hello React!
</h1>
)
}
}
React.render(<MyComponent />, document.getElementById('app'))
```
**[View on CodePen](https://codepen.io/fluidbyte/pen/GMooWW?editors=0010)**
The above is really the leanest example I could think of for demonstrating rendering content through React. Reading through the code we just did the following:
1. Created a new class called `MyComponent` that extends React's `Component` class.
2. We defined a `render` method for that class so React knows what to render.
3. We added something to actually render to the `render` method (via the `return`).
4. We told React to render `<MyComponent />` to our DOM at `#app` that we created in the first section.
Congratulations! That's how to build a component. Let's make more!
### Adding Components, Using Properties
Let's add another component, it's so much fun!
```javascript
class ListItem extends React.Component {
render () {
return (
<li>{this.props.content}</li>
)
}
}
class MyComponent extends React.Component {
render() {
return (
<div>
<h1>
Hello React!
</h1>
<ul>
<ListItem content="Build a component" />
<ListItem content="Add more components" />
</ul>
</div>
)
}
}
React.render(<MyComponent />, document.getElementById('app'))
```
**[View on CodePen](https://codepen.io/fluidbyte/pen/veGbNg?editors=0010)**
Alright, so the above may seem a bit contrived, however, it very clearly demonstrates how components work in a broader sense, to allow us to break things up into manageable, reusable pieces.
So we've done the following:
1. Created a new component `ListItem` which simply renders the text passed via the `content` property (`this.props.content`)
2. Added several instances of the `ListItem` component into the `MyComponent`'s `render` method inside a `<ul>`.
3. Wrapped everything in `MyComponent`'s `render` with a `<div>`. This is a React-thing; everything _must_ have a parent.
### Using State
The components above are great, but have no way of working with data. This is where `state` comes in. Below is and example, expanding on what has been done previously:
```javascript
class ListItem extends React.Component {
render () {
return (
<li>{this.props.content}</li>
)
}
}
class MyComponent extends React.Component {
constructor (props, ctx) {
super(props)
this.state = {
items: [
'Build a component',
'Add more components',
'Add some state'
]
}
}
render() {
return (
<div>
<h1>
Hello React!
</h1>
<ul>
{this.state.items.map((item) => {
return (
<ListItem content={item} />
)
})}
</ul>
</div>
)
}
}
React.render(<MyComponent />, document.getElementById('app'))
```
**[View on CodePen](https://codepen.io/fluidbyte/pen/JrXxOK?editors=0010)**
So there's a bit more code here. Let's dive into it. All of the changes were made in the `MyComponent` class:
1. We added a `constructor` which allows you to perform actions when a Class is instantiated. In this case we're doing 2 things:
1. We call `super(props, ctx)` which is a fancy way of React initializing the class. Not to worry, this is just a standard
2. We initialized state by creating a `this.state` object which contains an array of `items`
2. Next we made our `ListItems` load from state by simply `map`'ing over them and returning new `ListItem` components with the content set to the item in the current iteration.
So now when `MyComponent` renders it loads all of its content from the state. Nice!
## Using Events to Change State
State is cool, but fairly useless without some interaction, so let's add that with events!
```javascript
class ListItem extends React.Component {
render () {
return (
<li>{this.props.content}</li>
)
}
}
class MyComponent extends React.Component {
constructor (props, ctx) {
super(props)
this.state = {
items: [
'Build a component',
'Add more components',
'Add some state'
],
newItem: ''
}
// Have to do this because Codepen doesn't support
// stage-3 es6, normally wouldn't need this...
this.onChangeNewItem = this.onChangeNewItem.bind(this)
this.onSubmitNewItem = this.onSubmitNewItem.bind(this)
}
onChangeNewItem (e) {
this.setState({
newItem: e.target.value
})
}
onSubmitNewItem (e) {
const newItems = this.state.items.concat(this.state.newItem)
this.setState({
items: newItems,
newItem: ''
})
e.preventDefault()
}
render() {
return (
<div>
<h1>
Hello React!
</h1>
<ul>
{this.state.items.map((item) => {
return (
<ListItem content={item} />
)
})}
</ul>
<form onSubmit={this.onSubmitNewItem}>
<input
type="text"
onChange={this.onChangeNewItem}
value={this.state.newItem}
/>
<button type="submit">Submit</button>
</form>
</div>
)
}
}
React.render(<MyComponent />, document.getElementById('app'))
```
**[View on CodePen](https://codepen.io/fluidbyte/pen/PJNVxB?editors=0010)**
Again, we're expanding on what we already have, so looking at what was added:
1. In the `constructor` we modified `this.state` to have a property `newItem`, this will store new items when we want to add something to the list.
2. This is sort of a special case (because CodePen doesn't support stage-3 es6) but we bind 2 new methods in the constructor.
3. We create a `onChangeNewItem` event. This will be bound to a form element. Whenever the value of that element changes we need to update our state using `setState` so we know what the current value of that field is.
4. We create a `onSubmitNewItem` which will do several things:
1. It will add (`concat`) the value of `newItem` into a new array (we don't mutate, folks)
2. It will set the state of `items` to the `newItems` array, then set `newItem` to empty (like you would expect when you submit a form)
3. We call `e.preventDefault()` to prevent the form from doing its default action (`POST`'ing the whole form)
5. Next, in the `render` method we simply add a form. The form itself gets a `onSubmit` binding to the `onSubmitNewItem` method.
6. In the form, the `input` has 2 bindings - we bind the `onChange` to `onChangeNewItem` which updates the `this.state.newItem` value to store that new data, and the `value` gets bound directly to the state for `newItem` so when the state of that item is changed the value reflects the state.
Now, when we enter a new item in the form and submit, the event-bound methods will handle the changes, update state, and our list will grow!
## Conclusion
This was a very introductory example of using React, however, it demonstrates some of the major concepts of React; rendering, components, props, state and events.
These are the core concepts on which React builds upon. If/once you feel like this makes some sense you're well on your way to being able to build more complex React applications.
I plan to do a follow up post on setting up an actual development environment and some of the more tooling-related topics which I will post a link to here.
If you'd like me to go into depth on any of the above, have questions, or would like me to setup some more specific examples let me know!