React

Made by

Developer-
Happiness
& Sanity

Model

View

Controller

Model

View

Controller

 

View

 

Key principles

  • Mix DOM generation and view logic
  • Re-render on every change
  • Virtual DOM

Separation

of concerns?

But... what about

Markup and
view logic:

Same concern,

different technology.

Rerendering on every change must be slow?

No.

Thanks to the virtual DOM

Virtual DOM?

Virtual DOM

Changes are made to an in-memory, virtual DOM and this is used to calculate the smallest possible set of changes to the actual DOM.

 

This way, we do one slow, big change to the DOM instead of many small (but still slow) changes.

Virtual DOM in-memory → FAST

Actual DOM → sync browser API → SLOW

Component

  • Components are the elementary building blocks in react
     
  • Everything is a component
     
  • A component contains the UI logic and the markup
     
  • Components can be composed
import React from 'react';

class HelloWorld extends React.Component {
    render() {
        return <h1>Hello world!</h1>;
    }
}

export default HelloWorld;

JSX

JSX

  • HTML-like syntax. Two exceptions (className and htmlFor)
     
  • Transpiles to regular JS (using Babel or something similar)
return (
    <div className="hello-world">
        <h1 className="hello-world__heading">Hello world!</h1>
        <p>It's a beautiful day</p>
    </div>
);
return React.createElement(
    'div',
    { className: 'hello-world' },
    [
        React.createElement('h1', {
            className: 'hello-world__heading' 
        }, 'Hello world!'),

        React.createElement('p', null, 'It\'s a beautiful day')
    ]
);

turns into...

*drum roll*

Composing components

Composing components

When building components with components

  • the code gets more reusable
     
  • the chance of everything eventually turning into spaghetti code is lowered and
     
  • the UI becomes more consistent
class Heading extends React.Component {
    render() {
        return (
            <h1 className="heading">Hello, world!</h1>
        );
    }
}

class HelloWorld extends React.Component {
    render() {
        return (
            <div className="hello-world">
                <Heading />
                <p>It's a beautiful day</p>
            </div>
        );
    }
}

Component in component

class Heading extends React.Component {
    render() {
        return (
            <h1 className="heading">{ this.props.children }</h1>
        );
    }
}

Heading.propTypes = {
    children: React.PropTypes.element
};

class HelloWorld extends React.Component {
    render() {
        return (
            <div className="hello-world">
                <Heading>Hello, world!</Heading>
                <p>It's a beautiful day</p>
            </div>
        );
    }
}

Components in component

Props & state

Props

Used when passing data down the component tree:

 

<Greet name="Fredrik"/>

 

Never changed from within the component.

State

State within a component. Similar to $scope  in Angular.

 

 

 

Never changed (directly) from outside the component. Only from the inside using setState.

Prop types

Prop types

Rules defining the props the component expects to be passed.

 

  • A prop can be specified as required
     
  • Different predefined types
     
  • Errors is given if a prop has the wrong type
/* ./components/greeting.jsx */

import React from 'react';

class Greeting extends React.Component {
    render() {
        return <h1>Hello, { this.prop.name }!</h1>;
    }
}

Greeting.propTypes = {
    name: React.PropTypes.string.isRequired
};

export default Greeting;
import React from 'react';

import Greeting from './components/greeting.jsx';

export default class Hello extends React.Component {
    render() {
        return <Greeting name=[]/>;
    }
}

Routing

Routing

React-router is the component you want to use. In most cases you'll be building the routes as a component that refers to a component for each page.

<Router history={appHistory}>
    <Route path="/" component={Layout} >
        <IndexRoute component={Home} />
    </Route>
</Router>

Data fetching

Don't start out with redux, redux-saga and 97 other dependencies from boilerplate X found on the intertube. Start out with what you need, and what you understand!

Data fetching

For prototyping JSON stored in a file in you project will work just fine (we'll see that later). As your app grows you'll usually get to the point where JSON is painful. Move on to fetching from an API.

 

When that too gets painful, you're probably at the point where Redux is right for a more predictable and effective data flow.

Pure components

It's not that important, but since you'll hear the term soon enough...

Pure components

[The linting tool will tell you that some of your modules should be written as pure components.]

 

A pure component is a component that does not have state – a stateless component. Because it doesn't have state, it is possible to write it as a function, skipping the whole
class Something extends React.component
and so on. Less writing.

export default class Greeting extends React.Component {
    render() {
        return <h1>Hello, { this.props.name }!</h1>
    }
}

Something.propTypes = {
    name: React.PropTypes.string
};
const Something = ({ name }) => <h1>Hello, { name }!</h1>;

Something.propTypes = {
    name: React.PropTypes.string
};

export default Something;

vs

A few tips

Contain data fetching in container components and keep your view components clean

Hold off with abstracting everything until you have an actual need

Read up on a few basic patterns from functional programming

start with map, filter and reduce

// Map                                    
['a', 'b', 'c'].map((val, index) => (     
    <span key={key}>{val}</span>          
))                                        

/*
 <span key="0">a</span>
 <span key="1">b</span>
 <span key="2">c</span>
*/

// Filter
['a', 'b', 'c']
    .filter(val => val === 'a)
    .map((val, index) => (
        <span key={key}>{val}</span>
    ));

/*
 <span key="0">a</span>
*/
// Map                                    
['a', 'b', 'c'].map((val, index) => (     
    <span key={key}>{val}</span>          
))                                        

/*
 <span key="0">a</span>
 <span key="1">b</span>
 <span key="2">c</span>
*/

// Filter
['a', 'b', 'c']
    .filter(val => val === 'a)
    .map((val, index) => (
        <span key={key}>{val}</span>
    ));

/*
 <span key="0">a</span>
*/

React intoduction

By Kristoffer Brabrand

React intoduction

  • 789