javascript - Reflux connectFilter 仍在向所有监听组件发送更新

标签 javascript reactjs refluxjs datastore

我正在使用 Reflux.connectFilter mixin 让一堆 Graph 组件监听我的 GraphStore 中的变化。使用过滤器,它们应该仅在 GraphStore 的图形数组中与其 ID 匹配的元素发生更改(或添加/删除)时才重新呈现。但是,当我更新数组的单个元素时,比如通过设置名称变量,我仍然看到所有正在监听的图形都重新呈现。我做错了什么吗?

图形存储

var Reflux       = require('reflux');
var GraphActions = require('./graphActions').GraphActions;

var GraphStore = Reflux.createStore({
  listenables: [GraphActions],
  init: function() {
    this.graphs         = [];
    this.metricMetaData = {};
  },
  onAddGraph: function(graphId, name) { // Called only by the Dashboard component that is a parent to all Graphs
       this.graphs.push(
          {
             id:   graphId,
             name: ""
          }
       );

       this.updateGraphs();
  },
  onSetName: function(graphId, name) { // Called only by the Dashboard component that is a parent to all Graphs
     for(var i = 0, gl = this.graphs.length; i < gl; ++i) {
        if(this.graphs[i].id === graphId) {
           this.graphs[i].name = name;
           this.updateGraphs();
           return;
        }
     }
  },
  ...
  updateGraphs: function() {
    this.trigger(this.graphs); // This is the only place in the store where trigger is called
  },
  getInitialState: function() {
    return this.graphs;
  }
});

module.exports = {GraphStore: GraphStore};

图表

/** @jsx React.DOM */
var React        = require('react');
var Reflux       = require('reflux');
var GraphActions = require('./graphActions').GraphActions;
var GraphStore   = require('./graphStore').GraphStore;

var Graph = React.createClass({
  mixins: [Reflux.connectFilter(GraphStore, "graph", function(graphs) {
    return graphs.filter(function(graph) {
      return graph.id === this.props.id;
    }.bind(this))[0];
  })],
  propTypes: {
    id: React.PropTypes.string.isRequired
  },
  ...
  render: function() {
    if(typeof this.state.graph === "undefined") {
       return (<div>The graph has not been created in the store yet</div>);
    } else {
       return (<div>Graph name: {this.state.graph.name}</div>);
    }
  }
};

module.exports = {Graph: Graph};

仪表板

/** @jsx React.DOM */
var React        = require('react');
var Graph        = require('./graph').graph;
var GraphActions = require('./graphActions').GraphActions;
var UUID         = require('uuid');    

var Dashboard = React.createClass({
  propTypes: {
    numGraphs: React.PropTypes.int.isRequired
  },
  ...
  render: function() {
    var graphs = [];
    for(var i = 0; i < this.props.numGraphs; ++i) {
        var currId = UUID.v4();
        GraphActions.addGraph(currId, "");
        graphs.push(<Graph id={currId} />);
    }

    return (<div>{graphs}</div>);
  }
};

module.exports = {Dashboard: Dashboard};

最佳答案

我没有使用过 Reflux,但我认为这里的问题是你所有的 Graph 实例都在监听 GraphStore,一旦那个存储发送一个事件,所有组件实例都会收到该事件。他们会过滤掉他们不感兴趣的数据,但 Reflux 仍然会在所有实例上调用 setState ,触发它们重新渲染。如果过滤函数的结果与之前相同,Reflux 不会(据我所知)短路重新渲染。

要将它短路并避免在获取相同数据时重新渲染,您需要在组件上实现 shouldComponentUpdate 方法并将新状态与旧状态进行比较,然后返回如果相同则为假。

一种流行的方法是将 [1] Immutable.js 与 [2] PureRenderMixin 一起使用,后者会为您短路。

[1] https://github.com/facebook/immutable-js

[2] https://facebook.github.io/react/docs/pure-render-mixin.html

关于javascript - Reflux connectFilter 仍在向所有监听组件发送更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29709388/

相关文章:

javascript - 如何更改 react 路由器路由?

css - 如何在react-table中添加淡入淡出效果?

reactjs - 使用基于 React 的应用程序时,redux 和回流的核心区别是什么?

javascript - 回流如何监听异步操作完成

javascript - 结帐后收据中的 Shopify 脚本显示付款信息

javascript - less 1.4 string.trim() ie8 崩溃

javascript - Socket.io 和 Jquery 附带不需要的附加数据

javascript - 基本 JS/HTML5 Canvas 问题

reactjs - React Native Expo 离线应用 : How to Update Local Database from Remote Server

javascript - 为什么 Reflux.js ListenAndPromise 帮助程序不起作用?