react-dom
react-dom copied to clipboard
Cycle.js driver that uses React DOM to render the view
Cycle ReactDOM
Cycle.js driver that uses React DOM to render the view
- Provides a driver factory
makeDOMDriver - Contains hyperscript helper functions, like in Cycle DOM
npm install @cycle/react-dom
Example
import xs from 'xstream';
import {run} from '@cycle/run';
import {makeDOMDriver, div, h1, button} from '@cycle/react-dom';
function main(sources) {
const inc = Symbol();
const inc$ = sources.react.select(inc).events('click');
const count$ = inc$.fold(count => count + 1, 0);
const vdom$ = count$.map(i =>
div([
h1(`Counter: ${i}`),
button(inc, 'Increment'),
]),
);
return {
react: vdom$,
};
}
run(main, {
react: makeDOMDriver(document.getElementById('app')),
});
API
makeDOMDriver(container)
Returns a driver that uses ReactDOM to render your Cycle.js app into the given container element.
Hyperscript helpers
Import hyperscript helpers such as div, span, p, button, input, etc to create React elements to represent the respective HTML elements: <div>, <span>, <p>, <button>, <input>, etc.
The basic usage is div(props, children), but some variations and shortcuts are allowed:
div()becomesh('div')div('#foo')becomesh('div', {id: 'foo'})div('.red')becomesh('div', {className: 'red'})div('.red.circle')becomesh('div', {className: 'red circle'})div('#foo.red')becomesh('div', {id: 'foo', className: 'red'})div(propsObject)becomesh('div', propsObject)div('text content')becomesh('div', 'text content')div([child1, child2])becomesh('div', [child1, child2])div(props, 'text content')becomesh('div', props, 'text content')div(props, [child1, child2])becomesh('div', props, [child1, child2])div('#foo.bar', props, [child1, child2])- etc
There are also shortcuts for (MVI) intent selectors:
div(someSymbol)becomesh('div', {sel: someSymbol})div('inc#foo.bar')becomesh('div', {sel: 'inc', id: 'foo', className: 'bar'})div('inc', props)becomesh('div', {sel: 'inc', ...props})div('inc', 'text content')becomesh('div', {sel: 'inc'}, 'text content')div('inc', [child1])becomesh('div', {sel: 'inc'}, [child1])div('inc', props, [child1])becomesh('div', {sel: 'inc'}, [child1])- etc
JSX
Babel
Add the following to your webpack config:
module: {
rules: [
{
test: /\.jsx?$/,
loader: 'babel-loader',
options: {
plugins: [
['transform-react-jsx', { pragma: 'jsxFactory.createElement' }],
]
}
}
]
},
If you used create-cycle-app you may have to eject to modify the config.
Automatically providing jsxFactory
You can avoid having to import jsxFactory in every jsx file by allowing webpack to provide it:
plugins: [
new webpack.ProvidePlugin({
jsxFactory: ['react-dom', 'jsxFactory']
})
],
Typescript
Add the following to your tsconfig.json:
{
"compilerOptions": {
"jsx": "react",
"jsxFactory": "jsxFactory.createElement"
}
}
If webpack is providing jsxFactory you will need to add typings to custom-typings.d.ts:
declare var jsxFactory: any;
Usage
import { jsxFactory } from '@cycle/react-dom';
function view(state$: Stream<State>): Stream<ReactElement> {
return state$.map(({ count }) => (
<div>
<h2>Counter: {count}</h2>
<button sel="add">Add</button>
<button sel="subtract">Subtract</button>
</div>
));
}
Notes
Please ensure you are depending on compatible versions of @cycle/react and @cycle/react-dom. They should both be at least version 2.1.x.
yarn list @cycle/react
should return a single result.
License
MIT, Andre 'Staltz' Medeiros 2018