Skip to content
/ baret Public

Baret is a library that allows you to embed Bacon.js observables into React VDOM

Notifications You must be signed in to change notification settings

calmm-js/baret

Repository files navigation

[ | Tutorial | Reference ]

Baret

Baret is a library that allows you to embed Bacon.js observables into React Virtual DOM. Embedding observables into VDOM has the following benefits:

  • It allows you to use only functional components, because you can then use observables for managing state and ref for component lifetime, leading to more concise code.
  • It helps you to use React in an algorithmically efficient way:
    • The body of a functional component is evaluated only once each time the component is mounted.
    • Only elements that contain embedded observables are rerendered when changes are pushed through observables. An update to a deeply nested VDOM element can be an O(1) operation.

Using Baret couldn't be simpler. You just import React from "baret" and you are good to go.

npm version Gitter Build Status Code Coverage

Contents

Tutorial

To use Baret, you simply import it as React:

import React from "baret"

and you can then write React components:

const oncePerSecond = Bacon.interval(1000).toProperty()

const Clock = () =>
  <div>
    The time is {oncePerSecond.map(() => new Date().toString())}.
  </div>

with VDOM that can have embedded Bacon.js observables.

NOTE: The result, like the Clock above, is just a React component. If you export it, you can use it just like any other React component and even in modules that do not import baret.

Reference

Baret only lifts built-in HTML elements implicitly. The baret-lift attribute on a non-primitive element instructs Baret to lift the element.

For example, you could write:

import * as RR from "react-router"
import React   from "baret"

const Link1 = ({...props}) => <RR.Link baret-lift {...props}/>

to be able to use Link1 with embedded Bacon.js observables:

<Link1 href="https://www.youtube.com/watch?v=Rbm6GXllBiw"
       ref={elem => elem && elem.focus()}>
  {Bacon.sequentially(1000, [3, 2, 1, "Boom!"])}
</Link1>

Note that the ref attribute is only there as an example to contrast with $$ref.

fromBacon allows one to convert a Bacon observable of React elements into a React element. It is useful in case the top-most element of a component depends on a Bacon observable.

For example:

import {fromBacon} from "baret"
import {ifte} from "baret.util"

const Chosen = ({choice}) =>
  fromBacon(ifte(choice, <True/>, <False/>))

Here ifte from baret-util returns an observable that is <True/> when choice is true and otherwise <False/>.

Note that the point of using fromBacon in the above example is that we don't want to wrap the ifte(...) inside an additional element like this:

const Chosen = ({choice}) =>
  <div>
    {ifte(choice, <True/>, <False/>)}
  </div>

fromClass allows one to lift a React component.

For example:

import * as RR from "react-router"
import {fromClass} from "baret"

const Link2 = fromClass(RR.Link)

WARNING: A difficulty with lifting components is that you will then need to use the $$ref attribute, which is not necessary when using baret-lift to lift an element.

The $$ref attribute on an element whose component is lifted using fromClass

<Link2 href="https://www.youtube.com/watch?v=Rbm6GXllBiw"
       $$ref={elem => elem && elem.focus()}>
  {Bacon.sequentially(1000, [3, 2, 1, "Boom!"])}
</Link2>

does the same thing as the ordinary JSX ref attribute: JSX/React treats ref as a special case and it is not passed to components, so a special name had to be introduced for it.

About

Baret is a library that allows you to embed Bacon.js observables into React VDOM

Topics

Resources

Stars

Watchers

Forks

Packages

No packages published