Many of the tutorials I see on 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.
CodePen 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.
Settings and then JavaScript.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.Add External JavaScript section add the following:
//cdnjs.cloudflare.com/ajax/libs/react/0.13.0/react.min.js - The React LibrarySave & CloseThe pen is now setup to allow us to write in ES6, utilizing the React framework.
Code-first, explain later.
This seems to be a great way to learn, so let's jump in!
This first one is easy; in the HTML editor drop this:
<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!
In the JavaScript editor, enter the following:
class MyComponent extends React.Component {
render() {
return (
<h1>
Hello React!
</h1>
)
}
}
React.render(<MyComponent />, document.getElementById('app'))
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:
MyComponent that extends React's Component class.render method for that class so React knows what to render.render method (via the return).<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!
Let's add another component, it's so much fun!
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'))
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:
ListItem which simply renders the text passed via the content property (this.props.content)ListItem component into the MyComponent's render method inside a <ul>.MyComponent's render with a <div>. This is a React-thing; everything must have a parent.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:
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'))
So there's a bit more code here. Let's dive into it. All of the changes were made in the MyComponent class:
constructor which allows you to perform actions when a Class is instantiated. In this case we're doing 2 things:
super(props, ctx) which is a fancy way of React initializing the class. Not to worry, this is just a standardthis.state object which contains an array of itemsListItems 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!
State is cool, but fairly useless without some interaction, so let's add that with events!
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'))
Again, we're expanding on what we already have, so looking at what was added:
constructor we modified this.state to have a property newItem, this will store new items when we want to add something to the list.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.onSubmitNewItem which will do several things:
concat) the value of newItem into a new array (we don't mutate, folks)items to the newItems array, then set newItem to empty (like you would expect when you submit a form)e.preventDefault() to prevent the form from doing its default action (POST'ing the whole form)render method we simply add a form. The form itself gets a onSubmit binding to the onSubmitNewItem method.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!
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!