Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/calmm-js/baret
Baret is a library that allows you to embed Bacon.js observables into React VDOM
https://github.com/calmm-js/baret
bacon jsx observables react reactive vdom
Last synced: 2 months ago
JSON representation
Baret is a library that allows you to embed Bacon.js observables into React VDOM
- Host: GitHub
- URL: https://github.com/calmm-js/baret
- Owner: calmm-js
- Created: 2017-03-07T11:12:30.000Z (almost 8 years ago)
- Default Branch: master
- Last Pushed: 2018-04-04T14:03:01.000Z (over 6 years ago)
- Last Synced: 2024-10-10T14:34:41.841Z (2 months ago)
- Topics: bacon, jsx, observables, react, reactive, vdom
- Language: JavaScript
- Homepage:
- Size: 135 KB
- Stars: 12
- Watchers: 4
- Forks: 4
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
[ [≡](#contents) | [Tutorial](#tutorial) | [Reference](#reference) ]
# Baret
Baret is a library that allows you to
embed [Bacon.js](https://baconjs.github.io/) observables
into [React](https://facebook.github.io/react/) Virtual DOM. Embedding
observables into VDOM has the following benefits:
* It allows you to use
only
[functional components](https://facebook.github.io/react/docs/components-and-props.html#functional-and-class-components),
because you can then use observables for managing state
and [`ref`](https://facebook.github.io/react/docs/refs-and-the-dom.html) 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.
* This also helps you to avoid issues such as
the
[gotcha with ref](https://facebook.github.io/react/docs/refs-and-the-dom.html#caveats).
* 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](https://badge.fury.io/js/baret.svg)](http://badge.fury.io/js/baret)
[![Gitter](https://img.shields.io/gitter/room/calmm-js/chat.js.svg)](https://gitter.im/calmm-js/chat)
[![Build Status](https://travis-ci.org/calmm-js/baret.svg?branch=master)](https://travis-ci.org/calmm-js/baret)
[![Code Coverage](https://img.shields.io/codecov/c/github/calmm-js/baret/master.svg)](https://codecov.io/github/calmm-js/baret?branch=master)
[![](https://david-dm.org/calmm-js/baret.svg)](https://david-dm.org/calmm-js/baret)
[![](https://david-dm.org/calmm-js/baret/dev-status.svg)](https://david-dm.org/calmm-js/baret?type=dev)## Contents
* [Tutorial](#tutorial)
* [Reference](#reference)
* [`baret-lift` attribute](#baret-lift)
* [`fromBacon(observableVDOM)`](#fromBacon "fromBacon: Observable VDOM -> VDOM")
* [`fromClass(Component)`](#fromClass "fromClass: Component props -> Component (Observable props)")
* [`$$ref` attribute](#ref)## Tutorial
To use Baret, you simply import it as `React`:
```jsx
import React from "baret"
```and you can then write React components:
```jsx
const oncePerSecond = Bacon.interval(1000).toProperty()const Clock = () =>
The time is {oncePerSecond.map(() => new Date().toString())}.
```with VDOM that can have embedded [Bacon.js](https://baconjs.github.io/)
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
### [≡](#contents) [`baret-lift` attribute](#baret-lift)
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:
```jsx
import * as RR from "react-router"
import React from "baret"const Link1 = ({...props}) =>
```to be able to use `Link1` with
embedded [Bacon.js](https://baconjs.github.io/) observables:```jsx
elem && elem.focus()}>
{Bacon.sequentially(1000, [3, 2, 1, "Boom!"])}```
Note that the `ref` attribute is only there as an example to contrast
with [`$$ref`](#ref).### [≡](#contents) [`fromBacon(observableVDOM)`](#fromBacon "fromBacon: Observable VDOM -> VDOM")
`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:
```jsx
import {fromBacon} from "baret"
import {ifte} from "baret.util"const Chosen = ({choice}) =>
fromBacon(ifte(choice, , ))
```Here `ifte` from `baret-util` returns an observable that is `` when
`choice` is true and otherwise ``.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:```jsx
const Chosen = ({choice}) =>
{ifte(choice, , )}
```### [≡](#contents) [`fromClass(Component)`](#fromClass "fromClass: Component props -> Component (Observable props)")
`fromClass` allows one to lift a React component.
For example:
```jsx
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`](#ref) attribute, which is not necessary when
using [`baret-lift`](#baret-lift) to lift an element.#### [≡](#contents) [`$$ref` attribute](#ref)
The `$$ref` attribute on an element whose component is lifted using `fromClass`
```jsx
elem && elem.focus()}>
{Bacon.sequentially(1000, [3, 2, 1, "Boom!"])}```
does the same thing as the ordinary
JSX
[`ref` attribute](https://facebook.github.io/react/docs/more-about-refs.html#the-ref-callback-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.