This is a project I completed as a student at hackreactor.
React is “a JavaScript library for building user interfaces,” that gives you tools for interacting with the DOM that are cleaner and more performant than with raw JavaScript or jQuery.
React is declarative, rather than imperative. Imperative code, like raw JavaScript or jQuery, says how something ought to occur. Declarative code (HTML being an example) states what something ought to be, and hides the how away from the developer. Therefore, in React, you write components that looks a lot like HTML, and the React library, hidden from you, handles the details of how these components are actually rendered to the DOM.
Think of React components as superpowered HTML tags that:
- Can be given information for how they ought to behave
- Can communicate with each other
- Can be composed, reused and nested together to build small to very large applications
React is used on some of the largest websites in the world, including Instagram and Facebook, where React was developed. It is fast, does an excellent job supporting code modularity and reuse, and developers tend to find it clean and fun to work with.
- Learn how to create React components
- Learn how to render React components
- Learn how to use JSX and ES6 in React code
- Learn how to utilize props
- Learn how React components handle user events
- Learn the difference between stateless functional components and class components
- Learn why there is state and how to update it
- npm install -g live-server
- live-server
There are two steps to making components in a React application:
- Create a component
- Render it to the page
The following is a very basic React component, written in ES6, and JSX. JSX is a JavaScript syntax extension allowing you to write declaritive HTML-like code:
var App = () => (
<div>Some cliche salutation</div>
);
In its most basic form, to create a React component you just write a function (with a capitalized name by convention) that returns JSX. The JSX should represent the intended HTML of the rendered component.
To render a React component you use ReactDOM.render(componentInstance, DOMElement). JSX returns a component instance when you wrap a component in an HTML tag. Thus, to render the component App created above:
ReactDOM.render(<App />, document.getElementById("actual-dom-element-where-I-want-to-render-my-component"));
- Inside app.js, create a GroceryList component that contains an unordered list of 2 grocery items. Render this component to the div tag in index.html with an id of app
- To appreciate what ES6 and JSX offers when writing React code, copy the snippets above into the Babel REPL and see what they look like in ES5
When creating React components, you can return JSX representations of React component instances in addition to JSX representations of HTML. For example, assuming you have created a TodoList component:
var App = () => (
<div>
<h2>My Todo List</h2>
<TodoList />
</div>
);
- Create React components for the 2 items in your grocery list. For example, if your grocery list contains "cucumbers" and "kale", create a Cucumbers component and a Kale component
- Use these two new components inside your GroceryList component instead of the hardcoded
- s
React gives you a way to pass data into components, making them more dynamic and reusable. When creating a component, you can expect an argument to be passed in, typically called props. When creating an instance of this component, you can pass in these props using a syntax similar to passing properties into HTML elements.
Note that inside of JSX, you can write JavaScript expressions inside of curly braces:
// Here we create a `TodoList` component
var TodoList = (props) => (
<ul>
<li>{props.todos[0]}</li>
<li>{props.todos[1]}</li>
<li>{props.todos[2]}</li>
</ul>
);
var App = () => (
<div>
<h2>My Todo List</h2>
<TodoList todos={['Learn React', 'Crush Recast.ly', 'Maybe sleep']}/> // Here we are creating an instance of the `TodoList` component
</div>
);
- Create a reusable GroceryListItem component that dynamically renders a given grocery item
- Refactor GroceryList to dynamically render an array of groceryItems, utilizing your new GroceryListItem component
React components come with built-in support for many user events.
var TodoList = (props) => {
// This function will be called when the first `<li>` below is clicked on
// Notice that event handling functions receive an `event` object
// We want to define it where it has access to `props`
var onListItemClick = (event) => {
console.log('I got clicked');
};
// Because we used curly braces with this arrow function
// we have to write an explicit `return` statement
return (
<ul>
<li onClick={onListItemClick}>{props.todos[0]}</li>
<li>{props.todos[1]}</li>
<li>{props.todos[2]}</li>
</ul>
);
}
var App = () => (
<div>
<h2>My Todo List</h2>
<TodoList todos={['Learn React', 'Crush Recast.ly', 'Maybe sleep']}/> // Here we are creating an instance of the `TodoList` component
</div>
);
Class components Up until now we have been working with stateless functional components which are great when all you need to do is receive props and render JSX. Recall that props are immutable and cannot be changed once passed in from a parent. If an entire React application is created with only functional stateless components, it would not be very different from a static HTML page.
To make applications interactive, our components need to do more than simply receive props. Sometimes components need to store data that cannot be explicitly passed in as props and re-render this data changes.
React makes this possible with class components. To demonstrate this, we'll refactor each
// A class component can be defined as an ES6 class
// that extends the base Component class included in the React library
class TodoListItem extends React.Component {
// A `constructor` method is expected on all ES6 classes
// When React instantiates the component,
// it will pass `props` to the constructor
constructor(props) {
// Equivalent to ES5's React.Component.call(this, props)
super(props);
}
// Every class component must have a `render` method
// Stateless functional components are pretty much just this method
render() {
// `props` is no longer passed as an argument,
// but instead accessed with `this.props`
return (
<li>{this.props.todo}</li>
);
}
}
// Update our `TodoList` to use the new `TodoListItem` component
// This can still be a stateless function component!
var TodoList = (props) => (
<ul>
{props.todos.map(todo =>
<TodoListItem todo={todo} />
)}
</ul>
);
- Refactor GroceryListItem to be a class component
We're going to add a feature to our TodoListItem that toggles a crossed-out style when its
state is only available on class components. We can initialize a class component's state in its constructor. To update the state, invoke this.setState. Whenever this.setState is called, the component re-renders.
class TodoListItem extends React.Component {
constructor(props) {
super(props);
// `state` is just an object literal
this.state = {
done: false
};
}
// When a list item is clicked, we will toggle the `done`
// boolean, and our component's `render` method will run again
onListItemClick() {
this.setState({
done: !this.state.done
});
}
render() {
// Making the style conditional on our `state` lets us
// update it based on user interactions.
var style = {
textDecoration: this.state.done ? 'line-through' : 'none'
};
// You can pass inline styles using React's `style` attribute to any component
// snake-cased css properties become camelCased this this object
return (
<li style={style} onClick={this.onListItemClick.bind(this)}>{this.props.todo}</li>
);
}
}
- Make it so that when your mouse hovers over a list element of a GroceryListItem that it turns bold