Last active
June 7, 2017 02:02
-
-
Save Lucifier129/ea8e45b04d2b7cb1e0c587af285cdd91 to your computer and use it in GitHub Desktop.
Make React.js code look like Vue.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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