1. 程式人生 > >【11】react 之 flux

【11】react 之 flux

ntb var 發生 tor 回調函數 1.3 執行流程 下回 關聯

Flux 是 Facebook 使用的一套前端應用的架構模式。React 標榜自己是 MVC 裏面 V 的部分,那麽 Flux 就相當於添加 M 和 C 的部分。

1.1. Flux介紹

Flux並不是一項新的技術,而是一種架構模式,一個Flux應用由四個部分:

View: 視圖層(組件)

Action(動作):視圖層發出的消息(比如mouseClick)

{
    type:’save’,
   payload:’明天不能休息,自己在家把react弄一弄’
}

Dispatcher(派發器):用來接收Actions、執行回調函數

if(action.type==’save’){

//執行保存代碼。。。。。

store.add(xxxx);

store.emit(‘change’);

}

Store(數據層):用來存放應用的狀態(數據),一旦發生變動,就提醒Views要更新頁面

技術分享

Flux 的最大特點:以單向數據流方式支持MVC,Flux執行流程:

1、一個Action由系統或View 層通過用戶交互觸發;

2、Dispatcher 會分發觸發的 Action 給所有註冊的 Store 的回調函數;

3、Store 回調函數根據接收的 Action 更新自身數據之後會觸發一個 change 事件通知 View 數據更改了;

4、View 會監聽這個 change 事件,拿到對應的新數據並調用 setState 更新組件 UI;

Action -> Dispatcher -> Store -> View

View->Action -> Dispatcher -> Store -> View

1.2. Flux安裝

npm i flux -save

1.3. Flux View

Flux中的View其實就是React中的組件,與我們以前編寫的組件沒有任何區別。

index.js 入門文件

import React from ‘react‘;
import ReactDOM from ‘react-dom‘;
import TodoApp from ‘./flux/TodoApp‘;

ReactDOM.render(
	<TodoApp />,
	document.getElementById(‘app‘)
);

TodoApp 主應用組件

import React from ‘react‘;
import TextInput from ‘./TextInput‘;
import TodoList from ‘./TodoList‘;
class TodoApp extends React.Component{
	constructor(){
		super();
		this.state = {
			datas : [12,123,123]
		};
	}
	render(){
		return (
			<div>
				<TextInput />
				<TodoList datas={this.state.datas} />
			</div>
		);
	}
	
}
export default TodoApp;

  

TextInput.js 備忘錄輸入框組件

import React from ‘react‘;
// 備忘錄,用戶輸入內容,按下回車鍵保存數據
class TextInput extends React.Component{
    constructor(){
        super();
        this.state ={value:""};
    }
    //鍵盤按下回車鍵
    _onKeyDown(event){
        //判斷是否是回車鍵
        if(event.keyCode == 13){
            //保存到本地

            //清空輸入框
            this.setState({
                value:""
            });
        }
    }

    _onChange(event){
        this.setState({
            value:event.target.value
        });
    }
    render(){
        return (
            <div>
                <input type="text" name="username" onChange={this._onChange.bind(this)} onKeyDown={this._onKeyDown.bind(this)} value={this.state.value}/>
            </div>
        );
    }
}
export default TextInput;

TodoList.js 備忘錄列表

import React from ‘react‘;
class TodoList extends React.Component{
	constructor(){
		super();
	}
	render(){
		var datas = this.props.datas;
		var lis = datas.map(function(data,index){
			return <li key={index}>{data}</li>;
		});
		return (
			<ul>
				{lis}
			</ul>
		);
	}
}

export default TodoList;

1.4. Flux Dispatcher

一個應用只需要一個 dispatcher 作為分發中心,管理所有數據流向,分發action給 Store,沒有太多其他的邏輯(一些 action creator 方法也可以放到這裏)。Facebook官方的 Dispatcher 實現輸出一個類,你要寫一個AppDispatcher.js,生成 Dispatcher 實例。

