Skip to content

Instantly share code, notes, and snippets.

@ushiboy
Last active October 14, 2017 13:27
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 ushiboy/6133cde53907e553c86316590deeb4ef to your computer and use it in GitHub Desktop.
Save ushiboy/6133cde53907e553c86316590deeb4ef to your computer and use it in GitHub Desktop.
observable-store sample
{
"presets": [
"env",
"react"
],
"plugins": [
"transform-flow-strip-types"
]
}
{
"env": {
"browser": true,
"commonjs": true,
"es6": true,
"node": true
},
"extends": "eslint:recommended",
"parser": "babel-eslint",
"parserOptions": {
"ecmaFeatures": {
"experimentalObjectRestSpread": true,
"jsx": true
},
"sourceType": "module"
},
"plugins": [
"flowtype",
"react"
],
"rules": {
"react/jsx-uses-react": "error",
"react/jsx-uses-vars": "error",
"indent": [
"error",
2
],
"linebreak-style": [
"error",
"unix"
],
"quotes": [
"error",
"single"
],
"semi": [
"error",
"always"
]
}
}
[ignore]
.*/node_modules/.*
[include]
[libs]
./node_modules/@ushiboy/observable-store/lib/index.js.flow
[options]
unsafe.enable_getters_and_setters=true
/* @flow */
import createObservableStore from '@ushiboy/observable-store';
import type { Store } from '@ushiboy/observable-store';
import React from 'react';
import { render } from 'react-dom';
/**
* アプリケーションの主要な型定義
*/
type AppState = {
count: number
}
type AppStore = Store<AppState>;
type AppUseCase = {
increment: () => void
}
/**
* モデル
*/
class CounterModel {
_count: number
constructor(count: number) {
this._count = count;
}
getCount(): number {
return this._count;
}
increment(): void {
this._count++;
}
}
/**
* ビュー
*/
type AppProps = {
store: Store<AppState>,
usecase: AppUseCase
}
class Application extends React.Component<AppProps, AppState> {
constructor(props) {
super();
const { store } = props;
this.state = store.state;
store.observe(state => {
this.setState(state);
});
}
render() {
return (
<CounterView count={this.state.count} usecase={this.props.usecase} />
);
}
}
type CounterViewProps = {
count: number,
usecase: AppUseCase
}
function CounterView(props: CounterViewProps) {
const { count, usecase } = props;
return (
<div>
<div>{count}</div>
<button onClick={() => usecase.increment()}>Add</button>
</div>
);
}
/**
* ユースケース
*/
function CounterUseCase(store: AppStore): AppUseCase {
return {
increment(): void {
const counter = new CounterModel(store.state.count);
counter.increment();
store.assign({
count: counter.getCount()
});
}
};
}
/**
* 初期化と起動
*/
const store = createObservableStore({
count: 0
});
const usecase = CounterUseCase(store);
render(
<Application store={store} usecase={usecase} />,
document.querySelector('#app')
);
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Counter</title>
</head>
<body>
<div id="app">
</div>
<script src="bundle.js"></script>
</body>
</html>
{
"name": "observable-store-sample",
"version": "0.1.0",
"description": "",
"main": "app.js",
"scripts": {
"start": "webpack-dev-server"
},
"author": "ushiboy",
"license": "MIT",
"devDependencies": {
"babel-cli": "^6.26.0",
"babel-eslint": "^8.0.1",
"babel-loader": "^7.1.2",
"babel-plugin-transform-flow-strip-types": "^6.22.0",
"babel-preset-env": "^1.6.0",
"babel-preset-react": "^6.24.1",
"eslint": "^4.8.0",
"eslint-plugin-react": "^7.4.0",
"eslint-plugin-flowtype": "^2.39.1",
"flow-cli": "0.0.0-pre",
"webpack": "^3.7.1",
"webpack-dev-server": "^2.9.1"
},
"dependencies": {
"@ushiboy/observable-store": "^0.1.0",
"react": "^16.0.0",
"react-dom": "^16.0.0"
}
}
module.exports = {
entry: [
'./app.js',
],
output: {
filename: 'bundle.js',
path: __dirname
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader'
}
]
},
devServer: {
contentBase: '.',
inline: true,
host: '127.0.0.1',
port: 8080,
stats: {
version: false,
hash: false,
chunkModules: false
}
},
plugins: [
],
devtool: 'source-map'
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment