React

Introduction

  • it is NOT a framework
  • fast rendering library

 

Defining points:

  • virtual DOM
  • enforces component-driven development

Virtual DOM

  • JavaScript is cheap
  • touching the DOM is expensive
    • as it involves rendering

 

  • keeps an in-memory representation of the DOM
  • when something changes, calculates a diff
  • updates once
    • only the parts that actually changed

Component Driven Dev.

Components are:

  • the building block of a React application
  • the only block of a React application
    • hence the appeal of React

 

It allows you to split a complex problem in multiple simpler ones.

Component structure

import React from "react";

class Button extends React.Component {
    render() {
        return <div className="button"></div>;
    }
}

Minimal component

Highlights:

  • all components extend React.Component 
  • HTML like syntax called JSX 
  • className attribute for CSS class

Component Properties

Properties are:

  • an explicit way for a parent component to pass data to it's children
  • a way for the children to notify parent about changes, through callbacks
class Button extends React.Component {
    render() {
        return (
            <div className="button" onClick={this.props.onClick}>
                {this.props.text}
            </div>
        );
    }
}

Button.defaultProps = {
    text: "Default Button Text",
    onClick: () => {}
};

Component State

  • calling setState triggers a re-render
  • setState calls are transparently bundled together
class CheckBox extends React.Component {
    constructor(props, context) {
        super(props, context);

        this.state = {
            checked: false
        };
    }

    render() {
        return (
            <input type="checkbox" 
                   checked={this.state.checked} 
                   onClick={this.handleChange.bind(this)} />
        );
    }
}

Component Lifecycle

Initialization:

  • constructor
  • componentWillMount()
    • once, before initial rendering
    • setState will not trigger a re-render
  • render()
  • componentDidMount()
    • once, after initial rending
    • DOM can be accessed

Component Lifecycle

State changes:

  • shouldComponentUpdate(nextProps, nextState)
    • when new props or state are being received​
  • componentWillUpdate(nextProps, nextState)
    • no allowed setState here
  • render()
  • componentDidUpdate(prevProps, prevState)
    • DOM can be accessed

Component Lifecycle

Props changes:

  • componentWillReceiveProps(nextProps)
    • when new props are received
    • not on initial rendering
  • shouldComponentUpdate(nextProps, nextState)
  • render()
  • componentDidUpdate(prevProps, prevState)

Component Lifecycle

Unmounting:

  • componentWillUnmount()
    • immediately before unmount from the DOM
    • perform cleanup operations here

Rendering children

this.props.children

  • is an object when there is only one child
  • is an array when there are multiple children

 

You can use the utility methods from React.Children:

  • React.Children.map(children, child => {}, context)
  • React.Children.forEach(children, child => {}, context)
  • React.Children.toArray()
  • React.Children.count()

 

Handling children:

  • React.cloneElement(element, props, children);
  • element.type

Rendering children

// simple approach
render() {
    return <div>{this.props.children}</div>;
}

// adding or modifying child properties
render() {
    return <div>{this.renderChildren()}</div>;
}

renderChildren() {
    return React.Children.map(this.props.children, (child) => {
        return React.cloneElement(child, {
            key: child.props.id, // an id uniq to the child
            overridenProp: "newVal",
            newProp: "someVal"
        });
    });
}

// checking for a child type
renderChildren() {
    return React.Children.map(this.props.children, (child) => {
        // only render CheckButton 's
        if (child.type == CheckButton) {
            return child;
        }
    });
}

Refs

Refs or references:

  • gets the DOM node - for a DOM component
  • gets the backing instance of a component - for a composite component

 

JSX

  • doesn't return a component instance
  • returns a representation of the component - a ReactElement

 

Refs break the encapsulation principle, try to avoid using them.

Refs 

import ReactDOM from "react-dom";

class Container extends React.Component {
	// accessing refs
        componentDidMount() {
		this.refs.title; // DOM node
                this.tabView = $.tabView(this.refs.title);
		this.refs.button; // React component instance
		ReactDom.findDOMNode(this.refs.button); // DOM node
	}

        // attaching refs
	render() {
		return (
			<div>
				<span ref="title">Foo</span>
                                <MyComponent ref={(el) => {/**/}}
				<Button ref="button"/>
			</div>
		);
	}

        componentWillUnmount() {
            this.tabView.distroy();
        }
}

React

By kenjiru

React

An airplane overview of React

  • 561