Javascript 此筛选器仍在向所有侦听组件发送更新

Javascript 此筛选器仍在向所有侦听组件发送更新,javascript,reactjs,refluxjs,datastore,Javascript,Reactjs,Refluxjs,Datastore,我使用mixin让一组图形组件监听GraphStore中的更改。使用该过滤器,只有当GraphStore的graphs数组中与其ID匹配的元素发生更改(或添加/删除)时,它们才应重新渲染。然而,当我更新数组的单个元素时,比如通过设置一个name变量,我仍然看到所有侦听图重新呈现。我做错什么了吗 图形存储 var Reflux = require('reflux'); var GraphActions = require('./graphActions').GraphActions;

我使用mixin让一组图形组件监听GraphStore中的更改。使用该过滤器,只有当GraphStore的graphs数组中与其ID匹配的元素发生更改(或添加/删除)时,它们才应重新渲染。然而,当我更新数组的单个元素时,比如通过设置一个name变量,我仍然看到所有侦听图重新呈现。我做错什么了吗

图形存储

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};
var reflection=require('reflection');
变量GraphActions=需要('./GraphActions')。GraphActions;
var GraphStore=reflow.createStore({
可列表项:[图形化],
init:function(){
这个图=[];
this.metricMetaData={};
},
onAddGraph:函数(graphId,name){//仅由作为所有图的父级的仪表板组件调用
这是推(
{
id:graphId,
姓名:“
}
);
this.updateGraphs();
},
onSetName:function(graphId,name){//仅由作为所有图形父级的仪表板组件调用
对于(var i=0,gl=this.graphs.length;i
图形

/** @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=要求('React');
var回流=需要(“回流”);
变量GraphActions=需要('./GraphActions')。GraphActions;
var GraphStore=require('./GraphStore')。GraphStore;
var Graph=React.createClass({
mixins:[回流.connectFilter(图存储,“图”,函数(图){
返回图。过滤器(函数(图){
返回graph.id==this.props.id;
}.bind(this))[0];
})],
道具类型:{
id:React.PropTypes.string.isRequired
},
...
render:function(){
if(this.state.graph的类型==“未定义”){
返回(尚未在存储中创建图形);
}否则{
返回(图名:{this.state.Graph.name});
}
}
};
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};
/**@jsx React.DOM*/
var React=要求('React');
变量图=要求('./图')。图;
变量GraphActions=需要('./GraphActions')。GraphActions;
var UUID=require('UUID');
var Dashboard=React.createClass({
道具类型:{
numGraphs:React.PropTypes.int.isRequired
},
...
render:function(){
var图=[];
对于(var i=0;i
我没有使用Reflux,但我认为这里的问题是,您的所有
Graph
实例都在侦听
GraphStore
,一旦该存储发送事件,所有组件实例都将接收该事件。它们将过滤掉不感兴趣的数据,但Reflux仍将调用
setState
在所有实例上,都会触发它们重新渲染。据我所知,如果过滤函数的结果与以前相同,回流不会短路重新渲染

为了缩短它的时间并避免在返回相同数据时重新渲染,您需要在组件上实现
shouldComponentUpdate
方法,并将新状态与旧状态进行比较,如果相同,则返回false

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

[1]


[2]

Ah,React.connectFilter更有意义。谢谢!关于提议的解决方案:两者配合得很好?PureRender mixin上的一条说明指出,它只做了一个肤浅的比较,而Immutable.js对象似乎会变得相当复杂。Immutable.js的美妙之处在于,如果您在t中深层次地变异一个值对象,则返回对包含更改的对象的新引用。因此可以使用引用等式(=)检查两个不可变的对象是否相同。当你改变一个普通的JS对象时,你不会得到一个新的引用,所以你必须做一个深入的比较,这是你不需要immutable.JS的。我终于在immutable中重写了它,我实现了PureRenderMixin…工作起来很有魅力!再次感谢。repo没有
Reflux、 连接过滤器
anywherementioned@AlxVallejo这个问题已经问了将近三年了。我相信从那时起,很多事情都发生了变化。