Skip to content

Instantly share code, notes, and snippets.

@Lucifier129
Last active June 7, 2017 02:02
Show Gist options
  • Save Lucifier129/ea8e45b04d2b7cb1e0c587af285cdd91 to your computer and use it in GitHub Desktop.
Save Lucifier129/ea8e45b04d2b7cb1e0c587af285cdd91 to your computer and use it in GitHub Desktop.
Make React.js code look like Vue.js
import React from 'react'
import ReactDOM from 'react-dom'
function createStore(actions, initialState={}) {
let currentState = initialState
let getState = () => currentState
let listeners = []
let subscribe = listener => !listeners.includes(listener) && listeners.push(listener)
let publish = () => listeners.forEach(listener => listener())
let dispatch = (type, payload) => {
currentState = actions[type](currentState, payload)
publish()
}
let storeActions = Object.keys(actions).reduce((ret, key) => {
ret[key] = payload => dispatch(key, payload)
return ret
}, {})
return {
getState,
dispatch,
subscribe,
publish,
actions: storeActions
}
}
class Revue extends React.Component {
componentWillMount() {
this.store = createStore(this.actions, this.data)
this.store.subscribe(this.forceUpdate.bind(this))
}
componentDidMount() { this.mounted && this.mounted() }
componentWillUnmount() { this.beforeDestroy && this.beforeDestroy() }
getMethods() {
if (this.$methods) return this.$methods
let result = {}
Object.keys(this.methods).forEach(key => {
result[key] = this.methods[key].bind(this)
})
return this.$methods = result
}
render() {
let { View } = this
let state = this.store.getState()
let methods = this.getMethods(this)
return <View data={state} methods={methods} />
}
}
let View = ({ data, methods }) => {
return (
<div>
<h1>Count: {data.count}</h1>
<button onClick={methods.handleIncre}>+1</button>
</div>
)
}
class Counter extends Revue {
View = View
data = {
count: 0
}
actions = {
INCREMENT: state => ({...state, count: state.count + 1})
}
methods = {
handleIncre: () => {
let { INCREMENT } = this.store.actions
INCREMENT()
}
}
mounted() {
let { INCREMENT } = this.store.actions
this.timer = setInterval(INCREMENT, 1000)
}
beforeDestroy() {
clearInterval(this.timer)
}
}
ReactDOM.render(
<Counter />,
document.getElementById('root')
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment