Introduction
Installation
Through a CDN:
<script src="unpkg.com/dyo"></script>
OR installed through NPM —
npm install dyo --save
Getting Started
The following is the "Hello World" example of Dyo.
import {render} from 'dyo'
render('Hello, world!', document)
This will render the text content 'Hello World!' into the root of the document.
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 reconciler takes care of mounting and updating these elements 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 desired behaviours and properties for elements to assume.
In the following we describe a heading element with a class attribute and the text content "Hello World".
const element = h('h1', {class: 'red'}, 'Hello World')
Components
Components are independent, reusable building blocks of an interface.
Conceptually, components are JavaScript functions. They accept arbitrary arguments as props
and return elements describing the appearance and behavior of the interface.
function Welcome (props) {
return h('h1', {}, 'Hello', props.name)
}
Rendering a Component
function Welcome(props) {
return h('h1', {}, props.name)
}
render(h(Welcome, {name: 'World'}), document)
The example demonstrates that like elements we can render components and pass arbitrary arguments "props" to a component similar to how might do the same for a function.
Effects
Effects lets you perform side effects within a component:
import {useEffect} from 'dyo'
function Welcome (props) {
useEffect(() => {
document.title = `Hello World`
})
return h('h1', {}, 'Hello World!')
}
There are two types of efffects – useEffect and useLayout.
Unlike useLayout, useEffect effects are scheduled with requestAnimationFrame.
Effect | When it gets called |
---|---|
useEffect |
Executed within the next requestAnimationFrame. |
useLayout |
Before yielding back to the host process. |
State
Like JavaScript functions components can accept arbitrary arguments as "props", but unlike functions components can also use and allocate persistant state, localized to that particular component.
function Welcome (props) {
const [state, setState] = useState('Hello World!')
return h(h1, {}, state)
}
Events & State
Events form the interactive bridge between the user and interface.
The following example demonstrates this through a text input element and an onInput event that is dispatched when data is exchanged.
function Welcome (props) {
const [state, setState] = useState('')
return h('form',
h('h1', {}, state)
h('input', {
type: 'text',
onInput: event => setState(event.target.value)
})
)
}
The example propagates the value of the <input>
element to the value of the <h1>
element whenever an input
event is dispatched.
Interoperability
The ref prop plural: refs; allows authors the ability to retrieve a reference to the document node that a "virtual" element actualizes when it is mounted.
These come in two variants: function, and object refs.
Function Refs
function Welcome (props) {
return h('h1', {ref: value => console.assert(value instanceof Node)})
}
Object Refs
function Welcome (props) {
const reference = useRef()
useLayout(() => {
console.assert(reference.current instanceof Node)
})
return h('h1', {ref: reference})
}
Where the later would have the objects current
property populated with the reference to the node.
Introducing JSX
JSX is an optional syntax extension that enables one to write HTML templates 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 an html dialect: <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 in. 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": "h",
"pragmaFrag": "Fragment"
}]
]
}
Typescript —
Typescript is a typed superset of JavaScript that compiles to plain JavaScript.
{
"compilerOptions": {
"jsx": "React",
"jsxFactory": "h"
}
}
Moving Foward
There are details we haven't gone into that hopefully the API and Advanced sections can help document.
At this point you can jump right into creating something, look at some Examples or learn and contribute on GitHub.