Reflux: несколько компонентов имеют доступ к одному и тому же магазину

tl;dr: UUID для GraphStore меняется каждый раз, когда я добавляю в него новый график. Это заставляет меня предположить, что каждый Graph создает свой собственный уникальный GraphStore. Я хочу, чтобы они все делили один магазин.

У меня есть компонент React Dashboard, который содержит несколько компонентов Graph.

Моему компоненту Graph передается реквизит идентификатора из панели инструментов. Используя этот идентификатор, он затем ищет данные в массиве графиков, хранящемся в GraphStore. Однако мне кажется, что каждый Graph создает свой собственный GraphStore, а не все используют одно и то же (желаемое поведение). Как заставить их всех использовать один и тот же GraphStore?

Я подумал о передаче правильного GraphStore с панели управления, но тогда я не могу заставить каждый Graph прослушивать изменения из GraphStore.

Я рад не использовать Reflux.connectFilter, но он кажется идеальным для этого.

Мой код (по крайней мере, ключевые части):

Панель управления

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

var Dashboard = React.createClass({
    ...
    render: function() {
        var graphs = [];
        for(var i = 0; i < 10; ++i) {
            var id = UUID.v4();
            GraphActions.createGraph(id);
            graphs.push(
                <Graph id={id} />
            );
        }
    }
});

module.exports = {Dashboard: Dashboard}; 

График

var React      = require('react');
var GraphStore = require('./graphStore').GraphStore;

var Graph = React.createClass({
    mixins: [Reflux.connectFilter(GraphStore, "graph", function(){
        return graphs.filter(function(graph) {
            return graph.id === this.props.id;
        }.bind(this))[0];
    })],
    propTypes: {
        id: React.PropTypes.string
    },
    render: function() {
        // Needed because the AJAX call in GraphStore might not have completed yet
        if(typeof this.state.graph == "undefined") {
            return (<div>Graph loading...</div>);
        }

        return (<div>Data: {this.state.graph.data}</div>);
    }
});

module.exports = {Graph: Graph};

Хранилище графиков

var Reflux       = require('reflux');
var jQuery       = require('jquery');
var GraphActions = require('./graphActions').GraphActions;
var UUID         = require('uuid');

var GraphStore = Reflux.createStore({
    listenables: [GraphActions],
    onCreateGraph: function(graphId) {
        console.log("GraphStore " + this.id + " is adding new graph " + graphId);

         jQuery.ajax({
              ...
              success: this.addGraph
         });
    },
    addGraph: function(data) {
        this.graphs.push(
            {
                id:   graphId,
                data: data
            }
        );

        this.trigger({graphs: this.graphs});
    },
    getInitialState: function() {
        this.graphs = [];

        // Here I give the store a UUID so I can identify it later
        this.id = UUID.v4();

        return {
            graphs: this.graphs
        };
    }
});

person Matthew Herbst    schedule 02.04.2015    source источник


Ответы (1)


getInitialState в магазине Reflux срабатывает каждый раз, когда компонент подписывается на хранилище (это исходные данные для component).

Если вам нужно, чтобы что-то запускалось один раз в магазине, используйте init:

var GraphStore = Reflux.createStore({
    listenables: [GraphActions],
    init: function() {
        this.graphs = [];

        // Here I give the store a UUID so I can identify it later
        this.id = UUID.v4();
    },
    getInitialState: function() {
        return {
            graphs: this.graphs
        };
    }
});
person Ashley 'CptLemming' Wilson    schedule 02.04.2015