Flux

一、基本概念

action

dispatcher:接受actions,每个application中只有一个dispatcher.

store:管理application的数据。每个store都在dispatcher中进行注册,并接受actions。store中的数据改变时,会触发change事件。每个application中有多个store. store中只能设置getters,不能有setter,但可以设置内置方法,如_add().

view:视图,通常对应React。当view使用一个store中的数据时,必须对store的change事件进行监听。当发生用户交互时,触发相应的action.

 二、 以facebook flux + React为例进行说明。

const React = require('react');
const ReactDOM = require('react-dom');
const Dispatcher = require('flux').Dispatcher;
const dispatcher = new Dispatcher();
const Store = require('flux/utils').Store;

class MyStore extends Store {
    constructor(dispatcher) {
        super(dispatcher);
        this.list = [];
    }
    __onDispatch (action) {
        switch(action.type) {
            case 'add':
                this.list.push(action.data);
                console.log('1', this.list);
          // 手动触发事件
this.__emitter.emit('change'); break; default: this.data += 'in the default' } } } var store = new MyStore(dispatcher); class ContainerUI extends React.Component { constructor(props) { super(props); this.state = { list: [] } } handleClick () { dispatcher.dispatch({ type: 'add', data: ReactDOM.findDOMNode(this.refs.input).value }) } componentDidMount () { this.remove = store.addListener(() => { console.log('2') this.setState({ list: store.list }) }) } componentWillUnmount () { this.remove(); } render () { let list = this.state.list.map(item => <li key={item}>{item}</li>); return <ul> <li> <input type='text' ref='input' defaultValue='' /> <button onClick={ this.handleClick.bind(this) }> add </button> </li> {list} </ul> } } export default ContainerUI;

效果如下:

 

 

 

 此外,facebook flux中还提供了reduceStore API

import React from 'react';
const Store = require('flux/utils').ReduceStore;
const Dispatcher = require('flux').Dispatcher;
const dispatcher = new Dispatcher();

class MyStore extends Store {
    // ReduceStore中需要重写以下两个方法:
    getInitialState () {
        return {
            year: 2020,
            month: 2,
            date: 26
        }
    }
    // 返回一个State
    reduce(oldState, action) {
        switch (action.type) {
            case 'add':
                return {
                    year: 2020,
                    month: 2,
                    date: oldState.date + 1
                }
            default:
                return oldState
        }

    }
}
const store = new MyStore(dispatcher);

class ContainerUI extends React.Component {
    handleClick () {
        dispatcher.dispatch({
            type: 'add'
        })
    }
    componentDidMount () {
        this.remove = store.addListener(() => {
            console.log(store.getState())
        })
    }
    componentWillUnmount () {
        this.remove();
    }
    render () { 
        return <ul>
            <li>
                <button onClick={ this.handleClick.bind(this) }> new day comes!</button>
            </li>
        </ul>
    }
}

export default ContainerUI;

 

posted @ 2020-02-19 18:10  cecelia  阅读(328)  评论(0编辑  收藏  举报