Created
May 31, 2016 10:11
-
-
Save dolpen/ca0c5ce6ca3a1473eb8760df115531ff to your computer and use it in GitHub Desktop.
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"; | |
import {EventEmitter} from "events"; | |
import weapons from "./weapons.json"; | |
class StateContainer { | |
constructor(initialState, shouldUpdate) { | |
this.root = undefined; | |
this.state = initialState; | |
this.prevState = Object.assign({}, initialState); | |
this.emitter = new EventEmitter(); | |
this.shouldUpdate = shouldUpdate || ((a, b) => true); | |
} | |
register(rootComponent) { | |
this.root = rootComponent; | |
this.root.state = this.prevState; | |
} | |
// 今はonだけ | |
on(type, listener) { | |
// ここの関数合成の筋が悪すぎてしんどい | |
return this.emitter.on(type, (...args) => { | |
listener(...args); | |
this.commit(); | |
}); | |
} | |
commit() { | |
if (this.shouldUpdate(this.prevState, this.state)) | |
this.root.setState(this.state); | |
this.prevState = Object.assign({}, this.state); | |
} | |
} | |
// React.Component 拡張 | |
const ContainerContextTypes = { | |
container: React.PropTypes.any | |
}; | |
class ContainerComponent extends React.Component { | |
static get childContextTypes() { | |
return ContainerContextTypes; | |
} | |
constructor(...args) { | |
super(...args); | |
this.props.container.register(this); | |
} | |
getChildContext() { | |
return { | |
container: this.props.container | |
}; | |
} | |
} | |
class DispatchableComponent extends React.Component { | |
static get contextTypes() { | |
return ContainerContextTypes; | |
} | |
dispatch(...args) { | |
const container = this.context.container; | |
return container.emitter.emit(...args); | |
} | |
} | |
// 実装 | |
class Weapon extends React.Component { | |
render() { | |
return ( | |
<li> | |
{this.props.data.name} ( {this.props.data.sub} / {this.props.data.special} ) | |
</li> | |
); | |
} | |
} | |
class RootComponent extends ContainerComponent { | |
constructor(...args) { | |
super(...args); | |
} | |
render() { | |
const q = this.props.container.state.filterQuery; | |
const filteredWeapons = weapons.filter(weapon => { | |
return weapon.name.indexOf(q) > -1 | |
|| weapon.sub.indexOf(q) > -1 | |
|| weapon.special.indexOf(q) > -1; | |
}); | |
return <App weapons={filteredWeapons}/> | |
} | |
} | |
class App extends DispatchableComponent { | |
render() { | |
return ( | |
<div className="weapons"> | |
<input onChange={(ev) => this.dispatch("change-filter-query", ev.target.value)}/> | |
<ul> | |
{ | |
this.props.weapons.map(weapon => { | |
return <Weapon key={weapon.id} data={weapon}/> | |
}) | |
} | |
</ul> | |
</div> | |
); | |
} | |
} | |
const container = new StateContainer({ | |
filterQuery: "" | |
}, (nowState, newState) => { | |
return nowState.filterQuery.length <= newState.filterQuery.length; | |
}); | |
ReactDOM.render( | |
<RootComponent container={container}/>, | |
document.querySelector(".mainContainer") | |
); | |
container.on("change-filter-query", (value) => { | |
container.state.filterQuery = value; | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment