effector
Advanced tools
Changelog
effector-react 20.8.0
Gate
state in createGate
via defaultState
fieldcreateGate({defaultState}) in documentation
object
restriction from createGate
Props
type in typescript, as it becomes useless with introduction of useGate
. This code now passes type checking successfullyimport {value createGate} from 'effector-react'
const RouteGate = createGate<string>()
const UserGate = createGate({defaultState: 'guest'})
Changelog
effector-react 20.7.3, effector-vue 20.4.2
effector-react/compat
and effector-vue/compat
compatibility with IE11Changelog
effector-react 20.7.1
useList
hook typings for typescript by allowing usage as components' return value (fix DefinitelyTyped issue)This code now works without type errors:
import {value createStore} from 'effector'
import {value useList} from 'effector-react'
const $users = createStore<User[]>([
{
username: 'alice',
email: 'alice@example.com',
bio: '. . .',
},
{
username: 'bob',
email: 'bob@example.com',
bio: '~/ - /~',
},
{
username: 'carol',
email: 'carol@example.com',
bio: '- - -',
},
])
const UserList = () => useList($users, ({username}) => <p>{username}</p>)
const App = () => (
<div>
<UserList />
</div>
)
Changelog
effector-react 20.7.0
useGate
, thereby making it consistent with <Gate />
createContextComponent
and createReactState
, which previously were based on createComponent
Changelog
effector 20.6.1, effector-react 20.4.1, effector-vue 20.3.2
Changelog
effector 20.9.0, effector-react 20.6.0
effector/fork
and effector-react/ssr
: api for server side rendering and managing independent instances of application in general./**
* app
*/
import {value createDomain, value forward, value restore} from 'effector'
import {
value useStore,
value useList,
value Provider,
value useEvent,
} from 'effector-react/ssr'
export const app = createDomain()
const requestUsernameFx = app.createEffect<{login: string}, string>()
const requestFriendsFx = app.createEffect<string, string[]>()
const $username = restore(requestUsernameFx, 'guest')
const $friends = restore(requestFriendsFx, [])
forward({
from: requestUserName.done.map(({result: username}) => username),
to: requestFriends,
})
const Friends = () => (
<ul>
{useList($friends, friend => (
<li>{name}</li>
))}
</ul>
)
const Title = () => <header>Hello {useStore($username)}</header>
export const View = ({root}) => (
<Provider value={root}>
<Title />
<Friends />
</Provider>
)
/**
* client
*/
import ReactDOM from 'react-dom'
import {value fork} from 'effector/fork'
import {value app, value View} from './app'
// initialize app with values from server
const clientScope = fork(app, {
values: window.__initialState__,
})
ReactDOM.hydrate(<View root={clientScope} />, document.getElementById('root'))
/**
* server
*/
import express from 'express'
import {value renderToString} from 'react-dom/server'
import {value fork, value serialize, value allSettled} from 'effector/fork'
import {value app, value View} from './app'
export const server = express()
server.get('/user/:login', async (req, res) => {
// clone application
const scope = fork(app)
// call requestUsername(req.params) in scope
// and await all triggered effects
await allSettled(requestUsername, {
scope,
params: req.params, // argument for requestUsername call
})
// save all stores in application to plain object
const data = serialize(scope)
// render dom content
const content = renderToString(<View root={scope} />)
res.send(`
<body>
${content}
<script>
window.__initialState__ = ${JSON.stringify(data)};
</script>
</body>
`)
})
This solution requires effector/babel-plugin
in babel configuration:
{
"plugins": ["effector/babel-plugin"]
}
Example application with express Serverless example
createApi
, stores created with restore
and events created with .prepend
to domain of given source unitsimport {createDomain, createApi, restore} from 'effector'
const domain = createDomain()
domain.onCreateStore(store => {
console.log('store created')
})
domain.onCreateEvent(event => {
console.log('event created')
})
const $position = domain.createStore({x: 0})
// => store created
const {move} = createApi($position, {
move: ({x}, payload) => ({x: x + payload}),
})
// => event created
const $lastMove = restore(move, 0)
// => store created
Changelog
effector-vue 20.5.0
Migrated from Vue.util.defineReactive to Vue.observable
Effector stores will show in Vue devtools
Cosmetic improvements for support plugin in the future.
Now we can add some units to effector object (will be return Store<number>)
const fx = createEffect({...});
export default Vue.extend({
effector: {
isCompleted: fx.done
},
watch: {
isCompleted(sid) {
this.isPopupOpened = false;
}
},
data: () => ({
isPopupOpened: true,
})
})
const $msg = createStore()
export default Vue.extend({
effector: {
$msg,
},
})
<template>
<input v-model="$msg" />
</template>