bs-effector-react
ReasonML bindings for effector-react.
Installation
npm install --save bs-effector-react
Then add bs-effector to bs-dependencies in your bsconfig.json
:
{
"bs-dependencies": ["bs-effector-react"]
}
Usage
open Effector;
let counter = Store.make(0);
let increment: Event.t(unit) = Event.make("increment");
counter
|> Store.watch(state => Js.log(state));
counter
|> Store.on(increment, (state, _) => state + 1);
let component = EffectorReact.createComponent(counter);
let make = (_children) => {
...component,
render: self =>
<div className="counter">
(ReasonReact.stringToElement("counter: " ++ string_of_int(self.state)))
<br />
<button onClick=(_ => increment())>
(ReasonReact.stringToElement("increment"))
</button>
</div>,
};
effector 20.0.0
- Add
merge
for merging events
import {createEvent, merge} from 'effector'
const foo = createEvent()
const bar = createEvent()
const baz = merge([foo, bar])
baz.watch(v => console.log('merged event triggered: ', v))
foo(1)
// => merged event triggered: 1
bar(2)
// => merged event triggered: 2
Try it
- Add
split
for pattern-matching over events
import {createEvent, split} from 'effector'
const message = createEvent()
const messageByAuthor = split(message, {
bob: ({user}) => user === 'bob',
alice: ({user}) => user === 'alice',
})
messageByAuthor.bob.watch(({text}) => {
console.log('[bob]: ', text)
})
messageByAuthor.alice.watch(({text}) => {
console.log('[alice]: ', text)
})
message({user: 'bob', text: 'Hello'})
// => [bob]: Hello
message({user: 'alice', text: 'Hi bob'})
// => [alice]: Hi bob
/* default case, triggered if no one condition met */
const {__: guest} = messageByAuthor
guest.watch(({text}) => {
console.log('[guest]: ', text)
})
message({user: 'unregistered', text: 'hi'})
// => [guest]: hi
Try it
- Allow
clearNode
to automatically dispose all related intermediate steps
import {createEvent, clearNode} from 'effector'
const source = createEvent()
const target = source.map(x => {
console.log('intermediate step')
return x
})
target.watch(x => console.log('target watcher'))
source()
// => intermediate step
// => target watcher
clearNode(target)
source() // ~ no reaction ~
Try it
import {createEffect} from 'effector'
const fetchApiFx = createEffect({
handler: n =>
new Promise(resolve => {
setTimeout(resolve, n, `${n} ms`)
}),
})
fetchApiFx.finally.watch(response => {
console.log(response)
})
await fetchApiFx(10)
// => {status: 'done', result: '10 ms', params: 10}
// or
// => {status: 'fail', error: Error, params: 10}
Try it
- Add types for createEvent with config instead of string
- Add types for createEffect with config instead of string
- Add
event.filterMap
as new alias for event.filter(fn)
- Remove
extract
, withProps
, is.*
re-exports