Introduction

Installation

DIO can be installed through the following CDN's.

  1. unpkg.com/dio.js
  2. cdn.jsdelivr.net/npm/dio.js

OR through NPM —


npm install dio.js --save

Getting Started

This Hello World example can be used try out code you see in this introduction.


render(
  h('h1', 'Hello, world!'),
  document.getElementById('root')
)

This Hello World example should render a heading with the content 'Hello World!'.

Introducing Elements


const element = h('h1', 'Hello World');

Elements are represented by JavaScript objects that describe what and how a particular element should look and behave.

Given what to render at any one point in time, the underlining reconciler takes care of updating/mounting these elements correctly to reflect the current state of the interface.

Elements are composed of three distinct parts — type, props and children. These can be used to assign the desired behaviours and properties that we want our elements to assume.


const element = h('h1', {
	class: 'red'
}, 'Hello World')

Components

Components are units that allow us to sub-divide an interface into independent, reusable pieces.

Conceptually, components are like JavaScript functions. They accept arbitrary arguments and return elements describing the look and behavior of the interface.

Functions and Classes

The first varient of a component is a JavaScript Function.


function Welcome (props) {
	return h('h1', 'Hello', props.name)
}

The second varient, a JavaScript Class that implements a render method.


class Welcome {
	render() {
		return h('h1', 'Hello', this.props.name)
	}
}

Components accept props, state & context as arguments.

For the most part function and class components are equivalent in what you can archive with them, and like their counter part(class components) function components can also retain state.

Rendering a Component


function Welcome({name}) {
  return h('h1', name)
}

render(
  h(Welcome, {name: 'World'}),
  document.getElementById('root')
)

The example demonstrates that we can render components just as we would elements but it also shows us that when required we can pass arbitrary arguments "props" to a component.

Lifecycles

Lifecycles allow us to observe the different phases that a component unit goes through throughout the render process, and like state, function components can hold lifecycle methods.

When implementated lifecycles are invoked in certain stages of the components life.

Function Lifecycle


function Welcome () {
	return h('h1', props.name)
}
Welcome.componentDidMount = () => {}

Class Lifecycle


class Welcome {
	componentDidMount() {}
	render({name}) {
		return h('h1', name)
	}
}

Lifecycle method When it gets called
getInitialState After instantiating a component
componentWillMount Before the component has mounted
componentDidMount After the component has mounted
componentWillReceiveProps Before new props are received
shouldComponentUpdate Before the component is updated
componentWillUpdate Before the component is updated
componentDidUpdate After the component has updated
componentWillUnmount Before the component is removed
componentDidCatch When an error is thrown

Events & State

Events allow us to respond to behaviour.


class Input {
	handleInput({target}) {
		return {value: target.value}
	}
	render() {
		return [
			h('input', {
				type: 'text',
				onInput: this.handleInput
			}),
			h('h1', this.state.value)
		]
	}
}

render(h(Input), document.getElementById('root'))

The example demonstrates how we can listen to events on an element and respond in kind.

In this particular example we update the value of our <h1> element to contain the value of the <input> whenever an input event is triggered.

Interoperability

There are two main machanisms that make interoperability with the native DOM possible.

Refs

Refs allow us to reference the underline native DOM node that an element renders to the DOM.


const Welcome = return h('h1', {
	ref: el => console.log(el)
}, 'Welcome')

findDOMNode

findDOMNode retrieves the native DOM node that a component renders.


class Welcome {
	componentDidMount() {
		console.log(findDOMNode(this))
	}
	render() {
		return h('div')
	}
}

In addition both lifecycles componentDidMount & componentWillUnmount recieve a reference to the DOM node that a component renders.


class Welcome {
	componentDidMount(node) {
		console.log(node)
	}
	render() {
		return h('div')
	}
}

Portals

Portals allow us to render some part of a components outside of itself while preserving the colocation relationship between the two.


const portal = document.querySelector('.modal')

render(
	['Welcome', createPortal('Back', portal)],
	document.getElementById('root')
)

In this example the text 'Hey' will render in the defined root container, while the text 'Welcome Back' will render within the defined portal.

Introducing JSX

JSX is an optional syntax extension that enables you to write HTML tags interspersed with JavaScript.

It is not a requirement, but it may be more pleasing to use depending on your preferences.

For example writing h('h1', 'Hello') as <h1>Hello</h1>

JSX Pragma

A pragma /* @jsx h */ is a comment that instructs the JSX compiler to use a function.

For example h as the calling function, in turn transforming <h1>Hello</h1> into h('h1', null, 'Hello')

Most JSX compilers will support pragma comments but they are only scoped to the files they are defined. This might make for a sub-optimal experience depending on your preferences; But it is possible to define a project setup through Babel/Typescript.

Setup

Babel —

Babel is a JavaScript transpiler best known for its ability to turn ES6 (the next version of JavaScript) into code that runs in your browser (or on your server) today.

{
  "plugins": [
  	["transform-react-jsx", {
  		"pragma": "dio.createElement",
  		"pragmaFrag": "dio.Fragment"
  	}]
  ]
}

Typescript —

Typescript is a typed superset of JavaScript that compiles to plain JavaScript.

{
  "compilerOptions": {
    "jsx": "React",
    "jsxFactory": "dio.createElement"
  }
}

Moving Foward

There are still details we haven't gone into that hopefully the API can help document.

At this point you can jump right into creating something with DIO, look at some Examples or learn how DIO works on GitHub.