回流动作触发两次

时间:2015-03-15 18:48:54

标签: javascript reactjs refluxjs

出于某种原因,每次我在react组件中触发一个动作时,与该动作相关联的store方法都会触发两次触发器。使用Firefox调试器我注意到事件发射器似乎“发出”了两次动作,尽管事实上我只调用了一次动作(onClick)。

组件


    var TodoHead = React.createClass({
        addItem: function(e){

            var todo = this.refs.TodoInput.getDOMNode().value;
            TodoActions.addTodoItem(todo);

            // signal that there was a change to the todo object/array
            TodoActions.todoItemsChanged();
        },
        removeItem: function(){

            TodoActions.removeItem(); 

            TodoActions.todoItemsChanged();
        },
        render: function(){

            return (
                // buttons that triggers the methods above onClick 
            );
        }
    });

回流商店


    var todoItems = [];
    var API = {
        addTodoItem: function(item){
            debugger;
            if(item != ""){
            todoItems.push(item);
            }
        },
        removeTodoItem: function(){

            todoItems.pop();
        },
    }

    var TodoStore = Reflux.createStore({
        init: function(){
            this.listenTo(TodoActions.addTodoItem,API.addTodoItem);
            this.listenTo(TodoActions.removeItem,API.removeTodoItem);
        },
        getTodos: function(){

            return todoItems;
        },
    });

回流行动


    var TodoActions = Reflux.createActions([
        'addTodoItem',
        'removeItem',
        'todoItemsChanged'
    ]);

你可以想象,这对我来说是一个真正的刺。我做错了什么?

任何答案将不胜感激!

1 个答案:

答案 0 :(得分:1)

您不应该需要TodoActions.todoItemsChanged()

如何工作只需拨打TodoActions.addTodoItem(todo)

所以,没有todoItemsChanged行动。

商店收听操作。 Component侦听Store。 Component调用Actions。

所以,Action-> Store-> Component-> Action等等。

商店收听Action并执行操作,然后触发更改:

var TodoStore = Reflux.createStore({
    init: function(){
        this.listenTo(TodoActions.addTodoItem,this.addTodoItem);
        this.listenTo(TodoActions.removeItem,this.removeTodoItem);
    },
    getInitialState() {
      this.todos = []; // or whatever
      return this.todos;
    },
    addTodoItem(todo) {
      API.addTodoItem(todo);
      // There are no hard and fast rules here,
      // you can do this however you want
      this.update([todo].concat(this.todos));
    },
    removeTodoItem() {
      // Similar to the above
    },
    // The docs do use this method
    // but you can call this.trigger from the liteners
    update(todos) {
      this.todos = todos;
      this.trigger(todos);
    },
});

您可能需要调整API以适应此格式。商店应该存储实际的待办事项并呼叫API。上面的方法更新本地状态,而不检查API是否成功。我打电话给我的api并使用这样的回调(Api在幕后使用superagent):

// Actual code I pulled for a project I'm working on
onAddNote(id, note) {
  Api.createNote(id, note, (err, res) => {
    let lead = JSON.parse(res.text).lead;
    this.updateLead(lead);
  })
},

组件侦听商店的更改(并调用您已有的Actions):

var TodoStore = require('/path/to/TodoStore');
var Reflux = require('reflux');

var TodoHead = React.createClass({
  mixins: [Reflux.connect(TodoStore, 'todos')],
  // **insert the rest of your component**
  // this will add the current value of
  // of the todos onto the state, you
  // access it at this.state.todos

每次商店调用this.trigger(this.todos)时,感谢Mixin都会更新您组件的状态。

还有其他方法可以连接到商店,请参阅The Reflux Docs