Karet is a library that allows you to embed Kefir properties into React Virtual DOM. Embedding observable properties into VDOM has the following benefits:
O(1)
operation.Using Karet couldn't be simpler. Usually you just
import * as React from 'karet'
and you are good to go.
To use Karet, you simply import it as React
:
import * as React from 'karet'
and you can then write React components:
const App = () => (
<div>
<h1>What is the date and time</h1>
{Kefir.interval(1000)
.toProperty(() => {})
.map(() => new Date().toString())}
</div>
)
with VDOM that can have embedded Kefir
properties. This works because Karet exports an enhanced version of
createElement
.
Note that the result, like the date and time display 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 karet
.
Here is a live example in CodeSandbox.
More links to live examples in the Calmm documentation Wiki.
Karet passes through the following exports from React:
Children
as is.
Note that with observable properties in children these functions may not do
exactly what you want and you might want to
lift them.Fragment
as is. It should work
without problems.createContext
as
is. Note that with Karet it is preferable to put observable properties into
the context and let changes propagate through them rather than update the
context. Also note that neither the provider nor the consumer are lifted by
default. Lifting the consumer will likely cause no issues, but lifting the
provider would eliminate observables from the value
property and could cause
problems. If you need to have observable children inside the provider, you can
wrap the children inside a
Fragment
. See the CodeSandbox
examples
createElement
which
lifts Kefir properties in fragments
and built-in HTML elements.forwardRef
as is.useContext
as
is.Notably the following are not exported:
Component
and
PureComponent
,
because with Karet you really don't need them and the render
method can
cause undesired component remounting when used with observable properties
embedded into VDOM.cloneElement
does
not work out of the box with elements containing Kefir properties. It should
be possible to support it,
however.createRef
is not
exported, because Karet Util
provides an alternative
that works better with observable properties.Suspense
and lazy
are not needed since import()
returns a promise and you can just convert
that to an observable property
like this.karet-lift
attributeKaret only lifts built-in HTML elements and
fragments implicitly. The
karet-lift
attribute on a non-primitive element instructs Karet to lift the
element.
For example, you could write:
import Select from 'react-select'
import * as React from 'karet'
// ...
const ReactSelect1 = ({value}) => (
<Select
karet-lift
name="form-field-name"
value={value}
options={options}
onChange={o => value.set(o && o.value)}
/>
)
to be able to use Select
from
React Select with embedded
Kefir Atoms.
Here is a live example in CodeSandbox.
fromClass(Component)
Karet only lifts built-in HTML elements and
fragments implicitly. fromClass
allows one to create lifted version of a given React component.
For example, you could write:
import Select from 'react-select'
import * as React from 'karet'
const SelectLifted = React.fromClass(Select)
const ReactSelect2 = ({value}) => (
<SelectLifted
name="form-field-name"
value={value}
options={options}
onChange={o => value.set(o && o.value)}
/>
)
to be able to use Select
from
React Select with embedded
Kefir Atoms.
Here is a live example in CodeSandbox.
The
React inline elements transform
is incompatible with Karet, because it bypasses React.createElement
. OTOH, the
React constant elements transform
works just fine with Karet.