React Reflux
17098 ワード
概念
RefluxはReactのfluxに基づいて作成された一方向データストリームクラスです.Refluxの一方向データストリームパターンは主にactionsとstoresから構成される.例えば、コンポーネントlistにitemが追加されると、actionsのある方法(addItem(data)など)を呼び出し、新しいデータをパラメータとして転送し、イベント機構を通じて、データがstroesに渡され、storesはサーバに要求を開始し、データデータベースを更新することができる.データの更新に成功した後も、やはりイベント機構を通して伝達されるコンポーネントリストの中で、uiを更新します.プロセス全体のドッキングはイベントによって駆動される.このように:
同じ点 actions があります.にstores があります.一方向データストリーム 違い点 actionsを内部的に展開することにより、一例のdispatcher が除去される. storesは、actionsの行動をモニターし、煩雑なswitch判断をする必要がない. storesは、相互に傍受することができ、さらなるデータ集約動作を行うことができ、map/reduce と同様である. waitForは、連続的かつ平行なデータストリームによって代替される .
アクションを作成
実際のアプリケーションシーンでは、ほぼすべての操作がバックエンドに要求されますが、これらの操作は非同期であり、Refluxも対応するPromiseインターフェースを提供しています.
Refluxは各actionに対して二つのhook方法を提供しています. preemit(params)、action emitの前に呼び出します.パラメータはactionで渡され、戻り値はshuldEmit に伝えられます. shoruldEmit(params)action emitの前に呼び出し、パラメータはデフォルトでaction転送であり、premitの戻り値があればpreemitの戻り値であり、戻り値はemit かどうかを決定する.
情景1:
アクションMethods
すべてのactionに共通の方法を追加する必要がある場合、このようにしても良いです.
直接addItemを呼び出す()とは、triggerまたはtrigger Asyncまたはtrigger Promiseの違いです.
Storeを作成
Storeは、アクションの挙動に応答して、サーバと対話することができる.
単一のアクションをモニターする
initメソッドに傍受処理を追加する
融通のきかない書き方
幸いにもRefluxは私達にlistentoMany方法を提供してくれました.重複労働を避けるために:
マークは頭文字が大文字であると認識できなくなります.例えば上のitem 1をItme 1に変更します.このおやじさん
listenables
Store Methods
Storeを拡張するための共用方法は2つあります.
方式1
前述したように、アクション、Store、コンポーネントの3つは、イベントメカニズムによって応答が変化し、コンポーネントを構築する際には、まずStoreの状態をモニターする必要があります.アクションとStoreを先に定義します.コンポーネントのライフサイクルが終了すると、Storeのリスニングを解除する必要があります. Storeがtriggerを呼び出すとオンスチャー関数が実行されますので、Store更新のたびに手動でtrigger関数 を呼び出す必要があります.
ミxins
Reflux.co nnect Filter
以上のComponentとStoreが交互になっている内容は、実際の状況によって異なる書き方を選ぶことができます.
結び目
私はコードで思想を表現するのが好きです.
コードリンク
github
参照
Reflux
RefluxはReactのfluxに基づいて作成された一方向データストリームクラスです.Refluxの一方向データストリームパターンは主にactionsとstoresから構成される.例えば、コンポーネントlistにitemが追加されると、actionsのある方法(addItem(data)など)を呼び出し、新しいデータをパラメータとして転送し、イベント機構を通じて、データがstroesに渡され、storesはサーバに要求を開始し、データデータベースを更新することができる.データの更新に成功した後も、やはりイベント機構を通して伝達されるコンポーネントリストの中で、uiを更新します.プロセス全体のドッキングはイベントによって駆動される.このように:
╔═════════╗ ╔════════╗ ╔═════════════════╗
║ Actions ║──────>║ Stores ║──────>║ View Components ║
╚═════════╝ ╚════════╝ ╚═════════════════╝
^ │
└──────────────────────────────────────┘
コードはこのように見えます.var TodoActions = Reflux.createActions([
'addItem'
]);
var TodoStore = Reflux.createStore({
items: [1, 2],
listenables: [TodoActions],
onAddItem: function (model) {
$.post('/server/add', {data: model}, function (data) {
this.items.unshift(data);
this.trigger(this.items);
});
}
});
var TodoComponent = React.createClass({
mixins: [Reflux.listenTo(TodoStore, 'onStatusChange')],
getInitialState: function () {
return {list: []};
},
onStatusChange: function () {
this.setState({list: TodoStore.items});
},
render: function () {
return (
{this.state.list.map(function (item) {
return {item}
})}
)
}
});
React.render(, document.getElementById('container'));
React Fuxと比較同じ点
アクションを作成
var statusUpdate = Reflux.createAction(options);
戻り値は関数です.この関数を呼び出すと、対応するイベントをトリガします.storeでこの関数を傍受し、対応する処理を行います.var addItem = Reflux.createAction();
var TodoStore = Reflux.createStore({
init: function () {
this.listenTo(addItem, 'addItem');
},
addItem: function (model) {
console.log(model);
}
});
addItem({name: 'xxx'});
複数のアクションを作成var TodoActions = Reflux.createActions([
'addItem',
'deleteItem'
]);
store actionsを傍受する行為:var TodoActions = Reflux.createActions([
'addItem',
'deleteItem'
]);
var TodoStore = Reflux.createStore({
init: function () {
this.listenTo(TodoActions.addItem, 'addItem');
this.listenTo(TodoActions.deleteItem, 'deleteItem');
},
addItem: function (model) {
console.log(model)
},
deleteItem:function(model){
console.log(model);
}
});
TodoActions.addItem({name:'xxx'});
TodoActions.deleteItem({name:'yyy'});
非同期アクション実際のアプリケーションシーンでは、ほぼすべての操作がバックエンドに要求されますが、これらの操作は非同期であり、Refluxも対応するPromiseインターフェースを提供しています.
var getAll = Reflux.createAction({asyncResult:true});
例えば、すべてのデータを取得します.var getAll = Reflux.createAction({asyncResult: true});
var TodoStore = Reflux.createStore({
init: function () {
this.listenTo(getAll, 'getAll');
},
getAll: function (model) {
$.get('/all', function (data) {
if (data) {
getAll.completed(data);
} else {
getAll.failed(data);
}
});
}
});
getAll({name: 'xxx'})
.then(function (data) {
console.log(data);
})
.catch(function (err) {
throw err;
});
アクションスクールRefluxは各actionに対して二つのhook方法を提供しています.
情景1:
var addItem = Reflux.createAction({
preEmit: function (params) {
console.log('preEmit:' + params);
},
shouldEmit: function (params) {
console.log('shouldEmit:' + params);
}
});
var TodoStore = Reflux.createStore({
init: function () {
this.listenTo(addItem, 'addItem');
},
addItem: function (params) {
console.log('addItem:' + params);
}
});
addItem('xxx');
$ preEmit:xxx
$ shouldEmit:xxx
情景二:var addItem = Reflux.createAction({
preEmit: function (params) {
console.log('preEmit:' + params);
return 324;
},
shouldEmit: function (params) {
console.log('shouldEmit:' + params);
return true;
}
});
var TodoStore = Reflux.createStore({
init: function () {
this.listenTo(addItem, 'addItem');
},
addItem: function (params) {
console.log('addItem:' + params);
}
});
addItem('xxx');
$ preEmit:xxx
$ shouldEmit:324
$ addItem:324
いくつかの戻り値とパラメータの関係に注意してください.アクションMethods
すべてのactionに共通の方法を追加する必要がある場合、このようにしても良いです.
Reflux.ActionMethods.print = function (str) {
console.log(str);
};
var addItem = Reflux.createAction();
var TodoStore = Reflux.createStore({
init: function () {
this.listenTo(addItem, 'addItem');
},
addItem: function (params) {
console.log('addItem:' + params);
}
});
addItem.print('xxx');
trigger、trigger Asyncとtrigger Promise直接addItemを呼び出す()とは、triggerまたはtrigger Asyncまたはtrigger Promiseの違いです.
var addItem = Reflux.createAction(); addItem(); # triggerAsync, addItem.triggerAsync()
var addItem = Reflux.createAction({sync:true});addItem(); # trigger, addItem.trigger()
var addItem = Reflux.createAction({asyncResult:true});addItem();# triggerPromise, addItem.triggerPromise()
triggerとtrigger Asyncの違いは:triggerAsync = setTimeout(function () {
trigger()
}, 0);
triggerとtrigger Promiseの違いは、trigger Promiseの戻り値がpromiseであることです.Storeを作成
Storeは、アクションの挙動に応答して、サーバと対話することができる.
単一のアクションをモニターする
initメソッドに傍受処理を追加する
var addItem = Reflux.createAction();
var TodoStore = Reflux.createStore({
init: function () {
this.listenTo(addItem, 'addItem');
},
addItem: function (model) {
console.log(model);
}
});
addItem({name: 'xxx'});
複数のアクションを傍受する融通のきかない書き方
var TodoActions = Reflux.createActions([
'addItem',
'deleteItem'
]);
var TodoStore = Reflux.createStore({
init: function () {
this.listenTo(TodoActions.addItem, 'addItem');
this.listenTo(TodoActions.deleteItem, 'deleteItem');
},
addItem: function (model) {
console.log(model);
},
deleteItem: function (model) {
console.log(model);
}
});
TodoActions.addItem({name: 'xxx'});
TodoActions.deleteItem({name: 'yyy'});
二つのactionの時にinitに二回の傍受処理方法を書きましたが、十個以上あったら、このように書きます.var TodoActions = Reflux.createActions([
'item1',
'item2',
'item3',
'item4',
'item5',
'item6',
'item7',
'item8',
'item9',
'item10'
]);
var TodoStore = Reflux.createStore({
init: function () {
this.listenTo(TodoActions.item1, 'item1');
this.listenTo(TodoActions.item2, 'item2');
this.listenTo(TodoActions.item3, 'item3');
this.listenTo(TodoActions.item4, 'item4');
this.listenTo(TodoActions.item5, 'item5');
this.listenTo(TodoActions.item6, 'item6');
this.listenTo(TodoActions.item7, 'item7');
this.listenTo(TodoActions.item8, 'item8');
this.listenTo(TodoActions.item9, 'item9');
this.listenTo(TodoActions.item10, 'item10');
},
item1: function (model) {
console.log(model);
},
item2: function (model) {
console.log(model);
}
});
TodoActions.item1({name: 'xxx'});
TodoActions.item2({name: 'yyy'});
リトントニー幸いにもRefluxは私達にlistentoMany方法を提供してくれました.重複労働を避けるために:
var TodoActions = Reflux.createActions([
'item1',
'item2',
'item3',
'item4',
'item5',
'item6',
'item7',
'item8',
'item9',
'item10'
]);
var TodoStore = Reflux.createStore({
init: function () {
this.listenToMany(TodoActions);
},
onItem1: function (model) {
console.log(model);
},
onItem2: function (model) {
console.log(model);
}
});
TodoActions.item1({name: 'xxx'});
TodoActions.item2({name: 'yyy'});
処理方法は、actionのロゴの頭文字を大文字にしてオンを付けるだけでいいです.マークは頭文字が大文字であると認識できなくなります.例えば上のitem 1をItme 1に変更します.このおやじさん
listenables
var TodoActions = Reflux.createActions([
'item1',
'item2',
'item3',
'item4',
'item5',
'item6',
'item7',
'item8',
'item9',
'item10'
]);
var TodoStore = Reflux.createStore({
listenables: [TodoActions],
onItem1: function (model) {
console.log(model);
},
onItem2: function (model) {
console.log(model);
}
});
TodoActions.item1({name: 'xxx'});
TodoActions.item2({name: 'yyy'});
私たちが実際のアプリケーションを書くときは、このような書き方をするべきです!!!Store Methods
Storeを拡張するための共用方法は2つあります.
方式1
Reflux.StoreMethods.print = function (str) {
console.log(str);
};
var addItem = Reflux.createAction();
var TodoStore = Reflux.createStore({
init: function () {
this.listenTo(addItem, 'addItem');
},
addItem: function (model) {
console.log(model);
}
});
TodoStore.print('rrr');
方式二var Mixins = {
print: function (str) {
console.log(str);
}
}
var addItem = Reflux.createAction();
var TodoStore = Reflux.createStore({
mixins: [Mixins],
init: function () {
this.listenTo(addItem, 'addItem');
},
addItem: function (model) {
console.log(model);
}
});
TodoStore.print('rrr');
コンポーネントと結合する前述したように、アクション、Store、コンポーネントの3つは、イベントメカニズムによって応答が変化し、コンポーネントを構築する際には、まずStoreの状態をモニターする必要があります.アクションとStoreを先に定義します.
var TodoActions = Reflux.createActions([
'getAll'
]);
var TodoStore = Reflux.createStore({
items: [1,2,3],
listenables: [TodoActions],
onGetAll: function () {
this.trigger(this.items);
}
});
基本var TodoComponent = React.createClass({
getInitialState: function () {
return {list: []};
},
onStatusChange: function (list) {
this.setState({list: list});
},
componentDidMount: function () {
this.unsubscribe = TodoStore.listen(this.onStatusChange);
TodoActions.getAll();
},
componentWillUnmount: function () {
this.unsubscribe();
},
render: function () {
return (
{this.state.list.map(function (item) {
return {item}
})}
)
}
});
React.render(, document.getElementById('container'));
ここには2つの注意点があります.ミxins
var TodoComponent = React.createClass({
mixins: [Reflux.ListenerMixin],
getInitialState: function () {
return {list: []};
},
onStatusChange: function (list) {
this.setState({list: list});
},
componentDidMount: function () {
this.unsubscribe = TodoStore.listen(this.onStatusChange);
TodoActions.getAll();
},
render: function () {
return (
{this.state.list.map(function (item) {
return {item}
})}
)
}
});
React.render(, document.getElementById('container'));
Reflux.listenTovar TodoComponent = React.createClass({
mixins: [Reflux.listenTo(TodoStore,'onStatusChange')],
getInitialState: function () {
return {list: []};
},
onStatusChange: function (list) {
this.setState({list: list});
},
componentDidMount: function () {
TodoActions.getAll();
},
render: function () {
return (
{this.state.list.map(function (item) {
return {item}
})}
)
}
});
React.render(, document.getElementById('container'));
Reflux.co nnectvar TodoComponent = React.createClass({
mixins: [Reflux.connect(TodoStore,'list')],
getInitialState: function () {
return {list: []};
},
componentDidMount: function () {
TodoActions.getAll();
},
render: function () {
return (
{this.state.list.map(function (item) {
return {item}
})}
)
}
});
React.render(, document.getElementById('container'));
データは自動的にstateのリストに更新されます.Reflux.co nnect Filter
var TodoComponent = React.createClass({
mixins: [Reflux.connectFilter(TodoStore, 'list', function (list) {
return list.filter(function (item) {
return item > 1;
});
})],
getInitialState: function () {
return {list: []};
},
componentDidMount: function () {
TodoActions.getAll();
},
render: function () {
return (
{this.state.list.map(function (item) {
return {item}
})}
)
}
});
React.render(, document.getElementById('container'));
データにフィルタを追加しました.以上のComponentとStoreが交互になっている内容は、実際の状況によって異なる書き方を選ぶことができます.
結び目
私はコードで思想を表現するのが好きです.
var TodoActions = Reflux.createActions([
'getAll',
'addItem',
'deleteItem',
'updateItem'
]);
var TodoStore = Reflux.createStore({
items: [1, 2, 3],
listenables: [TodoActions],
onGetAll: function () {
$.get('/all', function (data) {
this.items = data;
this.trigger(this.items);
}.bind(this));
},
onAddItem: function (model) {
$.post('/add', model, function (data) {
this.items.unshift(data);
this.trigger(this.items);
}.bind(this));
},
onDeleteItem: function (model, index) {
$.post('/delete', model, function (data) {
this.items.splice(index, 1);
this.trigger(this.items);
}.bind(this));
},
onUpdateItem: function (model, index) {
$.post('/update', model, function (data) {
this.items[index] = data;
this.trigger(this.items);
}.bind(this));
}
});
var TodoComponent = React.createClass({
mixins: [Reflux.connect(TodoStore, 'list')],
getInitialState: function () {
return {list: []};
},
componentDidMount: function () {
TodoActions.getAll();
},
render: function () {
return (
{this.state.list.map(function(item){
return
})}
)
}
});
var TodoItem = React.createClass({
componentDidMount: function () {
TodoActions.getAll();
},
handleAdd: function (model) {
TodoActions.addItem(model);
},
handleDelete: function (model,index) {
TodoActions.deleteItem(model,index);
},
handleUpdate: function (model) {
TodoActions.updateItem(model);
},
render: function () {
var item=this.props.data;
return (
{item.name}
{item.email}
/* */
)
}
});
React.render(, document.getElementById('container'));
実際の状況はこれよりずっと複雑です.ただ一つの考えを提供して、参考にしてください.コードリンク
github
参照
Reflux