Giter VIP home page Giter VIP logo

dio.js's Introduction

DIO

dio.js

A Library For Building User Interfaces.

  • ~7kb

licence npm Build Status Coverage Status dependencies Join the chat at https://gitter.im/thysultan/dio.js

Support

  • Edge
  • IE 9+
  • Chrome
  • Firefox
  • Safari
  • Node

Installation

Direct Download

<script src=dio.min.js></script>

CDN

<script src=https://unpkg.com/dio.js></script>
<script src=https://cdn.jsdelivr.net/npm/dio.js></script>

NPM

npm install dio.js --save

Getting started

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

The easiest way to get started with DIO is to walk through the Introduction to DIO or the API Documentation.

Features

The following is an overview of the features DIO allows you to make use of.

  1. Rendering

    1. Elements
    2. Components
    3. Primitives like strings, numbers, null, undefined
    4. Fragments like Arrays, Iterables
    5. and others renderables like Promises and Portals
  2. Components

    1. Functional stateful components
    2. Class stateful components
  3. Events

    1. Functions or EventListener
    2. Preserve "this" reference
  4. Errors

    1. Error boundaries through componentDidCatch
  5. setState

    1. As with a Object
    2. As with a Promise
    3. As with an implicit return
  6. Lifecycle

    1. async componentWillUnmount
    2. async getInitialState

Example

This intentionally overloaded example presents a few features detailed above, namely – error boundaries, an implicit setState return, Promise setState and rendering Promises & Fragments.

class Input {
	// Error Boundary
	componentDidCatch ({stack, message, ...error}, {componentStack}) {
		return {error: true}
	}
	// Isomorphic Async getInitialState
	async getInitialState() {
		return {value: 'Hi!'}
	}
	// Implicit Promise setState
	async handleInput({target}, props, state) {
		return {value: target.value}
	}
	// Rendering Promises
	async render(props, {value, error}, context) {
		if (error)
			return h('h1', 'Something went wrong!')

		// Rendering Fragments
		return [
			h('input', {
				value: value,
				// bonus: events preserve "this" reference
				onInput: this.handleInput
			}),
			h('p', value)
		]
	}
}

dio.render(h(Input))

Links

  1. Introduction to DIO
  2. API Documentation
  3. REPL

--

Goals

Public react compatibility with an edge, this means that any react library should work as long as it does not make use of undocumented features for example API's prefixed with unstable_.

Differences

Custom Reconciler, Config

There are a few react-like libraries but at the date of this writing DIO might be the only one to afford the ability to create your own renderer. Now while both React and DIO expose a way to create your own renderer, there is a difference in how you create this custom renderer.

While react might exposes a package called react-reconciler DIO exposes a public API for this as part of an overloaded createFactory API.

This is coupled with fact that the config structure somewhat differ as do the arguments passed to the methodes implemented – for example react might pass the view instance(in the case of ReactDOM this might be a DOM node) to the method while DIO would pass the related virtual element(s) that have a reference to the DOM node, which you can then extract(by means of a property read), which can be argued gives renderers room to do more with what they have.

All in all it is easy for DIO to consume the react reconcilers config, so the plan is that once the react-reconciler package is considererd stable by the React team DIO is in a position to consume the sementics of its config.

As a show of confidence DIO itself uses this interface to implement the DOM renderer that it ships by default, which can be used to create any renderer.

Portals, Event Bubbling

Events bubble in Portals as you would expect them to in the DOM, this avoid issues like #11387 where bubbling them through the virtual tree has unintented behaviors.

The createPortal API also supports string selectors which allows for server-side rendering portals and out-of-order rendering, a feature might also make it into react: related issue.

Events, Delegation

Though it may sound strange when considering all the articles about event delegation and performance/memory DIO on the other hand intentionally does not implement events with delegation to avoid the performance impact that comes with re-implementing(in JavaScript) event bubbling that browsers do which is almost always faster handled by the host enviroment.

However DIO's model does not create any more memory when attaching events than you might imagine React's event delegation model to use, interestingly it might just create less considerering that where react might create a Map entry for each element-event-pair the browser is in a better position to use an optimial reference pointer and data-strucuture to track the relationship between event handlers and elements when using addEventListener for each element.

In simple terms implementing events with Reacts model of delegation(preserving the DOM model of bubbling) involves doing the same/more amount of work at assignment of the event and more work when emitting the events than a browser would otherwise do.

Hydration, Self Correcting

DIO goes the whole 9 yards to correct differences when hydrating where react might otherwise error or ignore.

Error Messages

There are error messages for incorrect use of top-level API's but react is famous for going the extra mile in both error messages and warnings regarding what is considered best practices in dev mode but the presence of error boundaries insures that if an error does occur DIO can give you a full trace of the component tree affected in a presentable error message and more.

Tradeoffs

Community.

React hands down has the bigger community.

Warnings

React has dev mode warnings where DIO does not.

unstable_API

Sadly some libraries do make use of these undocumented unstable API's that React sometimes exposes with a unstable_ prefix – which DIO intentionally ignores implementing due to their otherwise "considered" unstable nature.

Edge

There a lot of small details that give DIO its edge that don't realy touch on new API's but rather on creating a larger surface area of what React already supports and adding to this.

For example React can render strings, numbers, elements and components but what if it was able to render Promises or Thenables? This would help solve a lot of "problems" with data fetching and lazy loading that is possible with React but not declaratively incentivised at the library level.

Supporting Thenables/Promises

The ability to render thenables makes support for code-splitting and lazy loading easy at the library level. The ability to use a Promise for initial state makes data fetching more declartive at the library level and the ability to update state with a promise allows you to deal with async services without cutting back on the declarative nature that is afforded to first-class citizens like elements.

class Input {
	async getInitialState() {
		return await fetch('service/')
	}
	async handleInput({target}, props, state) {
		return await fetch('service/?value=${target.value}')
	}
	async render() {
		return h('input', {
			value: value,
			onInput: this.handleInput
		})
	}
}

Supporting Pending Unmounts

It's no suprise that declarative entry and outro animations in react are not at its best compared to other first-class citizens. Allowing a means to declaratively define a pending unmount that can trigger an outro animation before it is unmounted goes a long away in reducing the abstractions that go into dealing with this when this feature is abscent from the library level.

class Input {
	async componentWillUnmount(){
		return new Promise((resolve) => {
			findDOMNode(this).animate([...], {
				...
			}).onfinish = resolve
		})
	}
	async getInitialState() {
		return {value: 'Initial value!'}
	}
	async handleInput({target}, props, state) {
		return {value: target.value}
	}
	async render() {
		return h('input', {
			value: value,
			onInput: this.handleInput
		})
	}
}

Events & "This"

Events in React have the infamous legacy of .bind. The implementation details of DIO allow it to avoid this legacy as demonstrated in the examples mentioned.

Server Side Renderer

While React 16 does allow some level of async server side rendering with renderToNodeStream DIO takes it a step further to make sure that the mentioned points about rendering Promises and Promise states applies just as well in a server side render.

That is to say the server-side renderer can render whatever the client renderer can, including portals – which coupled with the client renderers hydration API allows for out of order rendering that is ordered on the client while hydrating.

dio.js's People

Contributors

thysultan avatar askuzminov avatar chmln avatar peterdavehello avatar gitter-badger avatar

Watchers

James Cloos avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.