2

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

零件

    var TodoHead = React.createClass({
        添加项目:函数(e){

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

            // 表示待办事项对象/数组发生了变化
            TodoActions.todoItemsChanged();
        },
        删除项目:函数(){

            TodoActions.removeItem();

            TodoActions.todoItemsChanged();
        },
        渲染:函数(){

            返回 (
                // 触发上述方法 onClick 的按钮
            );
        }
    });

回流商店

    var todoItems = [];
    变种 API = {
        addTodoItem:功能(项目){
            调试器;
            如果(项目!=“”){
            todoItems.push(item);
            }
        },
        删除待办事项:函数(){

            todoItems.pop();
        },
    }

    var TodoStore = Reflux.createStore({
        初始化:函数(){
            this.listenTo(TodoActions.addTodoItem,API.addTodoItem);
            this.listenTo(TodoActions.removeItem,API.removeTodoItem);
        },
        获取待办事项:函数(){

            返回待办事项;
        },
    });

反流动作

    var TodoActions = Reflux.createActions([
        '添加待办事项',
        '除去项目',
        'todoItemsChanged'
    ]);

正如你可以想象的那样,这一直是我的眼中钉。我究竟做错了什么?

任何答案将不胜感激!

4

1 回答 1

1

你不应该需要TodoActions.todoItemsChanged().

它应该如何工作是你只需调用TodoActions.addTodoItem(todo).

所以,没有todoItemsChanged行动。

Store 监听 Action。组件监听 Store。组件调用动作。

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

store 监听 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 以适应这种格式。Store 应该存储实际的待办事项并调用 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);
  })
},

组件监听 store 上的变化(并调用你已经拥有的 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

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

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

于 2015-05-05T22:14:37.017 回答