Skip to content

Instantly share code, notes, and snippets.

@Elastic1
Last active May 13, 2021 11:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Elastic1/7a03265a280c9a5dc13309a6d2e83a77 to your computer and use it in GitHub Desktop.
Save Elastic1/7a03265a280c9a5dc13309a6d2e83a77 to your computer and use it in GitHub Desktop.
Riot + Redux Container Component
import { connect } from './riot-redux'
import Counter from './counter.riot'
const mapStateToProps = (state) => ({
count: state
})
const mapDispatchToProps = (dispatch) => ({
increment() {
dispatch({ type: 'INCREMENT' })
},
decrement() {
dispatch({ type: 'DECREMENT' })
}
})
export default connect(mapStateToProps, mapDispatchToProps)(Counter)
<counter>
<div>{ props.count }</div>
<button onclick="{ props.increment }">+</button>
<button onclick="{ props.decrement }">-</button>
</counter>
import { component } from 'riot'
import { registerStore } from './riot-redux'
import { createStore } from 'redux'
import Counter from './counter'
function reducer(state = 0, action) {
switch (action.type) {
case 'INCREMENT':
return state + 1
case 'DECREMENT':
return state - 1
default:
return state
}
}
const store = createStore(reducer)
registerStore(store)
component(Counter)(document.querySelector('#app-root'))
import { component, pure, __ } from 'riot'
import { evaluateAttributeExpressions } from '@riotjs/util/misc'
import { DOMattributesToObject } from '@riotjs/util/dom'
import { callOrAssign } from '@riotjs/util/functions'
const { createExpression, expressionTypes } = __.DOMBindings
let store = null
function registerStore(_store) {
store = _store
}
function evaluateInitialProps(element, initialProps = {}) {
return {
...DOMattributesToObject(element),
...callOrAssign(initialProps)
}
}
const attr = {
type: expressionTypes.ATTRIBUTE,
name: null,
evaluate: scope => ({ ...scope.state, ...scope.actions })
}
function connect(mapStateToProps, mapDispatchToProps) {
return (Component) => ({
name: Component.name,
exports: pure(
({ slots, attributes, props }) => ({
el: null,
component: null,
expressions: null,
unsubscribe: null,
props: {},
state: {},
actions: {},
getMappedState() {
const state = store.getState()
return mapStateToProps ? mapStateToProps(state, this.props) : this.state
},
getMappedActions() {
return mapDispatchToProps ? mapDispatchToProps(store.dispatch, this.props) : this.actions
},
mount(el, parentScope) {
this.el = el
this.expressions = (attributes || []).map(a => createExpression(el, a))
this.expressions.forEach(e => e.mount(parentScope))
this.props = {
...evaluateInitialProps(el, props),
...evaluateAttributeExpressions(this.expressions)
}
this.state = this.getMappedState()
this.actions = this.getMappedActions()
this.unsubscribe = store.subscribe(() => { this.update() })
this.component = component(Component)(this.el, {}, { attributes: [attr], parentScope: this, slots })
},
update(parentScope) {
if (parentScope)
this.expressions.forEach(e => e.update(parentScope))
this.props = {
...this.props,
...evaluateAttributeExpressions(this.expressions)
}
this.state = this.getMappedState()
this.actions = this.getMappedActions()
this.component.update({}, this)
},
unmount(...args) {
this.unsubscribe()
this.expressions.forEach(e => e.unmount())
this.component.unmount(...args)
}
})
)
})
}
export {
registerStore,
connect
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment