Skip to content

Instantly share code, notes, and snippets.

@MinimumViablePerson
Created July 13, 2018 12:54
Show Gist options
  • Save MinimumViablePerson/6483fbc599526d6119afa352bae3666f to your computer and use it in GitHub Desktop.
Save MinimumViablePerson/6483fbc599526d6119afa352bae3666f to your computer and use it in GitHub Desktop.

React from scratch By Nicolas Marcora

Why React?

React is a JavaScript library for creating user interfaces. Its core principles are declarative code, efficiency, and flexibility. Simply specify what your component looks like and React will keep it up-to-date when the underlying data changes.

- Official React Documentation

Building applications with JavaScript alone can work, but it quickly becomes unmanageable as your application grows.

Let's say you're building a todo app. Wouldn't it be great if you could just have a simple JavaScript array with strings in it, you defined what a single todo item should look like and magically, all the todos appeared on the screen? And what if adding a new todo on the screen was just a matter of adding a string to that JavaScript array? What if removing or editing a todo was also just as simple as removing or editing that item in the array?

This is the power of React. You define things once, you work with your data, and everything else just falls into place without you having to worry about it. Oh, and it's fast!

Pre-requisite knowledge

  • Basic HTML
  • Basic JavaScript
  • ES6 (classes and arrow functions)

Open and setup Codepen for React

  • Start a new project
  • Add the React and ReactDOM libraries
  • Choose Babel as the preprocessor

Create a root div

This will be React's way into the page. We will use this div to render our components.

<div id='root'></div>

Create the simplest component (Stateless functional)

A stateless functional component is just a function that takes props as a parameter and returns a React element.

Note: Although this may look like HTML, it is actually JSX.

const App = () => <h1>Hello</h1>;

Render component onto root div

ReactDOM takes 2 arguments:

  • What to render (React component)
  • Where to render it (DOM element)

Note: Once our component has been defined, we render it by calling it like we would any other HTML/JSX tag. i.e. App = <App /> (case sensitive)

ReactDOM.render(
  <App />,
  document.querySelector('#root')
)

Styling

Just like with regular HTML, we can give our React elements attributes. For example, you easily target your element with CSS by giving it a class or an id attribute.

Note: Since the class keyword is already taken in JavaScript, className is used instead.

Also note: Attributes in React are camelCased. i.e. onClick instead of onlick.

const App = () => <h1 className='title' id='hello'>Hello</h1>;

Interpolation

Since we're not actually using HTML, but JSX, we have the power to use JavaScript directly inside our components. All you have to do wrap your JavaScript code around {}.

const App = () => <h1>{3 + 5}</h1>;
const App = () => <h1>{'hello'.toUpperCase()}</h1>;
const name = 'Nicolas';

const App = () => <h1>{name}</h1>;
const name = 'Nicolas';

const App = () => <h1>{name.length > 4 && name}</h1>;
const name = 'Nicolas';

const App = () =>
  <h1>{name.length > 4 ? name : 'Your name is too short.'}</h1>;

Props

Every React component gets passed a props object. This object has all data passed to a component and is how a parent component can send things to a child component.

Since props are not directly owned by a component, you should avoid modifying them.

const App = props => <h1>{`Hello, ${props.name}!`}</h1>;

ReactDOM.render(
  <App name='Nicolas' />,
  document.querySelector('#root')
)

Composition

You can render React components within other React components.

const Title = () => 'Hello';

const App = () => (
  <div>
    <Title />
  </div>
);

Class components

Sometimes just having props and rendering elements is not enough. Class components allow you to more logic (lifecycle methods) and state.

class App extends React.Component {
  render() {
    return <div>App</div>;
  }
}

State

Sometimes, just having data passed down by a parent component is not enough, and we need the component to have some data of its own. This is called a component's state.

class App extends React.Component {
  state = {
    name: 'Nicolas'
  }

  render() {
    return <div>{this.state.name}</div>;
  }
}

or

class App extends React.Component {
  constructor() {
    this.state = state = {
      name: 'Nicolas'
    }
  }

  render() {
    return <div>{this.state.name}</div>;
  }
}

Modifying state

We said before that props don't belong to a component, so we should avoid modifying them. But state totally belongs to a component, so it's perfectly ok to change it. However, you should never change it directly. Instead, class components give you a handy method called setState.

class App extends React.Component {
  state = {
    name: 'Nicolas'
  }

  capitalizeName = () => {

    this.state.name = this.state.name.toUpperCase(); // AVOID THIS
    this.setState({name: this.state.name.toUpperCase()}); // DO THIS INSTEAD

  }

  render() {
    return <div>

      {this.state.name}

    </div>;
  }
}

Events

Like in regular HTML, you can add events to your React elements. This allows you to "react" to things like a button click or a form submission.

The list is long, but you can learn more about what events are available here.

class App extends React.Component {

  // ...

  render() {
    return <div>

      {this.state.name}
      <button onClick={this.capitalizeName}>CAPITALIZE</button>
    </div>;
  }
}

Project: Counter

You now have enough knowledge to build your very first React application. Let's make a counter. You'll need to:

  • Keep track of a counter number
  • Display that number on the screen
  • Create a method to increase the counter
  • Create a method to decrease the counter
  • Call these methods from your page
class App extends React.Component {
  state = {
    counter: 0
  }

  increaseCounter = () => {
    this.setState({ counter: this.state.counter + 1 })
  }

  decreaseCounter = () => {
    this.setState({ counter: this.state.counter - 1 })
  }

  render() {
    return <div>
      {this.state.counter}
      <button onClick={this.increaseCounter}>
        +
      </button>
      <button onClick={this.decreaseCounter}>
        -
      </button>
    </div>;
  }
}

Challenge: Extract the - and + buttons into their own components. (Or maybe even a single, reusable component?)

Extra challenge / Homework: Build a todo app.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment