何时在React Application中使用Dispatcher

时间:2018-04-11 12:42:56

标签: reactjs react-redux reactjs-flux refluxjs

我在ReactJS中使用Dispatcher时遇到了一些问题。因此,我尝试从商店中删除此调度程序,仍然可以很好地存储。存储正确保存我的数据并改变事件运作良好。

现在我在我们的应用程序中使用调度程序有点困惑。

这是代码

MenuList是我调用MenuStore.getMenuFromAPI()的组件,之后我还添加了MenuStore的onChange事件。

class MenuList extends React.Component{

  constructor(){
    super();
    this.state = {open:false, menuList:"",numbering:-1}
  }

  componentWillMount(){
    var that = this;
    MenuStore.getMenuFromAPI();
    MenuStore.on("change", ()=> {
      that.setState({menuList:MenuStore.getMenu()});
    })
  }

  componentWillReceiveProps(nextProps){
    if(nextProps.show!=this.props.show){
      this.setState({open:nextProps.show});
    }
  }

  render(){
    const { classes } = this.props;

    return (

      <div>My MEnu</div>
    )
  }
}

MenuStore

class MenuStore extends EventEmitter {
  constructor() {
    super();
    this.menu = null;
  }

  getMenu(){
    return this.menu;
  }

  getMenuFromAPI(){
    var that = this;
    $.ajax({
      type: "POST",
      url: LinkConstants.GETMENU,
      headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json'
      },
      data: "",
      dataType :"json",
      success: function(response) {
        that.menu =response;
        that.emit("change");
      }.bind(this),
      error: function(xhr, status, err) {
        console.log(err);
      }.bind(this)
    });
  }

  // handleAction(action) {
  //   switch (action.type) {
  //     case ActionTypes.MENU: {
  //       this.getMenuFromAPI();
  //       break;
  //     }
  //   }
  // }

}

const menuStore = new MenuStore;
//Dispatcher.register(menuStore.handleAction.bind(menuStore));
export default menuStore;

如您所见,我评论了Dispatcher.register行和handleAction函数。

上面的代码运行正常,但我想知道为什么在这里使用Dispatcher?

如果我想将我的数据存储在MenuStore中,并从应用程序中的任何组件上的MenuStore返回。因此,有必要使用调度员和行动,或仅与商店合作。

请通过适当的示例或案例场景(如果可能)澄清我对何时使用调度员和行动或何时仅与商店合作的疑虑。

1 个答案:

答案 0 :(得分:0)

在您的示例中,您根本不使用Redux,您刚刚创建了一个类,该类用作获取数据的简单存储,但您没有使用任何Redux功能。

Redux是一个商店,它只是一个代表你的应用程序状态树的普通对象。为了更改此状态,您可以调度操作。动作只是描述发生的事情的简单对象。每个操作都有一个type字段,用于描述操作。操作由reducers处理,reducers是获取当前状态和调度操作的函数,并决定应用程序的下一个状态。这是Redux的几句话。

Redux商店有一个名为dispatch的方法,用于调度操作。正如Redux文档中所提到的,这是触发状态更改的唯一方法。

假设我们有一个TODO列表应用程序。我们的商店可以表示为字符串数组(待办事项)。

要在列表中添加新项目,我们将定义一个简单的操作:

const addItemAction = (item = '') => ({
    type: 'ADD_ITEM',
    data: item,
});

调度此操作可以在您的某个组件的方法中完成,该方法将附加到某些键盘/鼠标事件:

class TodoList extends React.Component {
    ...
    // addNewItem is called with a value from a text field
    addNewItem(item) {
        store.dispatch(addItemAction(item));
    }
    ...
}

如上所述,状态由reducer函数改变。 reducer决定是否更改状态以及如何更改状态。如果调度动作不应该改变状态,它只能返回接收状态:

function todoReducer(state = [], action) {
    switch(action.type) {
        case 'ADD_ITEM':
            return [...state, action.data];
        break;
        default:
            return state;
    }
}

将Reducer传递给createStore方法:

import { createStore } from 'redux'    
const store = createStore(todoReducer);

在TodoList组件中,您可以使用store.subscribe方法订阅商店,该方法接受每次商店状态更改时将调用的回调函数。检测到更改时,您可以调用组件的setState来设置组件状态的列表并使组件重新呈现:

class TodoList extends React.Component {
    ....
    componentDidMount() {
        this.storeSubscription = store.subscribe((state) => {
            // For the example I'm just setting the state (list of todos) 
            // without checking if it changed or not
            this.setState({
                todos: state,
            });
        });
    }

    render() {
        return this.state.todos.map(todo => <div>{todo}</div>);
    }
    ....
}

这是使用Redux的几乎完整的示例。我们使用action来描述应用程序中的事件,我们使用商店的dispatch方法将操作分派给商店,Redux将在获取新操作时调用reducer,reducer计算新状态我们的组件使用商店的subscribe方法检测更改。

在更复杂的应用程序中,还有许多事情需要考虑和处理。您可能会有一个更复杂的状态树,因此您需要额外的Reducer来处理状态计算。此外,在某些步骤中,您需要考虑使用一些帮助程序来减少订阅状态更改和检测更改的开销。

在更复杂的应用程序中,您可能会通过绑定库(例如react-redux)将组件连接到存储,因此您的组件将通过props接收存储的相关部分,这将节省订阅的开销。存储更改并决定何时重新呈现组件。

我建议观看&#34;开始使用Redux&#34;丹·阿布拉莫夫(Dan Abramov)更多地了解Redux以及如何使用它。 Getting started with Redux