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
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')), });
Returns a driver that uses ReactDOM to render your Cycle.js app into the given container
element.
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
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.
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'] }) ],
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;
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> )); }
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.
MIT, Andre 'Staltz' Medeiros 2018