//AppDispatcher.js
//Dispatcher分發器,管理所有數據流向,分發動作給 Store。
var Dispatcher = require(‘flux‘).Dispatcher;
export default new Dispatcher();

1.5. Flux Action

Action:應用中的一個動作,比如“添加”,“刪除”...

首先要創建動作,通過定義一些 action creator(動作創建者)方法來創建,這些方法用來暴露給外部調用,通過 dispatch 分發對應的動作,所以 action creator 也稱作 dispatcher helper methods 輔助 dipatcher 分發.

TodoActions.js

import React from ‘react‘;
import AppDispatcher from ‘./AppDispatcherAppDispatcher‘;

var TodoActions = {
	todoAddItem:function(text){
		
		//創建action動作,然後通過AppDispatcher分發到store進行數據處理
		AppDispatcher.dispatch({
			actionType : ‘todo_addItem‘,
			text : text
		});
		
	},
	destroy:function(){
		AppDispatcher.dispatch({
			actionType : ‘todo_removItem‘
		});

	}
};
export default TodoActions;

有了action creator(動作創造者)我們就可以View中觸發這些動作。

TextInput.js

 _onKeyDown(event){
        //判斷是否是回車鍵
        if(event.keyCode == 13){
            //保存到本地(調用action)
            TodoAction.todoAddItem(this.state.value);
            //清空輸入框
            this.setState({
                value:""
            });
        }
    }

1.6. Flux Store

Flux四個部分,已經完成了三個,但是現在還沒有地方處理我們的數據。

View:視圖,數據交互(輸入、輸出),觸發動作。

Dispatcher:分發器,把動作發送給響應的Store處理。

Action:動作,描述動作的類型和動作的數據。

Store:管理整個應用的狀態數據(對數據進行實際操作)。

mport {EventEmitter} from ‘events‘;
//由於 Store 需要在變動後向 View 發送"change"事件,因此它必須實現事件接口。
//Object.assign 對象拷貝。 多個源對象(第二參數開始對象)的拷貝給目標對象(第一個參數對象)
var TodoStore = Object.assign({},EventEmitter.prototype,{
  items: [],
  getData: function() {
    return this.items;
  },
  addItem: function (text) {
    this.items.push(text);
  },
  emitChange: function () {
    this.emit(‘change‘);
  },
  addChangeListener: function(callback) {
    this.on(‘change‘, callback);
  },
  removeChangeListener: function(callback) {
    this.removeListener(‘change‘, callback);
  }
});

export default TodoStore;
//ListStore.items用來保存條目,ListStore.getAll()用來讀取所有條目,ListStore.emitChange()用來發出一個"change"事件。

最後一步:註冊到 dispatcher,通過動作類型過濾處理當前 Store 關聯的動作

import AppDispatcher from ‘./AppDispatcher‘;
//最後一步:註冊到 dispatcher,通過動作類型過濾處理當前 Store 關聯的動作
AppDispatcher.register(function(action){
	switch(action.actionType){
		case ‘todo_addItem‘:
			TodoStore.addItem(action.text);//調用Store方法進行數據操作
			TodoStore.emitChange();//觸發修改事件,通知view更新狀態
		break;
	}
});

1.7. Flux完結

import React from ‘react‘;
import TextInput from ‘./TextInput‘;
import TodoList from ‘./TodoList‘;
import TodoStore from ‘./TodoStore‘
class TodoApp extends React.Component{
         constructor(){
           super();
           this.state = {
                datas : TodoStore.getData()
          };
         }
         _onChange(){
           his.setState({datas : TodoStore.getData()});
         }
         componentDidMount(){
                   TodoStore.addChangeListener(this._onChange.bind(this));
         }
         componentWillUnmount(){
                   TodoStore.removeChangeListener(this._onChange.bind(this));
         }
         render(){
                   return (
                            <div>
                  <TextInput />
                     <TodoList datas={this.state.datas} />
                 </div>

                   );

         }

}

export default TodoApp;

  

【11】react 之 flux